ตั้งค่า Nginx Server Block สำหรับหลายเว็บไซต์ในเครื่องเดียว
เซิร์ฟเวอร์หนึ่งเครื่องที่มี IP เดียวสามารถให้บริการหลายเว็บไซต์ได้ เพราะเบราว์เซอร์ส่งชื่อโดเมนที่ต้องการมาใน Header Host (และใน SNI สำหรับ HTTPS) Nginx ใช้ค่านี้เลือกว่าจะตอบด้วยการตั้งค่าชุดใด การตั้งค่าแต่ละชุดเรียกว่า Server Block ซึ่งเทียบได้กับ VirtualHost ของ Apache
บทความนี้สาธิตการตั้งค่าสองเว็บไซต์ คือ example.com (เว็บ PHP) และ example.net (เว็บ HTML ล้วน) บนเครื่องเดียวกัน พร้อมการตั้ง Default Server เพื่อไม่ให้โดเมนแปลกปลอมที่ชี้มาที่ IP ของคุณแสดงเนื้อหาเว็บใดเว็บหนึ่ง บทความนี้สมมติว่าคุณติดตั้ง Nginx และ PHP-FPM แล้วตาม ติดตั้ง Nginx, PHP-FPM และ MariaDB (LEMP) บน Ubuntu
สิ่งที่ต้องเตรียม
- Ubuntu 22.04/24.04 หรือ AlmaLinux/Rocky Linux 8-9 ที่ติดตั้ง Nginx แล้ว
- ผู้ใช้ที่มีสิทธิ์
sudo - โดเมนทุกโดเมนชี้ A Record มาที่ IP ของเซิร์ฟเวอร์ (ตัวอย่างใช้
203.0.113.10) - สำรองโฟลเดอร์ Config เดิมไว้ก่อนแก้ไข:
sudo cp -a /etc/nginx /etc/nginx.bak-$(date +%F)
โครงสร้างไฟล์ Config บนแต่ละ Distro
| Ubuntu | AlmaLinux / Rocky Linux | |
|---|---|---|
| ตำแหน่งไฟล์ Server Block | /etc/nginx/sites-available/ แล้วสร้าง Symlink ไปที่ /etc/nginx/sites-enabled/ | /etc/nginx/conf.d/*.conf (ไฟล์ต้องลงท้าย .conf) |
| ผู้ใช้ที่ Nginx รัน | www-data | nginx |
| Socket ของ PHP-FPM | /run/php/php8.3-fpm.sock (24.04) หรือ /run/php/php8.1-fpm.sock (22.04) | /run/php-fpm/www.sock |
| Default Site ที่มากับแพ็กเกจ | sites-enabled/default | บล็อก server ใน /etc/nginx/nginx.conf |
ตรวจชื่อ Socket ของ PHP-FPM บนเครื่องคุณด้วย ls /run/php/ (Ubuntu) หรือ ls /run/php-fpm/ (AlmaLinux/Rocky) เพราะชื่อจะเปลี่ยนตามเวอร์ชัน PHP ที่ติดตั้ง
ขั้นตอนที่ 1: สร้างโฟลเดอร์ของแต่ละเว็บ
sudo mkdir -p /var/www/example.com/public /var/www/example.net/public
echo '<?php echo "example.com OK";' | sudo tee /var/www/example.com/public/index.php
echo '<h1>example.net OK</h1>' | sudo tee /var/www/example.net/public/index.html
ไฟล์ทดสอบนี้ใช้ยืนยันว่าแต่ละโดเมนไปถึงโฟลเดอร์ที่ถูกต้อง ภายหลังค่อยแทนที่ด้วยไฟล์เว็บจริง
ขั้นตอนที่ 2: สร้าง Server Block สำหรับเว็บ PHP
บน Ubuntu สร้างไฟล์ /etc/nginx/sites-available/example.com บน AlmaLinux/Rocky สร้าง /etc/nginx/conf.d/example.com.conf เนื้อหาเหมือนกัน ยกเว้นบรรทัด fastcgi_pass:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.(?!well-known) {
deny all;
}
}
คำอธิบาย:
server_nameคือรายชื่อโดเมนที่ Server Block นี้รับ ใส่ทั้งแบบมีและไม่มีwwwtry_filesบรรทัดนี้เหมาะกับ WordPress และเฟรมเวิร์กที่ส่งทุก Request ไปที่index.phplocation ~ /\.(?!well-known)ปฏิเสธการเข้าถึงไฟล์ที่ขึ้นต้นด้วยจุด เช่น.gitหรือ.envแต่ยังปล่อย.well-knownไว้ให้ Let's Encrypt ใช้- Log แยกของแต่ละเว็บทำให้หาสาเหตุ Error ได้ง่ายกว่ารวมในไฟล์เดียว
บน AlmaLinux/Rocky ไม่มีไฟล์ snippets/fastcgi-php.conf ให้ใช้บล็อก PHP แบบนี้แทน:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
ขั้นตอนที่ 3: สร้าง Server Block สำหรับเว็บ HTML ล้วน
server {
listen 80;
listen [::]:80;
server_name example.net www.example.net;
root /var/www/example.net/public;
index index.html;
access_log /var/log/nginx/example.net.access.log;
error_log /var/log/nginx/example.net.error.log;
location / {
try_files $uri $uri/ =404;
}
}
บันทึกเป็น /etc/nginx/sites-available/example.net (Ubuntu) หรือ /etc/nginx/conf.d/example.net.conf (AlmaLinux/Rocky)
ขั้นตอนที่ 4: ตั้ง Default Server ที่ปฏิเสธโดเมนที่ไม่รู้จัก
เมื่อมี Request ที่ Header Host ไม่ตรงกับ server_name ใดเลย เช่น มีคนเข้าด้วย IP ตรง ๆ หรือโดเมนของคนอื่นชี้มาที่ IP คุณ Nginx จะใช้ Server Block ที่มี default_server หรือถ้าไม่มี ก็ใช้บล็อกแรกที่อ่านเจอ ซึ่งอาจเป็นเว็บลูกค้าของคุณ ผลคือเว็บของคุณไปปรากฏใต้โดเมนอื่นและกระทบ SEO ได้ ให้สร้างบล็อก Default ที่ตัดการเชื่อมต่อทิ้ง:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
444 เป็นรหัสพิเศษของ Nginx ที่ปิดการเชื่อมต่อทันทีโดยไม่ส่งคำตอบกลับ
บน Ubuntu ให้บันทึกเป็น /etc/nginx/sites-available/000-default-deny แล้วปิดไซต์ Default เดิมเพราะมี default_server อยู่แล้ว และจะชนกัน:
sudo rm /etc/nginx/sites-enabled/default
บน AlmaLinux/Rocky ให้บันทึกเป็น /etc/nginx/conf.d/000-default-deny.conf แล้วเปิด /etc/nginx/nginx.conf ดูบล็อก server เดิมที่มากับแพ็กเกจ หากบรรทัด listen ในบล็อกนั้นมีคำว่า default_server (พบในบางเวอร์ชัน) ให้ลบคำนั้นออก หรือใส่ # หน้าบล็อกทั้งหมดหากไม่ได้ใช้
ขั้นตอนที่ 5: เปิดใช้งานและโหลดค่าใหม่
บน Ubuntu สร้าง Symlink:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example.net /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/000-default-deny /etc/nginx/sites-enabled/
ทุก Distro ตรวจไวยากรณ์แล้ว reload:
sudo nginx -t
sudo systemctl reload nginx
nginx -t ต้องแสดง syntax is ok และ test is successful เสมอก่อน reload การ reload ไม่ตัดการเชื่อมต่อที่ค้างอยู่ และถ้า Config ใหม่ผิด Nginx จะยังใช้ค่าเดิมต่อ
บน AlmaLinux/Rocky ที่เปิด SELinux นโยบายมาตรฐานกำหนดให้ /var/www เป็น httpd_sys_content_t อยู่แล้ว เพียงรีเซ็ต Context ของไฟล์ที่สร้างใหม่ให้ตรงกับนโยบาย:
sudo restorecon -Rv /var/www
หากใช้โฟลเดอร์อื่น เช่น /srv/www ต้องเพิ่มกฎก่อน:
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
sudo restorecon -Rv /srv/www
รายละเอียดดูที่ ใช้งาน SELinux บน AlmaLinux และ Rocky Linux โดยไม่ต้องปิด
ตรวจสอบผลลัพธ์
ทดสอบได้ทันทีแม้ DNS ยังไม่ชี้มา โดยส่ง Header Host เองจากตัวเซิร์ฟเวอร์:
curl -H "Host: example.com" http://127.0.0.1/
curl -H "Host: example.net" http://127.0.0.1/
curl -v -H "Host: unknown.test" http://127.0.0.1/
ผลที่ควรได้คือ example.com OK, <h1>example.net OK</h1> และบรรทัดสุดท้ายจะจบด้วย Empty reply from server ซึ่งแปลว่า Default Server ทำงานถูกต้อง
ดูว่า Nginx โหลด Config ใดบ้างจริง ๆ ด้วย sudo nginx -T | grep -E "server_name|listen"
ขั้นตอนต่อไป: HTTPS
เมื่อ DNS ชี้มาแล้ว ให้ขอใบรับรองแยกของแต่ละเว็บด้วย Certbot ตาม ติดตั้ง SSL ฟรีจาก Let's Encrypt ด้วย Certbot บน Nginx Certbot จะเพิ่มบรรทัด listen 443 ssl ใน Server Block ที่ตรงกับโดเมนให้เอง
สำหรับพอร์ต 443 ควรมี Default Server ที่ปฏิเสธเช่นกัน ใน Nginx 1.19.4 ขึ้นไป (Ubuntu 22.04 มี 1.18 จากแพ็กเกจมาตรฐาน จึงยังใช้ไม่ได้ ส่วน Ubuntu 24.04 และ AlmaLinux/Rocky 9 ใช้ได้) เพิ่มบล็อกนี้ได้โดยไม่ต้องมีใบรับรอง:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
}
ตรวจเวอร์ชันของเครื่องคุณด้วย nginx -v
ปัญหาที่พบบ่อย
ทุกโดเมนแสดงเว็บเดียวกัน
มักเกิดจากสะกด server_name ผิด ลืมสร้าง Symlink ใน sites-enabled หรือบน AlmaLinux ตั้งชื่อไฟล์ไม่ลงท้าย .conf ไฟล์จึงไม่ถูกโหลด ตรวจด้วย sudo nginx -T ว่ามี Server Block ของโดเมนนั้นจริงหรือไม่
nginx -t แจ้ง a duplicate default server
มีมากกว่าหนึ่งบล็อกที่ประกาศ default_server บนพอร์ตเดียวกัน มักเป็นไฟล์ default ของ Ubuntu หรือบล็อกใน nginx.conf ของ AlmaLinux ที่ยังไม่ได้ปิด
could not build server_names_hash
เมื่อมีชื่อโดเมนยาวหรือจำนวนมาก ให้เพิ่มบรรทัดนี้ในบล็อก http { } ของ /etc/nginx/nginx.conf แล้วทดสอบอีกครั้ง (บน Ubuntu มีบรรทัดนี้อยู่แล้วแต่ถูก Comment ไว้):
server_names_hash_bucket_size 64;
เว็บ PHP ขึ้น 502 Bad Gateway
Nginx ติดต่อ PHP-FPM ไม่ได้ ตรวจว่า Service ทำงานอยู่ (systemctl status php8.3-fpm บน Ubuntu หรือ php-fpm บน AlmaLinux) และ Path ของ Socket ใน fastcgi_pass ตรงกับไฟล์ที่มีจริง รายละเอียดดู /var/log/nginx/example.com.error.log และบทความ ทำความเข้าใจ HTTP Error 403, 404, 500, 502, 503 และ 504
หากเพิ่มเว็บไซต์แล้วยังแสดงผลไม่ถูกต้อง ติดต่อทีมซัพพอร์ต THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/
- Categories:
- Cloud
- Tags:
- Cloud
- Cloud Server
Related Posts
หมวดหมู่ที่น่าสนใจ
- Account Settings
- AD Server
- AI
- Alibaba Cloud
- Anti-Spam Gateway
- AWS Amazon Web Services
- Campaign
- CentOS/AlmaLinux
- Cloud
- Cloud Backup
- Cloud Communication
- Cloud Migration
- Cloud Security
- Cloud Server Management
- Cloud Solution
- Cloud Solution for Government
- Cloud Solutions by Industry
- Cloud Storage
- Cloud VPS App Plus +
- Cloud VPS DirectAdmin
- Cloud VPS Plesk
- CSR
- Cyber Security
- Cybersecurity
- Data Sovereignty
- Database Server
- DDoS
- Digital Tranformation
- Digital Transformation
- Direct Mail
- Directadmin
- Domainname
- Ecommerce
- ERP
- Generative AI
- Getting Started
- Google Cloud
- Google G Suite
- Huawei Cloud
- IT News
- Linux Server
- Managed Cloud Services
- Managed Service Provider
- Manual
- Microsoft
- Microsoft 365
- Microsoft Azure
- News
- On-premise
- Private Mail Server
- Promotion
- Recommend Solution (Enterprise)
- Server
- Sovereign Cloud
- THAI DATA CLOUD Platform
- Ubuntu
- Ubuntu
- Uncategorized
- VMware
- VPS Server
- Web Design
- Web Hosting
- Web Hosting (DirectAdmin)
- Web Hosting (Plesk)
- Web Technologies
- Windows Server
- Wordpress
- Zimbra
- เรื่องราวความประทับใจ
- โซลูชันสำหรับธุรกิจการผลิตและยานยนต์
- โซลูชันสำหรับธุรกิจการศึกษา
- โซลูชันสำหรับธุรกิจการเงิน
- โซลูชันสำหรับธุรกิจขนส่งและกระจายสินค้า
- โซลูชันสำหรับธุรกิจค้าปลีก
- โซลูชันสำหรับธุรกิจท่องเที่ยว
- โซลูชันสำหรับธุรกิจบริการสุขภาพและโรงพยาบาล
- โซลูชันสำหรับธุรกิจประกันภัย
- โซลูชันสำหรับธุรกิจพลังงานและสาธารณูปโภค
- โซลูชันสำหรับธุรกิจสื่อสารมวลชนและเอ็นเตอร์เทนเมนท์
- โซลูชันสำหรับธุรกิจอสังหาริมทรัพย์
- โซลูชันสำหรับธุรกิจเทคโนโลยี


