在 EC2 上部署 byteTuto
部署流程
git push到main→.github/workflows/deploy.yml- 測試 任務:
docker build、nginx -t、冒煙測試(/healthz、首頁、404、CSP 標頭)。 - 發布 任務:多架構映像(amd64 + arm64)推送至
ghcr.io/bytetuto/website:<sha7>及:latest。 - 部署 任務:SSH 至 EC2,寫入
/opt/bytetuto/.env,複製docker-compose.yml+deploy/*.sh,執行deploy/deploy.sh。 deploy.sh:拉取映像、up -d、等待/healthz(最多 40 秒)。失敗 → 自動回退至.last_image的映像。
Pull Request 僅執行測試任務。
GitHub Secrets / 變數(Settings → Secrets and variables → Actions)
- Secrets:
EC2_HOST、EC2_USER(ec2-user 或 ubuntu)、EC2_SSH_KEY(完整私鑰)、EC2_KNOWN_HOSTS(建議:ssh-keyscan -H <ip>的輸出)。 - 變數:
DOMAIN(例如 bytetuto.com)、LETSENCRYPT_EMAIL。 - GitHub 環境
production(可能需要手動審核)。
實用指令(在 EC2 上,目錄 /opt/bytetuto)
- 狀態:
docker compose ps· 日誌:docker compose logs -f web - 健康檢查:
curl -fsS http://127.0.0.1/healthz - 重新部署特定版本:
IMAGE=ghcr.io/bytetuto/website:<sha7> bash deploy/deploy.sh - 手動回退:使用舊標籤重新執行
deploy.sh(可在 GitHub 的 Packages 標籤頁查看)。 - HTTPS(一次設定,在 DNS 設定完成後):
bash deploy/init-ssl.sh(建議先用STAGING=1測試)。 - 憑證續約:cron 任務
/etc/cron.d/bytetuto-certbot(每日 2 次),日誌寫入certbot-renew.log。
nginx 如何選擇 HTTP 或 HTTPS
nginx/40-bytetuto-ssl.sh 在容器啟動時執行:
若 $DOMAIN 有憑證 → 使用 https.conf.template,否則 → 使用 http.conf.template。
執行 init-ssl.sh 後,只需 docker compose restart web 即可啟用 HTTPS。
快速診斷
| 症狀 | 可能原因 |
|---|---|
部署任務:Permission denied (publickey) | EC2_SSH_KEY / EC2_USER 不正確 |
docker: permission denied | 使用者未加入 docker 群組 → 執行 ec2-setup.sh 後重新登入 |
pull access denied | GHCR 套件為私人且登入失敗,或將套件設為公開 |
| 外部連線 HTTP 超時 | Security Group 未開放 80/443 連接埠 |
| certbot 失敗 | DNS 尚未傳播,或 80 連接埠未開啟 |
exec format error | 架構問題:確認映像是否為多架構 |
規則
- 絕不讀取或顯示
.env、SSH 金鑰或certbot/內容。 - 執行
git push、ssh、scp或修改deploy/及 workflow 前需先確認。