Flask 應用的 Linux 部署指南:從開發到 systemd 服務管理

#Flask #Linux #systemd #Python #WebDevelopment #Backend #Deployment #SystemService #DevOps

Table of Contents

在 Linux 環境中開發 Web 應用程式時,我們常常需要讓應用在系統啟動時自動運行,並且可以方便地透過命令行進行管理。本文將詳細介紹如何將一個簡單的 Flask 應用程式包裝成 Linux 系統服務,並利用 systemd 來管理它的生命週期。

撰寫基本的 Flask 應用

首先,我們需要建立一個簡單的 Flask 應用程式。在 /usr/local/bin/ 目錄下建立 myapp.py 檔案:

#!/usr/bin/env python3
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

if __name__ == "__main__":
    # 監聽所有介面,埠號 5000
    app.run(host="0.0.0.0", port=5000)

在這個範例中:

  • 第一行的 shebang (#!/usr/bin/env python3) 確保使用正確的 Python 解譯器
  • 我們定義了一個基本的路由「/」,當訪問時返回「Hello, World!」
  • app.run() 啟動內建開發伺服器,並監聽所有網路介面的 5000 埠

設定檔案執行權限:

sudo chmod +x /usr/local/bin/myapp.py

測試 Flask 應用

在進行下一步之前,先確認應用程式可以正常運行:

/usr/local/bin/myapp.py

在瀏覽器中打開 http://localhost:5000,應該能看到「Hello, World!」的回應。

建立 systemd 服務單元檔案

要讓 Flask 應用程式成為系統服務,我們需要建立一個 systemd 服務單元檔案。以 root 權限建立檔案 /etc/systemd/system/myapp.service

[Unit]
Description=My Flask Application
After=network.target nss-user-lookup.target

[Service]
# 直接執行檔案(已設定執行權限)
ExecStart=/usr/local/bin/myapp.py
# 若需要,可改為:
# ExecStart=/usr/bin/python3 /usr/local/bin/myapp.py

# 當應用程式異常退出時自動重啟
Restart=on-failure

# 指定執行的使用者(請替換為實際使用者名稱)
User=<your_username>

# 設定環境變數,例如設定 Flask 為 production 模式
Environment=FLASK_ENV=production

[Install]
WantedBy=multi-user.target

重要說明

  • User 設定:請確認這個使用者在系統中存在;可用 id <your_username> 檢查
  • 若使用 LDAP 或網路認證,After=nss-user-lookup.target 確保使用者資訊可正確解析
  • 使用非 root 使用者執行是安全性最佳實踐,但如需測試可暫時移除 User/Group 設定
  • Restart=on-failure 確保應用程式異常退出時會自動重新啟動

啟用與管理 systemd 服務

在建立服務檔案後,執行以下命令來啟用和管理服務:

啟用服務

# 重新載入 systemd 配置
sudo systemctl daemon-reload

# 啟用服務(開機自動啟動)
sudo systemctl enable myapp.service

# 立即啟動服務
sudo systemctl start myapp.service

# 檢查服務狀態
sudo systemctl status myapp.service

管理服務

# 停止服務
sudo systemctl stop myapp.service

# 重新啟動服務
sudo systemctl restart myapp.service

# 禁用開機自動啟動
sudo systemctl disable myapp.service

建立便捷的命令行工具

為了更方便地管理應用程式,我們可以建立一個 wrapper 腳本。在 /usr/local/bin/ 建立一個名為 myapp 的腳本:

#!/bin/bash
# Wrapper 腳本:透過 systemctl 控制 myapp.service

SERVICE_NAME=myapp.service

case "$1" in
  start)
    sudo systemctl start $SERVICE_NAME
    ;;
  stop)
    sudo systemctl stop $SERVICE_NAME
    ;;
  status)
    sudo systemctl status $SERVICE_NAME
    ;;
  restart)
    sudo systemctl restart $SERVICE_NAME
    ;;
  *)
    echo "用法: $0 {start|stop|status|restart}"
    exit 1
    ;;
esac

設定腳本為可執行:

sudo chmod +x /usr/local/bin/myapp

現在可以使用以下命令來管理應用:

  • 啟動:myapp start
  • 停止:myapp stop
  • 狀態:myapp status
  • 重啟:myapp restart

常見問題與解決方案

狀態錯誤 (status=217/USER)

  • 問題:服務啟動失敗,顯示 status=217/USER
  • 解決方案:確認 myapp.service 中指定的使用者存在,可用 id <your_username> 檢查

無法連接到應用

  • 問題:服務已啟動但無法在瀏覽器訪問
  • 解決方案:檢查防火牆設定,確保允許 5000 埠的流量
    sudo ufw allow 5000/tcp  # 若使用 UFW
    

權限問題

  • 問題:服務無法寫入日誌或訪問檔案
  • 解決方案:確認 User/Group 設定正確,並且該使用者對必要的檔案和目錄有適當權限

總結

透過這個完整的流程,我們成功將一個簡單的 Flask 應用程式包裝成 Linux 系統服務,並實現了:

  1. 開機自動啟動:透過 systemd 服務單元檔案設定
  2. 自動重啟:當應用程式異常退出時自動恢復
  3. 便捷管理:提供簡單的命令行指令進行服務管理

此方法不僅適用於 Flask 應用,也可應用於其他 Python Web 框架如 Django、FastAPI 等。根據你的專案需求,可能還需要進一步優化,例如添加日誌記錄、監控或更複雜的環境變數設定。

Disclaimer: All reference materials on this website are sourced from the internet and are intended for learning purposes only. If you believe any content infringes upon your rights, please contact me at csnote.cc@gmail.com, and I will remove the relevant content promptly.


Feedback Welcome: If you notice any errors or areas for improvement in the articles, I warmly welcome your feedback and corrections. Your input will help this blog provide better learning resources. This is an ongoing process of learning and improvement, and your suggestions are valuable to me. You can reach me at csnote.cc@gmail.com.