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:- Khởi động instance mới trên port dự phòng
- Kiểm tra sức khỏe ứng dụng trước khi chuyển lưu lượng
- Chuyển đổi bằng Caddy và tắt instance cũ một cách mềm mại
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