Nginx

Subdomain Configuration ใน Nginx — ตั้งค่า Subdomain อย่างครบถ้วน

Subdomain Configuration ใน Nginx — ตั้งค่า Subdomain อย่างครบถ้วน

Subdomain เป็นส่วนหนึ่งของชื่อโดเมนที่ช่วยให้คุณสามารถแบ่งเว็บไซต์หรือบริการของคุณออกเป็นส่วนต่าง ๆ ได้ เช่น api.example.com, blog.example.com, หรือ cdn.example.com การตั้งค่า subdomain บน Nginx ที่ถูกต้องจะช่วยเพิ่มประสิทธิภาพของเซิร์ฟเวอร์ และทำให้การจัดการเว็บไซต์เป็นไปอย่างมีประสิทธิภาพมากขึ้น บทความนี้จะแสดงให้คุณเห็นวิธีการตั้งค่า subdomain บน Nginx อย่างครบถ้วน รวมถึงการใช้ wildcard subdomain, SSL configuration, และการประยุกต์ใช้เพื่อให้บริการต่าง ๆ ที่สามารถปรับขยายได้

Subdomain คืออะไร และทำไมจึงสำคัญ

Subdomain เป็นส่วนเสริมของชื่อโดเมนหลักที่ใช้เพื่อจัดระเบียบและแยกส่วนต่าง ๆ ของเว็บไซต์ของคุณ ตัวอย่างเช่น ในโดเมน api.example.com นั้น “api” คือ subdomain ในขณะที่ “example.com” คือ primary domain

ข้อดีของการใช้ subdomain มีดังนี้:

  • แยกบริการ (API, Blog, Static Assets) ออกจากเว็บไซต์หลัก
  • ปรับปรุงการจัดการอินเด็กส์ SEO โดยการแยกเนื้อหา
  • ลดภาระการรับส่งข้อมูลโดยการแยกเซิร์ฟเวอร์ CDN
  • เพิ่มความปลอดภัยโดยการแยกระหว่าง API และ Web Frontend
  • ช่วยให้สามารถปรับขยาย (scale) ได้อย่างรวดเร็ว

ขั้นตอนพื้นฐาน: ตั้งค่า DNS และ Nginx

ก่อนที่จะเริ่มตั้งค่า Nginx สำหรับ subdomain คุณจำเป็นต้องตั้งค่า DNS record ของคุณก่อน

การตั้งค่า DNS Records

เข้าไปยังแพนเนล DNS ของคุณ (เช่น Cloudflare, cPanel, DirectAdmin) และเพิ่ม A record สำหรับ subdomain ของคุณ

TypeNameValue
Aapi123.45.67.89
Ablog123.45.67.89
Acdn123.45.67.89
A*123.45.67.89

หมายเหตุ: หากต้องการให้ทุก subdomain ชี้ไปยังเซิร์ฟเวอร์เดียวกัน ให้ใช้ wildcard record (*)

Dedicated Server Block สำหรับแต่ละ Subdomain

การสร้าง server block ที่แยกจากกันสำหรับแต่ละ subdomain จะให้ความยืดหยุ่นสูงสุดในการจัดการการตั้งค่า SSL, log files, และการเพิ่มประสิทธิภาพ

# /etc/nginx/sites-available/api.example.com
server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;

    # Redirect to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name api.example.com;

    # SSL certificates
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    # SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Document root
    root /var/www/api.example.com/public;
    index index.php index.html;

    # Access and error logs
    access_log /var/log/nginx/api.example.com_access.log;
    error_log /var/log/nginx/api.example.com_error.log;

    # Proxy to backend API server
    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

สร้างไฟล์นี้และเปิดใช้งานด้วยการเชื่อมลิงก์ไปยังโฟลเดอร์ sites-enabled:

sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Wildcard Subdomain กับ Nginx

หากคุณต้องการจัดการหลาย ๆ subdomain ที่มีการตั้งค่าเหมือนกัน ลองใช้ wildcard server_name กับ Nginx

# /etc/nginx/sites-available/wildcard.example.com
server {
    listen 80;
    listen [::]:80;
    server_name ~^(?<subdomain>.+)\.example\.com$ example.com;

    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ~^(?<subdomain>.+)\.example\.com$ example.com;

    # SSL certificates (wildcard cert)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Root directory
    root /var/www/example.com;
    index index.html index.php;

    # Logs
    access_log /var/log/nginx/wildcard_access.log;
    error_log /var/log/nginx/wildcard_error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}

หากต้องการใช้ wildcard certificate ตรวจสอบให้แน่ใจว่าคุณได้สร้าง certificate ที่ยอมรับ wildcard domain (*.example.com) แล้ว

Wildcard SSL Certificate สำหรับ Subdomain ทั้งหมด

การใช้ wildcard SSL certificate เป็นวิธีที่คุ้มค่ามากหากคุณมี subdomain หลายตัว

# สร้าง wildcard certificate ด้วย Let's Encrypt
sudo certbot certonly --manual --preferred-challenges=dns -d "*.example.com" -d "example.com"

# หรือใช้ Nginx plugin
sudo certbot certonly --nginx -d "*.example.com" -d "example.com"

# ตรวจสอบ certificate ที่ติดตั้ง
ls -la /etc/letsencrypt/live/example.com/

หลังจากสร้าง certificate แล้ว ให้อัปเดตไฟล์ Nginx configuration ให้ชี้ไปยังไฟล์ wildcard certificate

Subdomain Routing สำหรับ Backend ต่าง ๆ

สามารถใช้ subdomain เพื่อ route traffic ไปยังบริการ backend ต่าง ๆ ได้

# /etc/nginx/sites-available/routing.example.com
upstream api_backend {
    server localhost:3000;
}

upstream web_backend {
    server localhost:4000;
}

upstream admin_backend {
    server localhost:5000;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # Handle api.example.com
    if ($host = "api.example.com") {
        return 301 $scheme://api.example.com$request_uri;
    }
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://api_backend;
        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;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name blog.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://web_backend;
        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;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name admin.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://admin_backend;
        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;
    }
}

API Subdomain (api.example.com)

การแยก API ไปยัง subdomain ที่แตกต่างช่วยให้สามารถจัดการและปรับขยาย API ได้อย่างเป็นอิสระจากเว็บไซต์หลัก

# /etc/nginx/sites-available/api.example.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # CORS headers
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    limit_req zone=api_limit burst=20 nodelay;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Staging Subdomain (staging.example.com)

Subdomain สำหรับทดสอบเป็นวิธีที่มีประสิทธิภาพในการทดสอบการอัปเดตก่อนส่งไปยังเซิร์ฟเวอร์จริง

# /etc/nginx/sites-available/staging.example.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name staging.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/staging.example.com/public;
    index index.php index.html;

    # Basic authentication for staging
    location / {
        auth_basic "Restricted Access";
        auth_basic_user_file /etc/nginx/.htpasswd;

        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP processing
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

CDN Subdomain สำหรับ Static Assets (cdn.example.com)

การใช้ subdomain แยกสำหรับ static assets (รูป, CSS, JavaScript) สามารถลดภาระของเซิร์ฟเวอร์หลักได้

# /etc/nginx/sites-available/cdn.example.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name cdn.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/cdn.example.com;
    index index.html;

    # Caching headers for static assets
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 256;

    location / {
        try_files $uri =404;
    }
}

Regex-Based Subdomain Matching

Nginx อนุญาตให้ใช้ regex patterns เพื่อจับคู่ subdomain ซึ่งมีประโยชน์มากสำหรับการสร้าง dynamic routing

# /etc/nginx/sites-available/regex-subdomain.conf
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # Match any subdomain with regex
    server_name ~^(?<subdomain>[a-zA-Z0-9-]+)\.example\.com$;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Set root based on subdomain
    set $root_path "/var/www/$subdomain.example.com";
    root $root_path;

    # Log files with subdomain name
    access_log /var/log/nginx/$subdomain.example.com_access.log;
    error_log /var/log/nginx/$subdomain.example.com_error.log;

    location / {
        try_files $uri $uri/ /index.html =404;
    }
}

ตัวอย่างด้านบนจะจับคู่ทุก subdomain ของ example.com และตั้งค่า document root โดยอัตโนมัติ

Dynamic Subdomains ด้วย Map Directive

Nginx map directive ช่วยให้สามารถสร้าง dynamic routing บน subdomain ได้

# /etc/nginx/conf.d/subdomains.conf
map $host $backend {
    ~^api\.example\.com$ "http://localhost:3000";
    ~^blog\.example\.com$ "http://localhost:4000";
    ~^admin\.example\.com$ "http://localhost:5000";
    ~^cdn\.example\.com$ "http://localhost:6000";
    default "http://localhost:8000";
}

# /etc/nginx/sites-available/dynamic.example.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ~^(.+)\.example\.com$ example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass $backend;
        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;
    }
}

Subdomain กับ Docker Containers

หากคุณใช้ Docker containers สำหรับแต่ละบริการ ก็สามารถตั้งค่า subdomain เพื่อให้ route ไปยัง container ได้

# docker-compose.yml
version: '3'
services:
  api:
    image: node:16
    ports:
      - "3000:3000"
    networks:
      - webnet

  blog:
    image: wordpress:latest
    ports:
      - "4000:80"
    networks:
      - webnet

  nginx:
    image: nginx:latest
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./certs:/etc/nginx/certs
    depends_on:
      - api
      - blog
    networks:
      - webnet

networks:
  webnet:
    driver: bridge

# nginx.conf (inside container)
upstream api_backend {
    server api:3000;
}

upstream blog_backend {
    server blog:80;
}

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/privkey.pem;

    location / {
        proxy_pass http://api_backend;
        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;
    }
}

server {
    listen 443 ssl http2;
    server_name blog.example.com;

    ssl_certificate /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/privkey.pem;

    location / {
        proxy_pass http://blog_backend;
        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;
    }
}

SSL/TLS สำหรับทุก Subdomain

ความปลอดภัย SSL/TLS เป็นสิ่งสำคัญสำหรับทุก subdomain เพื่อป้องกันข้อมูลที่ส่งผ่าน

# ติดตั้ง Certbot
sudo apt-get install certbot python3-certbot-nginx

# สร้าง wildcard certificate สำหรับทุก subdomain
sudo certbot certonly --nginx \
  -d example.com \
  -d "*.example.com"

# ตรวจสอบ certificate
sudo certbot certificates

# Auto-renew certificate
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

ความปลอดภัยของ Subdomain

เมื่อตั้งค่า subdomain คุณควรพิจารณาประเด็นด้านความปลอดภัยต่อไปนี้:

  • CORS Policy: ตั้งค่า Cross-Origin Resource Sharing อย่างถูกต้องเพื่อป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต
  • Rate Limiting: ใช้ limit_req เพื่อป้องกัน DDoS attacks
  • Authentication: ใช้ basic auth หรือ OAuth สำหรับ subdomain ที่ไม่ต้องการสาธารณะ
  • HTTPS Only: บังคับให้ใช้ HTTPS สำหรับทุก subdomain
  • Security Headers: เพิ่ม security headers เช่น X-Frame-Options, X-Content-Type-Options
# เพิ่ม security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;

location / {
    limit_req zone=general burst=20 nodelay;
}

Best Practices และ Pattern ที่ใช้บ่อย

เมื่อตั้งค่า subdomain ใน Nginx มีหลายเรื่องที่ควรพิจารณา:

  • ชื่อ Subdomain ที่สื่อความหมาย: ใช้ชื่อที่บ่งบอกถึงวัตถุประสงค์ (api, blog, cdn, admin)
  • แยก Log Files: สร้าง access log และ error log แยกต่างหากสำหรับแต่ละ subdomain
  • Document Root แยกต่างหาก: จัดเก็บ files ของแต่ละ subdomain ในโฟลเดอร์แยก
  • ใช้ Upstream Blocks: ช่วยให้สามารถ load balance ได้ง่ายขึ้น
  • HTTP/2 และ SSL: ใช้ HTTP/2 กับ SSL เพื่อประสิทธิภาพที่ดีขึ้น
  • Monitoring: ตรวจสอบการ access และ error logs อย่างสม่ำเสมอ
# ตรวจสอบการทำงาน
sudo nginx -t

# ดูสถานะ Nginx
sudo systemctl status nginx

# ดู logs
tail -f /var/log/nginx/api.example.com_access.log
tail -f /var/log/nginx/api.example.com_error.log

สรุป

การตั้งค่า subdomain ใน Nginx ช่วยให้สามารถจัดระเบียบและจัดการเว็บไซต์ของคุณได้อย่างมีประสิทธิภาพ ไม่ว่าคุณจะใช้ dedicated server block สำหรับแต่ละ subdomain หรือ wildcard configuration คุณต้องตรวจสอบให้แน่ใจว่า DNS ถูกตั้งค่า, SSL certificates ติดตั้งแล้ว, และ Nginx configuration เหมาะสม

ข้อมูลหลักที่ควรจำ:

  • ตั้งค่า DNS A record สำหรับแต่ละ subdomain หรือใช้ wildcard record
  • สร้าง dedicated server block หรือใช้ wildcard server_name
  • ติดตั้ง wildcard SSL certificate เพื่อให้ครอบคลุมทุก subdomain
  • เพิ่มความปลอดภัยด้วย HTTPS, rate limiting, และ CORS headers
  • ใช้ upstream blocks สำหรับ load balancing และการจัดการบริการ backend
  • ตรวจสอบ log files อย่างสม่ำเสมอเพื่อหาปัญหา

แนะนำบริการ DE Cloud VPS และ Cloud Hosting

หากคุณต้องการ infrastructure ที่เสถียรและยืดหยุ่นสำหรับการตั้งค่า Nginx subdomain อย่างที่อธิบายในบทความนี้ DE Cloud VPS และ DE Cloud Hosting เป็นตัวเลือกที่เหมาะสม

DE Cloud VPS ให้คุณควบคุมเซิร์ฟเวอร์ได้อย่างสมบูรณ์ คุณสามารถติดตั้ง Nginx, ตั้งค่า subdomain, และใช้ dedicated resources ได้ทั้งหมด ด้วยการไม่จำกัด bandwidth และ SSD storage ที่รวดเร็ว คุณจะได้ประสิทธิภาพที่ดีเยี่ยมสำหรับ API, blog, หรือ CDN ของคุณ

DE Cloud Hosting เป็นทางเลือกที่ดีหากคุณต้องการความสะดวกและการจัดการโดยผู้ให้บริการ ด้วย cPanel/DirectAdmin integration คุณสามารถจัดการ subdomain ได้อย่างง่ายดายผ่าน control panel

ทั้ง DE Cloud VPS และ DE Cloud Hosting ทั้งคู่รองรับ SSL certificates, Nginx configuration, และ Docker deployment สำหรับ complex subdomain setups ที่คุณต้องการ

เยี่ยมชม: