HEROKU / MIGRATION

如何從 Heroku 移轉 Web 應用程式與 PostgreSQL?

演練還原、驗證應用程式並切換流量

把 HTTP 應用程式與 PostgreSQL 從 Heroku 移走時,要逐一確認啟動方式、設定與資料的去向。本文以 KamuiDash 為目的地。先在另一個網址和空資料庫演練,再安排正式切換。

本文依據官方文件及本機傾印、還原測試。驗證範圍為本機,Heroku 正式環境與 KamuiDash 雲端還原需要另外演練。

本文內容

盤點要移轉的服務

Heroku 元件 先確認
Web 程序 執行環境、相依套件、啟動指令和 PORT
PostgreSQL 版本、擴充套件、容量、權限和連線數
Config Vars 機密資料、執行時設定和建置時設定
Worker、Scheduler、附加服務 替代服務、佇列及停止方式
郵件、Redis 和檔案 各服務要保留或移轉
網域和 Webhook DNS、回呼網址、重送及切換順序
盤點來源 · 概念圖
啟動方式
環境變數
資料庫與外部整合

把 Procfile 對應到部署指令

Heroku 的 Procfile 宣告程序類型。以 Node.js 為例,web: npm start 啟動 HTTP 程序,release: npm run migrate 在發布階段執行結構遷移。在 KamuiDash 設定安裝指令(npm ci 和需要的建置指令)、適用的啟動前指令,以及啟動指令(npm start)。使用平台提供的 PORT 並監聽 0.0.0.0。確認啟動前指令何時執行,並規劃多個副本可能同時執行結構遷移的情況。Heroku Procfile

KAMUIDASH · 畫面截圖
KamuiDash 應用程式建立畫面,可選擇執行語言與 GitHub 儲存庫。
KamuiDash 的既有範例顯示如何選擇執行環境及原始碼儲存庫。

按用途移轉環境變數

將資料庫連線換成目的地的設定,並在測試寫入前確認新網址使用哪一個資料庫。檢查郵件、驗證、金流、CORS 和回呼網址。需要在建置時讀取的值應分開設定。既有工作階段或加密資料依賴的簽章金鑰和加密金鑰要妥善保留。Heroku Config Vars

先在空的 PostgreSQL 資料庫演練還原

準備專用的空 KamuiDash 資料庫,並確認 Pro 方案可使用外部連線。安裝 KamuiDash CLI 和 PostgreSQL 用戶端工具。如果 CLI 要求,為新的專用資料庫初始化外部連線密碼。

Terminal
kamui login
kamui db connect 'YOUR_PROJECT/YOUR_DATABASE'

在 psql 執行 SELECT current_database(), current_user; 確認目標,再用 \q 離開。互動式指令會開啟 psql。如果背景程序沒有列出目標,等現有使用者結束後再重新啟動,或從另一個環境建立通道。要執行 pg_restore,請使用常駐本機通道。先確認背景程序狀態,需要時才啟動。

Terminal
kamui db daemon start
kamui db daemon status

確認目標資料庫的本機連接埠和 CLI 提示的 CA 檔案路徑。範例的本機 TLS 設定依據 CLI 0.1.22。KamuiDash CLI · 連線實作 · 通道實作

擷取並下載 Heroku 備份

如果來源資料庫的附掛名稱不同,請替換 DATABASE_URL。將 b123 換成擷取指令顯示的備份 ID。下載前確認備份已完成,且對應正確的資料庫。演練和正式切換請使用不同檔名。Heroku 建議將 PGBackups 用於負荷適中且不超過 20 GB 的資料庫。Advanced 請採用適合的邏輯備份流程。Heroku PGBackups · Heroku 邏輯備份

Terminal
export HEROKU_APP_NAME='your-source-app'
heroku pg:backups:capture DATABASE_URL --app "$HEROKU_APP_NAME"
BACKUP_ID='b123'
heroku pg:backups:info "$BACKUP_ID" --app "$HEROKU_APP_NAME"
heroku pg:backups:download "$BACKUP_ID" --app "$HEROKU_APP_NAME" --output migration.dump
pg_restore --list migration.dump

傾印含有正式資料,請限制存取並避免提交至 Git。列出封存檔內容只是初步檢查,正式移轉前仍應演練還原。Heroku 匯出指南

還原到專用資料庫

在 ~/.pg_service.conf 加入服務設定。使用目標資料庫的實際外部連線資訊,替換範例連接埠、資料庫名稱、使用者及 CA 路徑。保持通道運作,依提示輸入密碼。

Code
[kamui-migration-target]
host=127.0.0.1
hostaddr=127.0.0.1
port=32000
dbname=YOUR_EXTERNAL_DB_NAME
user=YOUR_EXTERNAL_DB_USER
sslmode=verify-full
sslrootcert=/ABSOLUTE/PATH/SHOWN/BY/CLI/ca.pem
gssencmode=disable

先透過目的地應用程式的資料庫連線執行 SELECT current_user;,確認角色名稱後替換 YOUR_APP_DB_ROLE。切換至該角色可讓應用程式擁有還原的資料表及序列。若 SET ROLE 失敗,請停止並與管理員確認可用的還原方式。

Terminal
psql 'service=kamui-migration-target' -W \
  -c 'SELECT current_database(), current_user, version();'

export KAMUI_APP_DB_ROLE='YOUR_APP_DB_ROLE'
psql 'service=kamui-migration-target' -W -v ON_ERROR_STOP=1 \
  -v "app_role=$KAMUI_APP_DB_ROLE" <<'SQL'
SET ROLE :"app_role";
SELECT current_user;
SQL

pg_restore \
  --role="$KAMUI_APP_DB_ROLE" \
  --dbname='service=kamui-migration-target' \
  -W \
  --no-owner --no-privileges \
  --exit-on-error --single-transaction \
  migration.dump

還原時會略過來源的擁有者和權限,應依應用程式需求補上權限。單一交易可在失敗時避免留下部分還原的資料。確認擴充套件、用戶端和伺服器的版本、權限、序列,以及大型資料庫可能涉及的時間與鎖定。正式移轉前,先用測試資料驗證相同的還原路徑。PostgreSQL pg_dump · PostgreSQL pg_restore

用新網址確認程式和資料

檢查代表性記錄、關聯資料、時間、序列、登入、寫入與更新。另行測試檔案儲存和外部整合。

KAMUIDASH · 畫面截圖
KamuiDash 靜態網站詳細資訊:執行狀態、公開網址、GitHub 分支與各次提交的部署紀錄。
既有靜態網站範例顯示公開網址與部署版本。移轉後還要驗證實際讀寫。

最後切換前停止寫入

正式切換 · 概念圖
停止寫入
備份與還原
驗證、切換並恢復
  1. 通知使用者維護時段,停止舊應用程式、排程、Webhook 和其他用戶端的寫入。
  2. 擷取最終備份,還原到為正式切換準備的空資料庫。
  3. 讓新應用程式連上正式資料庫並驗證,舊系統保持停止寫入。
  4. 切換網域和 Webhook 目標,監控仍流向舊服務的請求。
  5. 只在新系統恢復寫入。

Heroku 維護模式會阻擋 HTTP 路由,但 dyno 仍會執行。Fir 不支援維護模式,請從應用程式等處阻擋寫入。記下目前的程序配置,停止會寫入的背景程序與排程,等進行中的交易結束後才擷取最終備份。新服務也應禁止寫入,包括預設網址與背景工作,切換前以唯讀方式驗證。Heroku 維護模式

DNS 快取可能讓新舊服務同時收到請求。若無法暫停寫入,應另行規劃持續同步及差異處理。新系統開始寫入後,切回舊系統前還要處理新增或變更的資料。請事先決定回復期限、停寫程序與資料同步方式。

常見問題

Heroku 附加服務會一起移轉嗎?

逐一盤點。背景工作、郵件、佇列及排程可能需要分別移轉或重新設定。

何時要執行資料庫結構遷移?

先將傾印還原到空資料庫。確認應用程式版本與還原後的結構相容,再套用額外需要的變更。

Ruby 和 Python 也適用嗎?

盤點和資料庫步驟可以沿用。依執行環境調整相依套件、建置、啟動和資料庫結構遷移指令。

KamuiDash 是位於東京區域的 PaaS,可透過 GitHub 與 AI 整合公開 Web 應用程式。