GitHub Actions 在自托管 Runner 部署 Docker Nginx¶
目标¶
这个博客是纯 MkDocs 静态站点,部署架构调整为 Docker 运行 Nginx 容器,由 Nginx 直接托管构建后的 site/ 静态文件。
GitHub Actions Runner 部署在同一台生产服务器上,所以不需要推送镜像到远程仓库,也不需要 SSH 到另一台服务器。workflow 会直接在 runner 服务器本地构建镜像并重启容器。
当前链路是:
git push origin main
-> GitHub Actions 触发
-> 自托管 runner 拉取代码
-> docker compose up -d --build
-> Dockerfile 多阶段构建
-> mkdocs build --clean
-> 将 site/ 复制进 Nginx 镜像
-> 在本机重启 Nginx 容器
访问请求会直接进入 Nginx 容器,不再依赖腾讯云 COS 静态网站托管。
仓库关键文件¶
.github/workflows/deploy-docker-nginx.ymlDockerfilenginx/default.confdocker-compose.ymlrequirements.txtmkdocs.ymlscripts/preview.shscripts/preview.ps1
其中 workflow 负责在自托管 runner 上直接执行 compose 部署。Dockerfile 负责在镜像内构建静态站点,nginx/default.conf 负责静态文件服务与缓存策略。
本地构建镜像¶
本地运行容器¶
访问:
也可以使用 compose:
服务器部署¶
服务器同时承担 GitHub Actions self-hosted runner 和 Docker 容器运行环境。runner 用户需要能执行 Docker 命令。
如果 runner 使用 frank 用户运行,推荐把 frank 加入 docker 组:
然后重启 GitHub Actions runner 服务,或者退出并重新登录 frank 用户,让新的组权限生效:
临时方案是给 Docker 命令配置免密 sudo。workflow 已经支持自动尝试 sudo -n docker,但长期更建议使用 docker 组权限。
Runner Systemd 服务¶
仓库提供了一个 systemd unit 模板:
按当前服务器路径 /opt/actions-runner 和运行用户 frank 安装:
sudo cp deploy/actions-runner.service /etc/systemd/system/actions-runner.service
sudo systemctl daemon-reload
sudo systemctl enable actions-runner
sudo systemctl start actions-runner
如果之前用 nohup ./run.sh 启动过 runner,先停止旧进程:
查看状态和日志:
确认 frank 的 Docker 权限生效:
部署命令由 workflow 执行:
如果服务器上还有一层宿主机 Nginx、SLB 或 CDN,可以把端口映射为本机内网端口:
然后由外层入口转发到 127.0.0.1:8080。
GitHub Variables¶
进入仓库:
可选添加:
DEPLOY_CONTAINER_PORTS:容器端口映射,默认80:80PIP_INDEX_URL:Docker 构建阶段使用的 Python 包镜像源,默认https://mirrors.cloud.tencent.com/pypi/simplePIP_TRUSTED_HOST:pip 镜像源 trusted host,默认mirrors.cloud.tencent.com
GitHub Actions¶
push 到 main 后,GitHub Actions 会自动执行:
- checkout 仓库
- 检查 runner 上的 Docker 与 compose
- 执行
docker compose up -d --build --remove-orphans - 访问
127.0.0.1验证容器本地可用
本地预览¶
开发写文档时仍然可以直接使用 MkDocs 预览。
Linux/macOS:
Windows:
预览地址:
注意事项¶
docs/private/只是内容目录名,构建后仍然是公开静态页面。- 不要把真正敏感的内部资料放进仓库或导航里。
- 如果前面接 CDN,发版后可能需要刷新 CDN 缓存。
- 生产 HTTPS 可以放在外层负载均衡、CDN 或宿主机 Nginx 上终止,容器内保持 HTTP 即可。
- 如果服务器上已经有别的服务占用
80端口,可以把 GitHub Variables 里的DEPLOY_CONTAINER_PORTS设置为127.0.0.1:8080:80,再由外层 Nginx 转发。 - 如果 Action 提示无法访问
/var/run/docker.sock,说明 runner 用户没有 Docker 权限,需要把 runner 用户加入docker组并重启 runner。 - 如果 Action 在
pip install阶段出现 PyPI 下载超时,优先确认 workflow 的PIP_INDEX_URL是否指向国内镜像源。当前默认使用腾讯云 PyPI 镜像,也可以在 GitHub Variables 中改成其他可访问的源。