
Nginx (อ่านว่า "เอ็นจิ้นเอกซ์") คือ Web Server ที่ได้รับความนิยมอย่างสูงในระดับโลก ใช้งานโดยเว็บไซต์ขนาดใหญ่อย่าง Netflix, Airbnb และ GitHub ด้วยสถาปัตยกรรม Event-driven ที่ทำให้รับ Connection พร้อมกันได้เป็นหมื่นเป็นแสน Connection โดยไม่กินทรัพยากรมากเกิน บทความนี้จะพาคุณติดตั้ง Nginx บน VPS Ubuntu 22.04 ตั้งแต่เริ่มต้น จนถึงการ Serve Static Site, ตั้ง Reverse Proxy สำหรับ Node.js และเปิด SSL ด้วย Let's Encrypt
Nginx คืออะไร และต่างจาก Apache อย่างไร
Apache และ Nginx ต่างเป็น Web Server ที่ใช้กันอย่างแพร่หลาย แต่มีแนวคิดที่แตกต่างกันอย่างสิ้นเชิงในการจัดการ Connection
Apache: Process-based / Thread-based
Apache ใช้รูปแบบ Process-based หรือ Thread-based ซึ่งหมายความว่าเมื่อมี Request เข้ามา 1 ครั้ง Apache จะสร้าง Process หรือ Thread ใหม่ขึ้นมา 1 ตัวเพื่อจัดการ Request นั้น เมื่อมี Concurrent Connection มาก ๆ (เช่น 1,000 Connection พร้อมกัน) Apache จะสร้าง Process/Thread ถึง 1,000 ตัว ซึ่งกินทั้ง RAM และ CPU อย่างมาก
Nginx: Event-driven, Non-blocking
Nginx ใช้สถาปัตยกรรม Event-driven และ Non-blocking I/O กล่าวคือ Worker Process เพียง 1 ตัวสามารถจัดการ Connection ได้หลายพันพร้อมกันโดยไม่ Block การทำงาน ทำให้ Nginx กิน RAM น้อยกว่า Apache อย่างเห็นได้ชัดเมื่อมี Traffic สูง
- Apache: เหมาะกับเว็บไซต์ที่ใช้ .htaccess มาก หรือต้องการ Module ที่หลากหลาย (เช่น mod_rewrite, mod_php)
- Nginx: เหมาะกับ Serve Static Files, Reverse Proxy สำหรับ Node.js/Python/PHP-FPM และ High-traffic Sites ที่ต้องการประสิทธิภาพสูง
- Memory: Nginx ใช้ RAM น้อยกว่า Apache ประมาณ 2–5 เท่าในสภาพแวดล้อมที่มี Concurrent Connection สูง
- Static Files: Nginx เร็วกว่า Apache ในการ Serve Static Files (HTML, CSS, JS, รูปภาพ) อย่างมีนัยสำคัญ
เลือกอะไรดี? ถ้าคุณรัน Node.js, Python (Django/Flask) หรือ PHP-FPM บน VPS และต้องการ Reverse Proxy ที่เร็วและเบา Nginx คือตัวเลือกที่ดีกว่า ถ้าคุณใช้ cPanel หรือต้องการ .htaccess Apache อาจเหมาะกว่า
ติดตั้ง Nginx บน Ubuntu 22.04
เริ่มต้นด้วยการเชื่อมต่อ VPS ผ่าน SSH จากนั้นรันคำสั่งต่อไปนี้เพื่อติดตั้ง Nginx
ขั้นตอนที่ 1: อัปเดต Package Index และติดตั้ง
apt update && apt install nginx -y
ขั้นตอนที่ 2: เปิดใช้งานและสั่ง Start Service
systemctl enable nginx systemctl start nginx
คำสั่ง enable ทำให้ Nginx เริ่มทำงานอัตโนมัติเมื่อ Server รีสตาร์ท ส่วน start เริ่ม Service ทันที
ขั้นตอนที่ 3: ตรวจสอบสถานะและ Port 80
# ตรวจสอบว่า Nginx ทำงานอยู่ systemctl status nginx # ตรวจสอบว่า Port 80 เปิดอยู่ ss -tlnp | grep :80 # ถ้าใช้ UFW ให้เปิด Port HTTP และ HTTPS ufw allow 'Nginx Full' ufw status
เปิด Browser แล้วไปที่ IP Address ของ VPS คุณ เช่น http://123.456.789.0 จะเห็นหน้า "Welcome to nginx!" ซึ่งยืนยันว่าติดตั้งสำเร็จ
โครงสร้างไฟล์สำคัญของ Nginx
ก่อนตั้งค่าอะไรเพิ่มเติม ควรทำความเข้าใจโครงสร้างไฟล์ของ Nginx บน Ubuntu
/etc/nginx/ ├── nginx.conf # ไฟล์ config หลัก (global settings) ├── conf.d/ # Config ที่ include อัตโนมัติ (สำหรับ custom global settings) ├── sites-available/ # ไฟล์ Virtual Host ทั้งหมด (เก็บไว้ ยังไม่ active) │ └── default # Virtual Host เริ่มต้น ├── sites-enabled/ # Symlink ของ Virtual Host ที่ active อยู่ │ └── default -> ../sites-available/default ├── modules-available/ # Module ที่ available ├── modules-enabled/ # Module ที่ load อยู่ └── snippets/ # Config ย่อยที่ include ซ้ำได้ (เช่น SSL params)
- nginx.conf: ไฟล์หลักที่กำหนด worker_processes, events, และ include paths ปกติไม่ต้องแก้ไขมาก
- sites-available/: ที่เก็บ Virtual Host config ทุกไฟล์ แต่ยังไม่ได้ใช้งานจริง
- sites-enabled/: เก็บ Symlink ของ Virtual Host ที่ active อยู่จริง Nginx จะ load เฉพาะไฟล์ใน directory นี้
ตั้งค่า Virtual Host สำหรับ Static Website
Virtual Host (หรือ Server Block ในภาษา Nginx) คือการตั้งค่าให้ Nginx รู้ว่าเมื่อมี Request เข้ามาที่ Domain ใด ให้ Serve ไฟล์จาก Directory ไหน และตั้งค่าอะไรบ้าง
สร้าง Directory สำหรับเว็บไซต์
# สร้าง document root mkdir -p /var/www/mysite.com/html # ตั้ง Ownership ให้ www-data (user ที่ Nginx ใช้รัน) chown -R www-data:www-data /var/www/mysite.com # ตั้ง Permission ที่เหมาะสม chmod -R 755 /var/www/mysite.com
สร้างไฟล์ Server Block Config
nano /etc/nginx/sites-available/mysite.conf
ใส่เนื้อหาต่อไปนี้ในไฟล์ โดยเปลี่ยน mysite.com เป็นโดเมนของคุณ
server {
listen 80;
listen [::]:80;
server_name mysite.com www.mysite.com;
root /var/www/mysite.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# ป้องกันไม่ให้เข้าถึงไฟล์ที่ขึ้นต้นด้วยจุด (เช่น .env, .git)
location ~ /\. {
deny all;
}
# Log files
access_log /var/log/nginx/mysite.com.access.log;
error_log /var/log/nginx/mysite.com.error.log;
}Enable Virtual Host และ Reload
# สร้าง Symlink จาก sites-available ไปยัง sites-enabled ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/ # ทดสอบ Config ว่า Syntax ถูกต้อง (สำคัญมาก!) nginx -t # ถ้าผ่านแล้ว ให้ Reload (ไม่ Downtime) systemctl reload nginx
สำคัญ: รัน nginx -t ทุกครั้งก่อน systemctl reload nginx เสมอ ถ้า Config มี Syntax Error แล้ว Reload โดยตรง Nginx อาจหยุดทำงานทำให้เว็บไซต์ล่มได้
Serve Static Files: root, index, try_files และ location blocks
Nginx มี Directive สำคัญหลายตัวสำหรับการ Serve Static Files ที่ควรเข้าใจ
server {
listen 80;
server_name mysite.com www.mysite.com;
root /var/www/mysite.com/html;
# ไฟล์ index ที่จะ serve เมื่อ request path เป็น directory
index index.html index.htm;
# Location block หลัก: ลอง serve ไฟล์ตรง ๆ ก่อน
# ถ้าไม่เจอ ลอง directory ถ้าไม่เจออีก return 404
location / {
try_files $uri $uri/ =404;
}
# Cache รูปภาพและ Static Assets เป็น 30 วัน
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# Block การเข้าถึง hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}- root: กำหนด Document Root ที่ Nginx จะหาไฟล์
- index: ไฟล์ที่จะ serve เมื่อ Request path เป็น Directory (เช่น
/จะ serveindex.html) - try_files $uri $uri/ =404: ลอง serve ไฟล์ตรง ๆ ก่อน ถ้าไม่เจอลอง Directory ถ้าไม่เจออีกให้ return 404
- location ~* ...: ใช้ Regular Expression (case-insensitive) เพื่อ Match ประเภทไฟล์
Nginx เป็น Reverse Proxy สำหรับ Node.js / PHP-FPM
หนึ่งในการใช้งาน Nginx ที่พบบ่อยที่สุดคือการทำ Reverse Proxy รับ Request จาก Browser แล้วส่งต่อไปยัง Application Server ที่รันอยู่ด้านหลัง เช่น Node.js (port 3000) หรือ PHP-FPM (unix socket)
Reverse Proxy สำหรับ Node.js
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
proxy_pass http://localhost:3000;
# ส่ง Header ต้นฉบับไปยัง Application
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}Upstream Block สำหรับ Load Balancing
ถ้าคุณรัน Application หลาย Instance (เช่น Node.js Cluster หรือ Multiple App Servers) สามารถใช้ upstream Block เพื่อกระจาย Traffic ได้
# กำหนด upstream ก่อน server block
upstream myapp_backend {
# Round-robin load balancing (default)
server localhost:3000;
server localhost:3001;
server localhost:3002;
# keepalive connections ไว้ใช้ซ้ำ (ดีต่อ performance)
keepalive 16;
}
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
proxy_pass http://myapp_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # จำเป็นสำหรับ keepalive
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Reverse Proxy สำหรับ PHP-FPM
server {
listen 80;
server_name myphp.com www.myphp.com;
root /var/www/myphp.com/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# ส่ง PHP files ไปยัง PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}ติดตั้ง SSL ด้วย Let's Encrypt และ Certbot
Let's Encrypt เป็น Certificate Authority ฟรีที่ออก SSL Certificate ได้อัตโนมัติ ร่วมกับ Certbot ซึ่งเป็น Client ที่รองรับ Nginx โดยตรง
ขั้นตอนที่ 1: ติดตั้ง Certbot
apt install certbot python3-certbot-nginx -y
ขั้นตอนที่ 2: ออก Certificate และตั้งค่า Nginx อัตโนมัติ
# เปลี่ยน example.com เป็นโดเมนของคุณ # Certbot จะแก้ไข Nginx config ให้อัตโนมัติและ redirect HTTP → HTTPS certbot --nginx -d example.com -d www.example.com
Certbot จะถามข้อมูล Email สำหรับแจ้งเตือน Certificate ใกล้หมดอายุ และถามว่าต้องการ Redirect HTTP → HTTPS อัตโนมัติหรือไม่ (แนะนำให้เลือก Yes)
ขั้นตอนที่ 3: ตรวจสอบ Auto-renewal
Certbot ติดตั้ง Systemd Timer หรือ Cron Job ให้อัตโนมัติสำหรับ Renew Certificate ก่อนหมดอายุ ตรวจสอบได้ด้วย
# ทดสอบว่า Auto-renewal ทำงานได้ปกติ (ไม่ Renew จริง) certbot renew --dry-run # ดู Timer ของ Systemd systemctl status certbot.timer # หรือดู Cron Job (แล้วแต่ระบบ) cat /etc/cron.d/certbot
Certificate ของ Let's Encrypt มีอายุ 90 วัน Certbot จะ Renew อัตโนมัติเมื่อเหลืออายุน้อยกว่า 30 วัน
ข้อกำหนด: ก่อนออก SSL Certificate ด้วย Let's Encrypt โดเมนของคุณต้องชี้มาที่ IP Address ของ VPS ก่อนแล้ว (DNS A Record ต้องถูกต้อง) มิฉะนั้น Certbot จะ Verify ไม่ผ่าน
Gzip Compression ใน Nginx
การเปิด Gzip Compression ช่วยลดขนาดไฟล์ที่ส่งไปยัง Browser ได้ 60–80% ทำให้หน้าเว็บโหลดเร็วขึ้นอย่างเห็นได้ชัดโดยเฉพาะในไฟล์ HTML, CSS, JS และ JSON
เปิดไฟล์ /etc/nginx/nginx.conf หรือสร้างไฟล์ใหม่ใน /etc/nginx/conf.d/gzip.conf
# เพิ่มใน http block ของ nginx.conf หรือสร้างไฟล์ใน conf.d/
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss
application/xhtml+xml
image/svg+xml
font/woff
font/woff2;- gzip_comp_level 6: ระดับการบีบอัด 1 (เบาสุด/เร็วสุด) ถึง 9 (แน่นสุด/ช้าสุด) ค่า 6 คือจุดสมดุลที่ดี
- gzip_min_length 256: ไม่ Compress ไฟล์ที่เล็กกว่า 256 bytes เพราะ Overhead ไม่คุ้ม
- gzip_vary on: เพิ่ม Header
Vary: Accept-Encodingเพื่อให้ Cache ทำงานถูกต้อง
Security Headers ใน Nginx
การเพิ่ม Security Headers ช่วยป้องกันการโจมตีประเภทต่าง ๆ เช่น Clickjacking, MIME Sniffing และ Information Leakage เพิ่มได้ใน Server Block หรือ Location Block
server {
# ... config อื่น ๆ ...
# ป้องกัน Clickjacking (ไม่ให้ฝัง iframe จาก domain อื่น)
add_header X-Frame-Options "SAMEORIGIN" always;
# ป้องกัน MIME Type Sniffing
add_header X-Content-Type-Options "nosniff" always;
# ควบคุม Referrer ที่ส่งไปยัง Site อื่น
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# ป้องกัน XSS (Cross-Site Scripting) สำหรับ Browser เก่า
add_header X-XSS-Protection "1; mode=block" always;
# บอก Browser ให้ใช้ HTTPS เสมอ (ต้องมี SSL ก่อน)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# ซ่อน Nginx version จาก Header
server_tokens off;
}หมายเหตุ: Strict-Transport-Security (HSTS) ควรเพิ่มหลังจากมั่นใจว่า HTTPS ทำงานได้ปกติแล้วเท่านั้น เพราะถ้าเปิดแล้ว SSL มีปัญหา Browser จะปฏิเสธการเข้าถึง HTTP โดยอัตโนมัติในช่วง max-age
ทดสอบ Config และ Reload อย่างปลอดภัย
Nginx มี Built-in Config Test ที่ควรรันทุกครั้งก่อน Reload หรือ Restart เพื่อป้องกัน Downtime จาก Config Error
# ทดสอบ Config Syntax (ไม่กระทบ Server ที่รันอยู่) nginx -t # ผลลัพธ์ที่ถูกต้องคือ: # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # nginx: configuration file /etc/nginx/nginx.conf test is successful # Reload (ไม่มี Downtime — Graceful reload) systemctl reload nginx # Restart (มี Brief Downtime — ใช้เมื่อจำเป็น) systemctl restart nginx # ดู Error Log แบบ Real-time tail -f /var/log/nginx/error.log # ดู Access Log แบบ Real-time tail -f /var/log/nginx/access.log
Reload vs Restart: systemctl reload nginx ทำ Graceful Reload โดย Nginx จะ Fork Worker Process ใหม่ที่ใช้ Config ใหม่ ส่วน Worker Process เดิมยังคง Serve Request ที่ค้างอยู่จนเสร็จ ทำให้ไม่มี Downtime ส่วน restart หยุดและเริ่ม Nginx ใหม่ทั้งหมด อาจทำให้ Request หายได้
ปัญหาที่พบบ่อยและวิธีแก้
502 Bad Gateway
เกิดขึ้นเมื่อ Nginx ไม่สามารถเชื่อมต่อกับ Backend ได้ (Node.js, PHP-FPM หยุดทำงาน หรือ Port ผิด)
# ตรวจสอบว่า Backend ทำงานอยู่ systemctl status php8.2-fpm # หรือสำหรับ Node.js ps aux | grep node # ตรวจสอบ Port ที่ Backend ฟังอยู่ ss -tlnp | grep 3000 # ดู Error Log ของ Nginx tail -100 /var/log/nginx/error.log # Restart Backend systemctl restart php8.2-fpm
Permission Denied (403 Forbidden)
มักเกิดจาก File/Directory Permission ไม่ถูกต้อง หรือ SELinux/AppArmor บล็อก
# ตรวจสอบ Ownership ของไฟล์ใน Document Root
ls -la /var/www/mysite.com/
# แก้ไข Ownership ให้ www-data
chown -R www-data:www-data /var/www/mysite.com/
# ตั้ง Permission: Directory = 755, File = 644
find /var/www/mysite.com/ -type d -exec chmod 755 {} \;
find /var/www/mysite.com/ -type f -exec chmod 644 {} \;Config Syntax Error
เกิดเมื่อแก้ไข Config ผิด ทำให้ nginx -t fail และ Nginx ไม่ Reload
# รันเพื่อดู Error ที่ชัดเจน nginx -t # ตัวอย่างข้อผิดพลาดที่พบบ่อย: # nginx: [emerg] unexpected "}" — ขาดเครื่องหมาย ; # nginx: [emerg] "server" directive is not allowed here — วาง block ผิดที่ # nginx: [emerg] host not found in upstream — ชื่อ upstream หรือ port ผิด # ถ้า Config พังและ Nginx หยุดทำงาน ให้ Restore config เดิมก่อน # แล้วแก้ไขให้ถูกต้องก่อน Start ใหม่
เว็บไซต์แสดง Default Nginx Page แทนเว็บของเรา
# ตรวจสอบว่า Symlink ถูกสร้างแล้ว ls -la /etc/nginx/sites-enabled/ # ตรวจสอบ server_name ใน Config ว่าตรงกับโดเมนที่ใช้ grep server_name /etc/nginx/sites-available/mysite.conf # ลบ default site ถ้าไม่ต้องการ rm /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx
พร้อมรัน Nginx บน VPS ของคุณ?
VPS AsiaGB ให้ Full Root Access ติดตั้ง Nginx, Node.js, PHP-FPM ได้เลยทันที VPS Linux เริ่มต้น 500 บาท/เดือน ดาต้าเซ็นเตอร์ไทย และ สิงคโปร์
ดู VPS AsiaGB