Flask + SQLite

Python 建立網站使用心得站

整理用 Python 建網站的經驗、踩坑與實作心得,讓安裝、環境、Flask 與部署實作更容易上手。

閱讀方向

從環境建置開始,逐步整理 Flask、虛擬環境、套件管理與實戰心得。

網站管理員 ・ 2026-03-31 15:46:26 ・ 約 5 分鐘

用 PM2 管理多個 Python 專案:啟動、重啟與常駐作法

如果你同一台主機上會跑很多 Python 專案,例如多個 Flask 網站、排程服務或 API,光靠手動執行 python app.py 很快就會變得難管理。這時候把 pm2 拿來當成程序管理器會很方便,因為它可以統一幫你啟動、重啟、查看狀態、保存清單,甚至在主機重開後自動拉起服務。 很多人以為 pm2 只能管 Node.js,但其實它也...

如果你同一台主機上會跑很多 Python 專案,例如多個 Flask 網站、排程服務或 API,光靠手動執行 `python app.py` 很快就會變得難管理。這時候把 `pm2` 拿來當成程序管理器會很方便,因為它可以統一幫你啟動、重啟、查看狀態、保存清單,甚至在主機重開後自動拉起服務。

很多人以為 `pm2` 只能管 Node.js,但其實它也很適合拿來管理 Python 專案。關鍵做法不是直接把 `pm2` 當成 Python 執行器,而是讓它去執行一條你熟悉的 shell 指令,例如用 `gunicorn` 啟動 Flask 專案。這樣做的好處是很一致,所有專案都能用同一種方式管理。

先看最常見的啟動格式。假設你要啟動一個 Flask 專案,專案路徑在 `/root/projects/python`,要綁定 `5002` port,而且要用共用虛擬環境 `/root/projects/news/venv`,可以這樣寫:

pm2 start bash \
  --name python-site \
  --cwd /root/projects/python \
  -- -lc '/root/projects/news/venv/bin/gunicorn -w 4 -b 0.0.0.0:5002 app:app'

這條指令有幾個重點。`--name` 是程序名稱,之後你要查看、重啟、停止都會靠這個名字。`--cwd` 是工作目錄,這很重要,因為你的 Flask 專案、模板、靜態檔案與 `app:app` 都依賴正確的專案目錄。最後的 `-lc` 會讓 bash 用 login shell 的方式執行後面的指令,這對於你平常慣用 shell 環境會比較穩定。

如果你的專案是一般 Flask app,通常 `gunicorn` 啟動格式會是:

/root/projects/news/venv/bin/gunicorn -w 4 -b 0.0.0.0:5002 app:app

如果你的專案不是直接暴露 `app`,而是像工廠模式那樣使用 `create_app()`,就可以改成:

/root/projects/news/venv/bin/gunicorn -w 4 -b 0.0.0.0:5888 "app:create_app()"

當你要管理多個專案時,最實用的方式通常不是一個一個手打,而是整理成一份 shell 腳本。像你現在的 `~/projects/run.sh` 就是這種做法,每個專案固定一段:先刪除舊程序,再以一致格式重新啟動。範例如下:

pm2 delete python-site || true
pm2 start bash \
  --name python-site \
  --cwd /root/projects/python \
  -- -lc '/root/projects/news/venv/bin/gunicorn -w 4 -b 0.0.0.0:5002 app:app'

這樣的好處是很清楚。你只要打開 `run.sh`,就知道每個專案的名稱、目錄、port 與啟動方式。日後如果要搬主機、改 port、換虛擬環境或調整 worker 數,也只要改這一份。

啟動後,最常用的 `pm2` 指令大概有這些:

pm2 list
pm2 status
pm2 logs python-site
pm2 restart python-site
pm2 stop python-site
pm2 delete python-site

`pm2 list` 或 `pm2 status` 可以快速看到哪些程序在線上。`pm2 logs python-site` 很適合查錯,尤其是 Flask、Gunicorn、import 失敗、port 被占用這類問題。`pm2 restart` 是你改完程式後最常用的指令。`pm2 stop` 只是停止程序但保留定義,`pm2 delete` 則是把這個程序從 `pm2` 管理清單裡移除。

當你把所有專案都啟動好後,記得做一件很重要的事,就是保存目前程序清單。否則主機重開後,`pm2` 可能不會自動把你目前這批程序拉起來。保存方式是:

pm2 save

接著要讓 `pm2` 在系統開機時自動恢復程序,可以執行:

pm2 startup

執行後它通常會輸出一條需要你再執行一次的系統指令。把那條指令照貼執行完,再重新 `pm2 save`,這樣下次主機重開時,程序清單才會自動恢復。

如果你有很多 Python 網站,而且它們依賴差不多,共用一套虛擬環境是可行的。像這種做法就很常見:

source ~/projects/news/venv/bin/activate
python -m pip install flask gunicorn

之後每個專案都統一用這個虛擬環境裡的 `gunicorn` 啟動。這樣好處是你不用每個專案都各裝一份虛擬環境,更新套件時也比較集中。不過前提是這些專案相依版本不能差太多,否則還是建議拆開。

實務上,用 `pm2` 管理多個專案時,最重要的不是指令本身,而是命名規則與規格一致。你最好固定每個專案都有明確的 `--name`、固定的 `--cwd`、固定的 port,以及統一的啟動格式。這樣之後你只看 `pm2 list` 就能快速知道哪個服務在哪個 port、是哪個專案。

如果你現在是自己維護多個 Flask 專案,那很建議直接建立一份像 `run.sh` 這樣的總控腳本,統一負責所有站台的 `pm2 delete`、`pm2 start` 與 `pm2 save`。這會比零散手動啟動穩定得多,也更適合日後維護。

回首頁