Apache2 + uWSGI + Flask → Nginx+ Gunicorn + Flask
- 2025.12.08
- Linux Ubuntu 22.04
前情提要
[筆記] Apache2 + Uncomplicated Firewall + uWSGI + Flask
停用 Apache2 和 uWSGI
中斷並停用 Apache2
sudo systemctl stop apache2sudo systemctl disable apache2
中斷並停用uWSGI
sudo uwsgi --stop {FlaskApps}/uwsgi/uwsgi.pidsudo nano /etc/rc.local- 註解掉 (#) 開機自動啟動 uWSGI:
# uwsgi --ini {FlaskApps}/uwsgi/uwsgi.ini
Gunicorn
- 安裝:
sudo python3 -m pip install --upgrade pip
sudo pip install gunicorn - 創建 socket 資料夾:
- 宣告 shell variable (僅限當前執行的 shell 進程):
FLASKAPPS="{FlaskApps}" sudo mkdir -p $FLASKAPPS/gunicorn_socket/
- 宣告 shell variable (僅限當前執行的 shell 進程):
- 修正 socket 資料夾權限:
sudo chown {Username}:www-data $FLASKAPPS/gunicorn_socket/sudo chmod g+w $FLASKAPPS/gunicorn_socket/
- 確認 Gunicorn 是否可運行
sudo gunicorn --chdir $FLASKAPPS main:app\
--workers 4 \
--bind unix:$FLASKAPPS/gunicorn_socket/gunicorn.sock \
--user {Username} --group www-data \
--daemon
⇒ 會在 {FlaskApps}/gunicorn_socket 下生成 gunicorn.sockps aux | grep gunicorn
⇒ 會看到數個 Gunicorn process (1 個 master process + 4 個 worker process)- 模擬 HTTP請求
curl --unix-socket $FLASKAPPS/gunicorn_socket/gunicorn.sock http://localhost/
- 設置開機自動啟動 Gunicorn
- 中止上一步中啟動的 Gunicorn processes
sudo pkill gunicorn - 創建 systemd service unit:
sudo nano /etc/systemd/system/gunicorn_flask.service- 將以下內容寫入 gunicorn_flask.service:
[Unit] Description=Gunicorn instance to serve your Flask application # 確保網路服務啟動後才啟動 Gunicorn After=network.target [Service] # Gunicorn 執行的用戶和群組 User={Username} Group=www-data # Gunicorn 尋找 main.py 的工作目錄 WorkingDirectory={FlaskApps} # 啟動前,先清除舊的 Socket 檔案,避免權限或檔案鎖定衝突 ExecStartPre=/bin/rm -f {FlaskApps}/gunicorn_socket/gunicorn.sock # Gunicorn 的完整啟動命令 ExecStart=/usr/bin/env /usr/local/bin/gunicorn --chdir {FlaskApps} main:app --workers 4 --bind unix:{FlaskApps}/gunicorn_socket/gunicorn.sock # 重新啟動策略:如果服務失敗,立即重啟 Restart=always KillSignal=SIGQUIT # 標準日誌輸出到 systemd 日誌中 StandardOutput=syslog StandardError=syslog [Install] # 告訴 systemd 在進入多用戶模式(開機完成)時啟動此服務 WantedBy=multi-user.target
- 設置開機自動啟動並開始執行 gunicorn_flask.service
- 重新載入 systemd:
sudo systemctl daemon-reload - 啟用 (設置開機自動啟動):
sudo systemctl enable gunicorn_flask.service - 立即啟動:
sudo systemctl start gunicorn_flask.service - 檢查服務狀態是否正常運作:
sudo systemctl status gunicorn_flask.service - (重啟服務:
sudo systemctl restart gunicorn_flask.service)
- 重新載入 systemd:
- 中止上一步中啟動的 Gunicorn processes
Nginx
- 安裝:
sudo apt update
sudo apt install nginx - 安裝完成後,Nginx 服務通常會自動啟動。
檢查運行狀態:sudo systemctl status nginx - 創建 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/default
寫入以下內容:server { listen 80 default_server; listen [::]:80 default_server; server_name {Domain Name 1} [{Domain Name 2} ...]; # 所有的 HTTP 流量將被重定向到 HTTPS return 301 https://$host$request_uri; }- 測試 Nginx 配置語法:
sudo nginx -t - 重新載入 Nginx 服務 已啟用新配置:
sudo systemctl reload nginx
- 設定 Uncomplicated Firewall 防火牆白名單:
sudo ufw allow 'Nginx Full' - Certbot
- 安裝:
sudo apt install certbot python3-certbot-nginx -y - 用
ps aux | grep certbot找出
是否有COMMAND使用了/usr/bin/certbot的 process?
若有:sudo kill {PID} - (確認先前是否有申請過 SSL 憑證:
sudo certbot certificates
若有:sudo certbot delete --cert-name {Certificate Name}) sudo certbot --nginx -d {Domain Name 1} [-d {Domain Name 2} ...]
- 安裝:
- 覆寫 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/default
寫入以下內容:server { listen 80 default_server; listen [::]:80 default_server; server_name {Domain Name 1} [{Domain Name 2} ...]; # 所有的 HTTP 流量將被重定向到 HTTPS return 301 https://$host$request_uri; } server { # 監聽 443 埠並啟用 SSL listen 443 ssl http2; listen [::]:443 ssl http2; server_name {Domain Name 1} [{Domain Name 2} ...]; # 憑證路徑 (使用 Certbot 已經創建的憑證) ssl_certificate /etc/letsencrypt/live/{Certificate Name}/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/{Certificate Name}/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot # 處理靜態檔案 # location /static/ { # alias {FlaskApps}/static/; # } # 代理給 Gunicorn location / { proxy_pass http://unix:{FlaskApps}/gunicorn_socket/gunicorn.s> 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 https; # 告訴 Gunicorn 這是 HTTPS 請求 } }- 測試 Nginx 配置語法:
sudo nginx -t - 重新載入 Nginx 服務 已啟用新配置:
sudo systemctl reload nginx
Last Updated on 2025/12/08 by A1go