byteTuto 在 EC2 上的部署
部署流程
git push到main分支 →.github/workflows/deploy.yml触发- test 作业:
docker build、nginx -t、冒烟测试(/healthz、首页、404、CSP 头)。 - publish 作业:多架构镜像(amd64 + arm64)推送到
ghcr.io/bytetuto/website:<sha7>和:latest。 - deploy 作业:通过 SSH 连接到 EC2,写入
/opt/bytetuto/.env,复制docker-compose.yml+deploy/*.sh,运行deploy/deploy.sh。 deploy.sh:拉取镜像、up -d、等待/healthz(最长 40 秒)。失败 → 自动回滚到.last_image中的镜像。
Pull Request 只执行 test 作业。
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>的输出)。 - Variables:
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 即可。
快速诊断
| 症状 | 线索 |
|---|---|
deploy 作业:Permission denied (publickey) | EC2_SSH_KEY / EC2_USER 不正确 |
docker: permission denied | 用户不在 docker 组中 → 运行 ec2-setup.sh 后重新连接 |
pull access denied | GHCR 包为私有且登录失败,或将包设为公开 |
| 从外部访问 HTTP 超时 | 安全组:80/443 端口未开放 |
| certbot 失败 | DNS 尚未传播,或 80 端口被关闭 |
exec format error | 架构问题:确认镜像是否为多架构 |
规则
- 切勿读取或显示
.env、SSH 密钥或certbot/目录中的内容。 - 在执行
git push、ssh、scp或任何修改deploy/目录和工作流的操作之前,请求确认。