Nginx

Nginx กับ Docker Containers — ใช้งาน Nginx ใน Container อย่างมืออาชีพ

Nginx เป็นเว็บเซิร์ฟเวอร์ที่มีประสิทธิภาพสูง และ Docker Containers เป็นเทคโนโลยีทำให้การบริหารแอปพลิเคชันง่ายขึ้น การรวมกันของ Nginx กับ Docker จึงสร้างสภาพแวดล้อมที่มืออาชีพ ปลอดภัย และสามารถขยายขนาดได้ บทความนี้จะอธิบายวิธีการใช้งาน Nginx ใน Docker Containers อย่างมืออาชีพ ตั้งแต่การสร้าง Container พื้นฐาน ไปจนถึงการตั้งค่า Reverse Proxy, SSL/TLS, และ Health Checks

เหตุใดจึงใช้ Nginx ใน Docker Containers

การใช้ Nginx ใน Docker Containers มีข้อดีมากมาย:

  • ความสอดคล้องกัน (Consistency) — แน่ใจว่าสภาพแวดล้อม Nginx เหมือนกันทุกที่ ตั้งแต่ Development ไปจนถึง Production
  • การบริหารง่าย (Simplicity) — ใช้เพียงคำสั่ง Docker ในการสร้าง, สตาร์ท, หรือหยุด Nginx Container
  • ความสามารถในการขยายขนาด (Scalability) — สร้าง Multiple Nginx Containers ขนานกันเพื่อแบ่งเบาภาระ
  • ความปลอดภัย (Security) — แยกสิ่งต่าง ๆ ออกจากกัน ลดความเสี่ยงในการเข้าถึง System ที่ไม่ได้ตั้งใจ
  • ง่ายต่อการทำความสะอาด (Easy Cleanup) — ลบ Container ก็ลบทั้งหมดไป เหลือเพียง Image ที่กำหนดไว้

Official Nginx Docker Image

Docker Hub เก็บ Official Nginx Image ที่ถูกดูแลอย่างดีโดย Docker และ Nginx Community ซึ่งมีเวอร์ชันต่าง ๆ เช่น Alpine (ขนาดเล็ก), Debian, และ Ubuntu

# ดึง Official Nginx Image (ล่าสุด)
docker pull nginx

# ดึงเวอร์ชน Alpine (ขนาดเล็ก)
docker pull nginx:alpine

# ดึงเวอร์ชนเฉพาะ
docker pull nginx:1.25.1

เลือกเวอร์ชนที่เหมาะสม: Alpine มีขนาด 50MB เท่านั้น เหมาะสำหรับ Production ที่ต้องการ Minimal Image ขณะที่ Debian เหมาะสำหรับสถานการณ์ที่ต้องการ Tools เพิ่มเติม

เรียกใช้ Nginx Container พื้นฐาน (Basic Docker Run)

วิธีพื้นฐานที่สุดในการเริ่มใช้ Nginx ใน Docker:

docker run --name my-nginx -d -p 8080:80 nginx

อธิบายคำสั่ง:

  • --name my-nginx — ตั้งชื่อ Container
  • -d — รันใน Background (Detached Mode)
  • -p 8080:80 — Bind Port 8080 บนเครื่องเรา กับ Port 80 ใน Container
  • nginx — ใช้ Official Nginx Image

ตรวจสอบสถานะ:

docker ps
docker logs my-nginx

Custom nginx.conf กับ Docker

Default Nginx Configuration ใน Image นั้นเรียบง่ายมาก ส่วนใหญ่คุณจะต้องสร้าง nginx.conf ของตัวเองเพื่อให้เหมาะกับแอปพลิเคชัน

วิธีที่ 1: ใช้ Volume Mount

สร้างไฟล์ nginx.conf บนเครื่องเรา:

server {
  listen 80;
  server_name _;

  location / {
    proxy_pass http://app:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

จากนั้นรัน Container โดย Mount ไฟล์นี้:

docker run --name my-nginx -d -p 80:80 \
  -v /path/to/nginx.conf:/etc/nginx/conf.d/default.conf \
  nginx

วิธีที่ 2: Copy ไฟล์ใน Dockerfile

สร้าง Dockerfile เพื่อจัดเก็บ Configuration:

FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Dockerfile สำหรับ Nginx

ตัวอย่าง Dockerfile ที่ครอบคลุมสำหรับ Nginx Container:

FROM nginx:1.25-alpine

# Copy configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Copy SSL certificates (if needed)
COPY /certs/*.crt /etc/nginx/certs/
COPY /certs/*.key /etc/nginx/certs/

# Create custom log directory
RUN mkdir -p /var/log/nginx && \
    chown -R nginx:nginx /var/log/nginx

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
  CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1

# Expose ports
EXPOSE 80 443

# Run Nginx
CMD ["nginx", "-g", "daemon off;"]

Docker Compose กับ Nginx

Docker Compose ทำให้การจัดการ Multi-container Environment ง่ายขึ้น นี่คือตัวอย่าง docker-compose.yml ที่ใช้ Nginx เป็น Reverse Proxy:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx_proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./certs:/etc/nginx/certs
    depends_on:
      - app
    networks:
      - app_network
    restart: unless-stopped

  app:
    image: my-app:latest
    container_name: my_app
    expose:
      - "3000"
    networks:
      - app_network
    restart: unless-stopped

networks:
  app_network:
    driver: bridge

เรียกใช้ด้วย:

docker-compose up -d

Nginx เป็น Reverse Proxy สำหรับ Docker Services

หนึ่งในการใช้ Nginx ที่สำคัญที่สุดคือทำหน้าที่เป็น Reverse Proxy เพื่อนำเสนอหลายบริการเป็นหนึ่ง URL

server {
  listen 80;
  server_name example.com;

  # Frontend service
  location / {
    proxy_pass http://frontend: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;
  }

  # API service
  location /api {
    proxy_pass http://api:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  # Admin panel
  location /admin {
    proxy_pass http://admin:8080;
    proxy_set_header Host $host;
  }
}

Multi-Container Architecture

สถาปัตยกรรมทั่วไปที่ใช้ Nginx กับ Docker:

Layer Container Purpose
Entry Point Nginx Reverse proxy, load balancing, SSL termination
Application App 1, App 2, … Business logic (Node.js, Python, PHP, etc.)
Database PostgreSQL, MySQL Data persistence
Cache Redis Session management, caching

Docker Networking

Containers ที่อยู่ใน Network เดียวกันสามารถติดต่อกันผ่านชื่อ Container:

# สร้าง Network
docker network create app_network

# เชื่อม Containers
docker run --name app --network app_network my-app:latest
docker run --name nginx --network app_network -p 80:80 nginx

# ใน nginx.conf สามารถใช้
upstream app {
  server app:3000;
}

หมายเหตุ: ชื่อ Container ต้องแมตกับชื่อในไฟล์ Configuration

SSL/TLS ใน Docker Nginx

การตั้งค่า HTTPS ใน Nginx Container:

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

  ssl_certificate /etc/nginx/certs/certificate.crt;
  ssl_certificate_key /etc/nginx/certs/private.key;

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

  location / {
    proxy_pass http://app:3000;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

# Redirect HTTP to HTTPS
server {
  listen 80;
  server_name example.com;
  return 301 https://$server_name$request_uri;
}

ใน docker-compose.yml เพิ่มการ Mount Certificate:

volumes:
  - ./nginx.conf:/etc/nginx/conf.d/default.conf
  - ./certs/certificate.crt:/etc/nginx/certs/certificate.crt
  - ./certs/private.key:/etc/nginx/certs/private.key

Environment Variables กับ envsubst

ทำให้ Configuration ยืดหยุ่นด้วย Environment Variables:

server {
  listen ${NGINX_PORT:-80};
  server_name ${SERVER_NAME:-example.com};

  location / {
    proxy_pass http://${UPSTREAM_HOST:-localhost}:${UPSTREAM_PORT:-3000};
  }
}

ใน Dockerfile:

FROM nginx:alpine

RUN apk add --no-cache gettext

COPY nginx.conf.template /etc/nginx/conf.d/default.conf.template

CMD envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && \
    nginx -g "daemon off;"

Health Checks ใน Docker

กำหนด Health Check เพื่อให้ Docker รู้ว่า Container ยังสามารถใช้งานได้หรือไม่:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

Logging ใน Docker Nginx

ดูเหตุการณ์และ Error ของ Nginx Container:

# ดูทั้งหมด
docker logs my-nginx

# ดูตัวอย่างล่าสุด
docker logs --tail 100 my-nginx

# ดูแบบ Real-time
docker logs -f my-nginx

# กำหนด Log Format ใน nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                 '$status $body_bytes_sent "$http_referer" '
                 '"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;

Nginx กับ Docker Swarm และ Kubernetes

Docker Swarm

ใน Docker Swarm Nginx ทำหน้าที่ Load Balancer และ Reverse Proxy สำหรับหลาย Replicas:

docker service create \
  --name nginx \
  -p 80:80 \
  --constraint node.role==manager \
  nginx:alpine

docker service create \
  --name web-app \
  --replicas 3 \
  --network app_network \
  my-app:latest

Kubernetes

ใน Kubernetes สามารถใช้ Nginx Ingress Controller เพื่อจัดการการเข้าถึง Services:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-app
                port:
                  number: 3000
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-app
                port:
                  number: 5000

พิจารณาประสิทธิภาพ (Performance Considerations)

เพื่อให้ Nginx ใน Docker ทำงานได้อย่างเหมาะสม:

  • Worker Processes — ตั้งให้เท่ากับจำนวน CPU Cores:
worker_processes auto;
  • Connection Pool — เพิ่ม Keepalive เพื่อลดการเชื่อมต่อใหม่:
upstream backend {
  server app1:3000 max_fails=3 fail_timeout=30s;
  server app2:3000 max_fails=3 fail_timeout=30s;
  keepalive 32;
}
  • Buffering — สำหรับ Slow Clients:
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
  • Caching — เก็บไฟล์ Static ไว้:
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
  expires 30d;
  add_header Cache-Control "public, immutable";
}

Security Best Practices

รักษาความปลอดภัยของ Nginx Container ด้วย:

  • ลดขอบเขต (Minimal Image) — ใช้ Alpine Image เพื่อลดการโจมตี
  • ไม่รัน as Root — ตั้งค่า User ใน Dockerfile:
FROM nginx:alpine
RUN addgroup -g 101 -S nginx
USER nginx
  • ปิด Unnecessary Headers:
server_tokens off;
proxy_hide_header X-Powered-By;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
  • Rate Limiting — ป้องกัน DDoS:
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;

server {
  location / {
    limit_req zone=general burst=20 nodelay;
    proxy_pass http://app:3000;
  }
}
  • CORS Headers — หากจำเป็น:
add_header 'Access-Control-Allow-Origin' '$http_origin' always;

Troubleshooting ปัญหาการใช้งาน

Container ไม่ start:

docker logs my-nginx
# ตรวจเช็ค nginx.conf ว่าถูกต้อง
docker exec my-nginx nginx -t

Connection Refused จาก Upstream:

# ตรวจสอบว่า Container อยู่ใน Network เดียวกัน
docker network ls
docker network inspect app_network

# ตรวจสอบชื่อ Container
docker ps

Slow Response:

# เพิ่ม Timeout
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# ดูการใช้ Resource
docker stats my-nginx

SSL Certificate Error:

# ตรวจสอบเส้นทางไฟล์
docker exec my-nginx ls -la /etc/nginx/certs/

# ตรวจสอบ Configuration
docker exec my-nginx nginx -t

สรุป

การใช้ Nginx กับ Docker Containers เป็นวิธีที่ยอดเยี่ยมในการสร้างสภาพแวดล้อมที่ปลอดภัย ปรับขนาดได้ และง่ายต่อการจัดการ จากการเรียกใช้ Container พื้นฐาน ไปจนถึงการตั้งค่า Reverse Proxy, SSL/TLS, Health Checks และ Logging นี่คือรากฐานที่มีประสิทธิภาพสำหรับแอปพลิเคชัน Production ในการเลือกใช้ Docker Compose, Docker Swarm หรือ Kubernetes คุณจะมีความยืดหยุ่นเต็มที่

ด้วยการเรียนรู้สิ่งเหล่านี้อย่างละเอียด คุณจะสามารถสร้าง Infrastructure ที่มืออาชีพและมีความน่าเชื่อถือในระดับ Enterprise

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

หากคุณต้องการทำงานกับ Nginx และ Docker Containers ในสภาพแวดล้อมที่ปลอดภัยและมีประสิทธิภาพสูง DE Cloud VPS เป็นตัวเลือกที่ยอดเยี่ยม ด้วยการให้บริการ Cloud Infrastructure ในประเทศไทย เรามี:

  • Cloud VPS ที่มีอำนาจ — ให้คุณเต็มอิสระในการติดตั้ง Docker, Nginx และเครื่องมืออื่น ๆ
  • Cloud Hosting — สำหรับแอปพลิเคชันที่ต้องการโซลูชันแบบ Managed พร้อมการสนับสนุนจาก Team
  • ความเร็วและความปลอดภัย — Server ตั้งอยู่ในไทย ลดปัญหา Latency และรักษาข้อมูลของคุณไว้ในประเทศ
  • การสนับสนุน 24/7 — Team ของเราพร้อมช่วยเหลือเมื่อคุณประสบปัญหาใด ๆ

ไปที่ https://de.co.th/cloud-vps หรือ https://de.co.th/cloud-hosting เพื่อเรียนรู้เพิ่มเติมและเริ่มต้นใช้งานบริการของเราวันนี้