0

Triển khai NGINX trên nhiều môi trường: Từ localhost đến production chỉ với một lệnh

Bài viết hướng dẫn chi tiết cách triển khai ứng dụng web với NGINX trên cả môi trường local và production. Bí quyết nằm ở việc sử dụng duy nhất một lệnh docker-compose đơn giản và hiệu quả.

Bạn có thể đọc thêm: Nginx là gì? Tính năng và cách cài đặt Nginx trên Windows

Những điểm chính

  • Triển khai ứng dụng web bằng NGINX trong cả môi trường phát triển và sản xuất.
  • Đơn giản hóa việc triển khai bằng cách tự động hóa cấu hình với Docker Compose.

Norm Way: Triển khai trên máy chủ EC2

Nếu bạn muốn triển khai ứng dụng web trên máy chủ EC2 , đây là ví dụ từng bước. Dưới đây là cấu hình docker-compose tôi đã sử dụng:

Tệp Docker Compose

version: '3.8'

services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    volumes:
      - /data/test-change-streams:/data/db
    ports:
      - "27017:27017"
    networks:
      - app-network
    command: mongod --replSet test-change-streams --logpath /data/db/mongodb.log --dbpath /data/db --port 27017

  mongodb-setup:
    image: mongo:latest
    depends_on:
      - mongodb
    networks:
      - app-network
    command: >
      bash -c "
      sleep 10 &&
      mongosh --host mongodb:27017 --eval \"
      rs.initiate({
        _id: 'test-change-streams',
        members: [
          {_id: 0, host: 'mongodb:27017'}
        ]
      })
      \"
      "

  fastapi-app:
    image: multilanguage_invoice_ocr-fastapi-app
    build:
      context: .
      dockerfile: Dockerfile
    container_name: fastapi-app
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - EMAIL_USER=${EMAIL_USER}
      - EMAIL_PASSWORD=${EMAIL_PASSWORD}
      - SECRET_KEY=${SECRET_KEY}
      - ALGORITHM=${ALGORITHM}
      - ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES}
    volumes:
      - ./config:/app/config
      - ./src:/app/src
    ports:
      - "8149:8149"
    networks:
      - app-network
    depends_on:
      - mongodb
      - mongodb-setup

  jwt-frontend:
    image: multilanguage_invoice_ocr-jwt-frontend
    build:
      context: ./jwt-auth-frontend
      dockerfile: Dockerfile
    container_name: jwt-frontend
    volumes:
      - ./jwt-auth-frontend/src:/app/src
    ports:
      - "3000:3000"
    networks:
      - app-network
    depends_on:
      - fastapi-app

  nginx:
    build:
      context: ./nginx
    container_name: nginx
    volumes:
      - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template:ro
    ports:
      - "80:80"
    networks:
      - app-network
    depends_on:
      - fastapi-app
      - jwt-frontend
      - mongodb
    environment:
      - CLIENT_MAX_BODY_SIZE=${CLIENT_MAX_BODY_SIZE}
      - SERVER_IP=${SERVER_IP}

networks:
  app-network:
    driver: bridge

Giải thích

Dịch vụ nginx trong cấu hình trên hoạt động như một proxy ngược kết nối tới:

  • Giao diện (jwt-frontend)
  • Phần cuối (fastapi-app)
  • Cơ sở dữ liệu (mongodb)

Do đó mà chúng ta hãy tập trung vào dịch vụ NGINX. Các tính năng chính của NGINX trong Docker Compose:

  • Tên dịch vụ: nginx
  • Xây dựng bối cảnh: Xây dựng hình ảnh Docker từ ./nginx
  • Tên container: nginx
  • Volumes: Gắn kết chỉ đọc nginx.conf.template để cấu hình
  • Cổng: Hiển thị cổng 80
  • Mạng: Kết nối với một tùy chỉnh app-network
  • Biến môi trường: Truyền các biến như CLIENT_MAX_BODY_SIZESERVER_IP

Cấu trúc thư mục cho cấu hình NGINX

Tạo một thư mục có tên tương ứng nginx với tất cả các cấu hình liên quan:

1. Tệp Docker:

   FROM nginx:latest

   COPY start-nginx.sh /start-nginx.sh
   RUN chmod +x /start-nginx.sh
   ENTRYPOINT ["/start-Nginx.sh"]

2. Tập lệnh khởi động (start-nginx.sh):

   #!/bin/bash
   envsubst '${CLIENT_MAX_BODY_SIZE} ${SERVER_IP}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
   nginx -g 'daemon off;'

3. Mẫu cấu hình Nginx (nginx.conf.template):

events {
       worker_connections 1024;
   }

   http {
       client_max_body_size ${CLIENT_MAX_BODY_SIZE};

       server {
           listen 80;
           server_name localhost ${SERVER_IP};

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

           location /api/ {
               proxy_pass http://fastapi-app:8149/;
               proxy_read_timeout 300s;
               proxy_connect_timeout 75s;
           }

           location /mongo/ {
               proxy_pass http://mongodb:27017/;
           }
       }
   }

Cách nâng cao: Xử lý nhiều môi trường

Khi triển khai trong sản xuất, bạn có thể cần các cấu hình khác so với phát triển cục bộ. Ví dụ:

  • Sản xuất: Yêu cầu HTTPS trên cổng 443.
  • Phát triển: Cấu hình HTTP đơn giản hơn trên cổng 80.

Sự khác biệt về môi trường

image.png

Tệp Dockerfile mới

FROM nginx:latest

RUN mkdir -p /etc/nginx/dev /etc/nginx/prod
COPY dev/nginx.conf.template /etc/nginx/dev/
COPY prod/nginx.conf.template /etc/nginx/prod/
COPY start-nginx.sh /start-nginx.sh
RUN chmod +x /start-nginx.sh
ENTRYPOINT ["/start-nginx.sh"]

Đã cập nhật start-nginx.sh

#!/bin/bash

if [ "$DEBUG" = "True" ]; then
    CONFIG_PATH="/etc/nginx/dev/nginx.conf.template"
else
    CONFIG_PATH="/etc/nginx/prod/nginx.conf.template"
fi

envsubst '${CLIENT_MAX_BODY_SIZE} ${SERVER_IP}' < $CONFIG_PATH > /etc/nginx/nginx.conf
exec nginx -g 'daemon off;'

Ví dụ .env

DEBUG=True
CLIENT_MAX_BODY_SIZE=5
SERVER_IP=12.13.13.14

Phần kết luận

Với thiết lập này: Bạn có thể triển khai NGINX chỉ bằng một lệnh:

  docker compose up -d

Ứng dụng của bạn sẽ hoạt động trơn tru trong cả môi trường phát triển và sản xuất.

Hy vọng các bạn thấy thông tin hữu ích qua bài viết vừa rồi!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí