Hướng Dẫn Triển Khai Backend Không Gián Đoạn Với Gunicorn và Caddy

Bối cảnh dự án: Hệ thống backend sử dụng framework Python/Django trên máy chủ VPS đơn

Giải pháp tổng thể

Thực hiện triển khai blue-green bằng cách chạy song song hai instance Gunicorn:
  1. Khởi động instance mới trên port dự phòng
  2. Kiểm tra sức khỏe ứng dụng trước khi chuyển lưu lượng
  3. Chuyển đổi bằng Caddy và tắt instance cũ một cách mềm mại
Giải pháp đảm bảo luôn có ít nhất một instance đang chạy trong suốt quá trình triển khai.

Cấu hình dịch vụ

app-server-xanh.service

[Unit]
Description=Backend server (Instance Xanh - Port 8000)
After=network.target

[Service]
User=www-data
WorkingDirectory=/var/www/app
ExecStart=/opt/venv/bin/gunicorn \
    --workers 4 \
    --bind 127.0.0.1:8000 \
    --timeout 120 \
    app.wsgi:application
Restart=on-failure
Environment="DJANGO_SETTINGS_MODULE=config.settings"

app-server-do.service

[Unit]
Description=Backend server (Instance Đỏ - Port 8100)
After=network.target

[Service]
User=www-data
WorkingDirectory=/var/www/app
ExecStart=/opt/venv/bin/gunicorn \
    --workers 4 \
    --bind 127.0.0.1:8100 \
    --timeout 120 \
    app.wsgi:application
Restart=on-failure
Environment="DJANGO_SETTINGS_MODULE=config.settings"

Caddyfile

api.duandemo.com {
  @media path /media/*
  handle @media {
    root * /var/www/app/media
    file_server
  }

  reverse_proxy {
    transport http {
      max_conns 250
    }
    health_check /healthz
    import /etc/caddy/active_backend.conf
  }
}

Script triển khai

setup.sh

#!/bin/bash
sudo cp app-server-*.service /etc/systemd/system/
sudo systemctl daemon-reload

# Thiết lập ban đầu cho instance Xanh
echo "to 127.0.0.1:8000" | sudo tee /etc/caddy/active_backend.conf

sudo systemctl enable --now app-server-xanh
sudo caddy reload

deploy.sh

#!/bin/bash
CURRENT_PORT=$(grep -oP ':\K\d+' /etc/caddy/active_backend.conf)
NEW_PORT=$((8000 + (CURRENT_PORT % 100)))

# Khởi động instance mới
sudo systemctl start app-server-$(($NEW_PORT == 8100 ? "do" : "xanh"))

# Kiểm tra sức khỏe
for i in {1..30}; do
  curl -sf http://127.0.0.1:$NEW_PORT/healthz && break
  sleep 2
done

# Chuyển lưu lượng
echo "to 127.0.0.1:$NEW_PORT" | sudo tee /etc/caddy/active_backend.conf > /dev/null
sudo caddy reload

# Dừng instance cũ
sudo systemctl stop app-server-$(($CURRENT_PORT == 8100 ? "xanh" : "do"))

Các lệnh quản lý

  • Khởi động ban đầu: ./setup.sh
  • Triển khai phiên bản mới: ./deploy.sh
  • Kiểm tra trạng thái: systemctl is-active app-server-xanh

Giám sát hoạt động

while true; do
  curl -s -o /dev/null -w "%{http_code} " https://api.duandemo.com/healthz
  sleep 0.5
done

Thẻ: Django gunicorn caddy blue-green deployment systemd

Đăng vào ngày 25 tháng 5 lúc 22:21