升級指南
docs/deploy/upgrade.md · 在 GitHub 上檢視首次安裝的人不需要這一頁,直接看安裝指南。這裡講的是「已經在用,想換到新版」。
系統採「向前相容遷移」:升級時資料保留,資料表結構的變更由 api 容器啟動時自動執行(alembic upgrade head),你不需要手動改資料庫。
開始前先備份。 升級本身不會刪資料,但任何重大操作前留一份備份是好習慣。到「系統管理 → 資料備份與還原 → 立即備份」,或見備份指南。
升級到 v1.4.2 ~ v1.4.18:補登、修改假別與計費方式、未請假的調課、批次 PDF、登入鎖定資安修正
v1.4.2(補登)、v1.4.3(操作紀錄修正)、v1.4.4(修改假別與計費方式)、v1.4.5(未請假的調課)、v1.4.6(全校課表匯出 PDF)、v1.4.7(登入鎖定資安修正,建議升級)、v1.4.8(自動排課自動建立草稿)、v1.4.9(同一天幾節一起調課)、v1.4.10(補登調課)、v1.4.11(鐘點統計自訂區間)、v1.4.12(調課從較早的週開始找、換不了的原因)、v1.4.13(跑班群組在班級課表的顯示)、v1.4.14(全校教師週總表)、v1.4.15(某一週實際課表、新增假別)、v1.4.16(跑班顯示、先調課再請假)、v1.4.17(調課寫出補課日期)、v1.4.18(重新發布後調課接到新課表;升級時會自動修正既有調課的資料,不改資料表)都沒有資料表變更,照下方方式 A 或方式 B 一般升級即可。
升級到 v1.4.1:授權改為 AGPL-3.0
v1.4.1 只改了授權(由 MIT 改為 AGPL-3.0),並在登入頁與側邊欄加上「原始碼」連結。功能與資料表都沒有變動, 照下方方式 A 或方式 B 一般升級即可;從 v1.3.x 或更早的版本升上來,一樣會經過 v1.4.0 的資料表變更(會先自動備份)。
升級到 v1.4.0:新增代導用的資料表
v1.4.0 新增一張「代導」用的資料表,既有的資料表與資料都不動。和 v1.3.0 一樣,api 容器發現資料庫結構
需要升級時,會先自動備份一次再升級(見下一節)。升級前已登記的假單不會補產生代導,只有升級後新登記的假單才有。
要退回 v1.3.x,請看下方「從 v1.4.0 退回 v1.3.x」。
升級到 v1.3.0:系統會自動先備份
v1.3.0 是第一個改動資料表結構的版本(新增單雙週課程用的欄位)。升級本身已在 v1.2.0、v1.2.10、 v1.2.19 三個版本的實際資料上驗證過:課表、配課、鐘點、請假、代課、統計、巡堂表升級前後完全相同。
為了讓沒看到這份說明的學校(例如 .env 設 IMAGE_TAG=latest)也受到保護,v1.3.0 起,
api 容器發現資料庫結構需要升級時,會先自動備份一次再升級:
- 備份出現在「系統管理 → 資料備份與還原」,標示「升級前自動備份」,不會被每日備份的輪替刪除。
- 升級後,系統管理員在「系統管理 → 系統版本」會看到一次提示,寫著這份備份的檔名。
- 自動備份萬一失敗(例如硬碟空間不足),系統照常升級、可以正常使用,提示會改成說明失敗原因; 這時請盡快按「立即備份」。要退回舊版仍有兩條路:升級前一晚的每日自動備份,或下方的「退回指令」。
仍建議升級前自己按一次「立即備份」並把檔案下載到另一台電腦保存——那是唯一不在同一台主機上的一份。
一條規則:docker-compose.yml 要跟著版本走
系統的容器組成會隨版本演進(例如 v1.1 就多了一個 worker-ops 容器)。升級時請連 docker-compose.yml 一起更新到新版——方式 A 重新下載該檔,方式 B 的 git pull 會自動帶到。
沿用舊 compose 檔而漏了新容器時,系統不會默默壞掉:相關功能會立刻回一句說得出處置的錯誤(例如「維運背景服務(worker-ops)沒有在執行……請更新 docker-compose.yml」),補上新檔案再 docker compose up -d 即恢復,資料不受影響。
方式 A:拉取映像部署(最常見)
在放 docker-compose.yml 的資料夾內:
# 1)(建議)先在系統內按「立即備份」
# 2) 更新 docker-compose.yml 到新版(容器組成可能有變動)
# https://raw.githubusercontent.com/begin0808/Course_Scheduling_System/main/docker-compose.yml
# 3) 選擇版本:編輯 .env
# 釘選版本(可控):IMAGE_TAG=v1.4.0
# 永遠最新: IMAGE_TAG=latest
# 4) 拉新映像並重啟
docker compose pull
docker compose up -d
docker compose up -d 只會重建映像有變動的容器;api 一啟動就自動跑遷移。完成後:
docker compose ps # 確認皆 healthy
curl http://localhost/api/health # {"status":"ok"}
登入確認資料都在、版本正確:左側選單最下方會顯示「版本 v1.2.3」這樣的版本號;系統管理員另可在「系統管理 → 系統版本」看到目前版本與最新正式版(v1.2.3 起)。
方式 B:從原始碼建置部署
git pull # 取得新版原始碼
docker compose up -d --build # 重新建置並重啟
關於版本釘選
- 正式環境建議
IMAGE_TAG=v1.4.0這樣釘住特定版本,你才能決定何時升級、升到哪一版,而不是每次pull都可能變動。 - 想升級時,把
IMAGE_TAG改成新版本號,再docker compose pull && up -d。 - 各版本的變更內容見專案根目錄的 CHANGELOG.md;破壞性變更(若有)會在該版本明確標註 ⚠️ 與對應處置。
退回舊版(升級後發現問題)
因為資料與映像分離,換回舊版映像很單純:
# .env 改回舊版本號,例如 IMAGE_TAG=v1.1.0
docker compose pull
docker compose up -d
⚠️ 注意資料庫遷移方向:若新版本引入了資料表結構變更,退回舊映像後其程式可能不認得新結構。最保險的退回方式是:退回舊映像 + 還原「升級前那份備份」(見備份指南的還原流程)。若該次升級的 CHANGELOG 未標註 schema 變更,則單純換映像即可。
從 v1.4.0 退回 v1.3.x
v1.4.0 改了資料表結構,直接把版本號改回 v1.3.x,舊版會啟動失敗。兩種退回方式擇一:
- 方式一:用升級前自動備份還原——做法同下方「從 v1.3.0 退回 v1.2.x」的方式一。升級後才登記的請假、調代課、代導不會保留。
- 方式二:退回指令(資料保留,只移除代導)——在
docker-compose.yml所在資料夾,先以 v1.4.0 執行:
bash
docker compose run --rm --entrypoint alembic api downgrade 0018_alternate_weeks
這會移除代導用的資料表(已安排的代導會一併刪除),課表、請假、代課等其他資料都不動。
接著把 .env 的 IMAGE_TAG 改回 v1.3.x,執行 docker compose pull 與 docker compose up -d。
從 v1.3.0 退回 v1.2.x
v1.3.0 改了資料表結構,直接把版本號改回 v1.2.x,舊版會啟動失敗(它不認得新的結構版本)。兩種退回方式擇一:
方式一:用升級前自動備份還原(建議)
- 在 v1.3.0 的「系統管理 → 資料備份與還原」,選標示「升級前自動備份」的那一份按「還原」。
- 還原完成後立刻把
.env的IMAGE_TAG改回舊版本號,執行docker compose pull與docker compose up -d。
資料會回到升級前那一刻;升級後才新增的資料(請假、調代課等)不會保留。
方式二:退回指令(不需要備份,資料全部保留)
還沒開始使用單雙週組時適用。在 docker-compose.yml 所在資料夾,先以 v1.3.0 執行:
docker compose run --rm --entrypoint alembic api downgrade 0017_class_name_unique
這會把資料表結構退回 v1.2.x 的樣子(只移除單雙週用的欄位),課表、請假、代課等資料都不動。
接著把 .env 的 IMAGE_TAG 改回舊版本號,執行 docker compose pull 與 docker compose up -d。
已經建了單雙週組的話,舊版看不懂那些組的資料,請改用方式一。
升級檢查清單
- ☐ 升級前已「立即備份」
- ☐ 已讀該版本 CHANGELOG,確認有無 ⚠️ 破壞性變更
- ☐
docker-compose.yml已更新到新版(容器組成可能有變動) - ☐
docker compose pull成功拉到新映像 - ☐
docker compose up -d後六容器 healthy - ☐
/api/health回 ok,登入資料完整 - ☐ (如有 schema 變更)確認關鍵頁面正常
docs/deploy/upgrade.md 自動產生(scripts/build_docs.py)。
要修改內容請改 Markdown 原始檔,不要直接編輯這份 HTML。排課與調代課系統 · AGPL-3.0 授權 · GitHub