手动 docker build + scp 镜像的时代该翻篇了:推代码自动出镜像、服务器自动拉新版、版本号可回滚。这篇讲私有镜像仓库怎么搭、CI 流水线怎么配、发布流程怎么设计。GitHub Actions 和 Gitee Go 都有现成配置。
需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署。
一、为什么需要镜像仓库
| 方式 | 问题 |
|---|---|
| Docker Hub 公共仓库 | 国内拉取慢、公开镜像有暴露风险、私有镜像要钱 |
| scp 镜像文件 | 几个 G 传来传去,版本一多就乱 |
| 每台机器各自 build | 环境差异、构建时间浪费、无版本记录 |
私有仓库(Registry):局域网/内网机器秒拉,版本集中管理,配合 CI 全自动。镜像命名规范:
registry.example.com/项目名/服务名:版本号
registry.example.com/blog/web:1.2.3二、搭私有 Registry(30 分钟)
2.1 Docker 自建(最简单)
# 跑一个 registry 容器
docker run -d \
--name registry \
-p 5000:5000 \
-v registry_data:/var/lib/registry \
--restart unless-stopped \
registry:2
# 本机测试:打标签+推送
docker tag nginx:1.27 localhost:5000/nginx:test
docker push localhost:5000/nginx:test
# 别的机器拉取(先配 insecure-registries,见下)
docker pull 服务器IP:5000/nginx:testHTTP 仓库要配白名单(默认只信 HTTPS)。每台用仓库的机器,/etc/docker/daemon.json:
{
"insecure-registries": ["192.168.1.10:5000"]
}改完 systemctl restart docker。
2.2 带认证的仓库(多机器必配)
# 1. 建账号密码
mkdir -p /opt/registry-auth && cd /opt/registry-auth
docker run --rm --entrypoint htpasswd httpd:2 -Bbn admin 你的密码 > htpasswd
# 2. 带认证重启 registry
docker run -d --name registry -p 5000:5000 \
-v registry_data:/var/lib/registry \
-v /opt/registry-auth:/auth \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2
# 3. 客户端先登录
docker login 服务器IP:5000
# 用户名 admin,密码 上面设的2.3 现成方案(不想运维)
- Harbor:企业级,带 UI、漏洞扫描、权限管理,功能全但吃资源(4G 起步)
- Nexus:Maven/npm/docker 一体
- 云厂商 ACR/CCR:托管服务,按量付费,省心
个人/小团队自建 registry 容器就够了,别上来就 Harbor。
三、镜像版本管理规范
# 推送规范:版本号 + latest 双标签
docker build -t registry.example.com/blog/web:1.2.3 .
docker tag registry.example.com/blog/web:1.2.3 registry.example.com/blog/web:latest
docker push registry.example.com/blog/web:1.2.3
docker push registry.example.com/blog/web:latest| 标签 | 用途 |
|---|---|
1.2.3(语义化版本) | 生产部署用这个,可精确回滚 |
latest | 测试/开发用,永远是最后一次构建 |
main / 分支名 | CI 每次推代码自动构建,供测试 |
铁律:生产环境跑版本号,不跑 latest。回滚就是改 compose 里的标签号,30 秒的事:
# 回滚到 1.2.2
docker compose down
# 改 docker-compose.yml 里 image 标签为 1.2.2
docker compose up -d版本策略和镜像瘦身见Dockerfile 编写与镜像优化。
四、CI 自动构建(GitHub Actions)
仓库里放 .github/workflows/build.yml:
name: Build and Push
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set version
id: vars
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
- name: Login Registry
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ secrets.REGISTRY_URL }} -u ${{ secrets.REGISTRY_USER }} --password-stdin
- name: Build and Push
run: |
docker build -t ${{ secrets.REGISTRY_URL }}/blog/web:${{ steps.vars.outputs.VERSION }} .
docker tag ${{ secrets.REGISTRY_URL }}/blog/web:${{ steps.vars.outputs.VERSION }} ${{ secrets.REGISTRY_URL }}/blog/web:latest
docker push ${{ secrets.REGISTRY_URL }}/blog/web:${{ steps.vars.outputs.VERSION }}
docker push ${{ secrets.REGISTRY_URL }}/blog/web:latest
- name: Scan vulnerabilities
run: docker run --rm aquasec/trivy image --exit-code 1 --severity CRITICAL ${{ secrets.REGISTRY_URL }}/blog/web:${{ steps.vars.outputs.VERSION }}仓库 Settings → Secrets 里配:REGISTRY_URL、REGISTRY_USER、REGISTRY_PASSWORD——密码绝不写进 yml,不然又泄露出事,防范见Git 仓库与代码泄露防范。
Gitee Go 类似:仓库 → 流水线 → 选 Docker 模板,改登录和构建命令即可。
五、服务器自动部署
镜像推好了,服务器怎么自动更新?两种姿势:
5.1 Watchtower(自动拉新镜像)
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_POLL_INTERVAL=300 # 每 5 分钟检查一次
- WATCHTOWER_CLEANUP=true # 删旧镜像
- WATCHTOWER_INCLUDE_STOPPED=false
restart: unless-stopped测试环境很香;生产环境慎用——latest 变了就自动重启,没测试过的新版直接上线容易出事。
5.2 Webhook 部署(推荐生产)
# 服务器上跑个 webhook 服务,收到 POST 就拉新镜像重启
docker run -d --name webhook -p 9000:9000 \
-v /opt/webhook:/etc/webhook \
-v /var/run/docker.sock:/var/run/docker.sock \
almir/webhook
# hooks.json:定义触发脚本
cat > /opt/webhook/hooks.json <<'EOF'
[{
"id": "deploy-web",
"execute-command": "/opt/webhook/deploy.sh",
"command-working-directory": "/opt/app"
}]
EOF
cat > /opt/webhook/deploy.sh <<'EOF'
#!/bin/bash
cd /opt/app
docker compose pull web
docker compose up -d web
EOF
chmod +x /opt/webhook/deploy.shCI 最后加一步 curl -X POST http://服务器IP:9000/hooks/deploy-web,全链路打通:推代码 → 构建镜像 → 服务器拉新 → 重启,全程无人值守。
Webhook 地址要保密(URL 里带 token),且只对 CI 的 IP 开放,安全组见云服务器安全组配置实战。
六、维护:仓库也要养
# 看仓库占用
docker system df
# 清理:删除 7 天前的旧镜像标签(registry 容器内跑,或配 REGISTRY_STORAGE_DELETE)
# registry 2.7+ 支持 API 删除,先开环境变量:
# -e REGISTRY_STORAGE_DELETE_ENABLED=true
# 然后:
curl -X DELETE http://localhost:5000/v2/blog/web/manifests/<digest>
# 定期跑垃圾回收(真删数据)
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml磁盘涨得最快的三样:CI 每次构建的新层、没人清理的旧标签、latest 反复覆盖的层。每周一次 GC + 保留策略(只留最近 10 个版本),仓库能长期健康。
七、常见问题
| 现象 | 原因 | 解法 |
|---|---|---|
push 报 http: server gave HTTP response to HTTPS client | 没配 insecure-registries | 按第二节配 daemon.json |
| pull 超时 | 大镜像走公网 | 走内网/同区域机器拉 |
| CI 构建慢 | 没利用缓存 | 依赖层先 COPY,见Dockerfile 优化 |
| 镜像越存越大 | 没跑 GC | 定期 garbage-collect |
| 密码泄露 | 写进了 CI yml | 用 Secrets,泄露了立刻吊销 |
| 生产被自动更新搞崩 | Watchtower + latest | 改版本号部署 + Webhook 手动触发 |
镜像仓库 + CI 是容器化的最后一公里:构建一次、到处运行、版本可回滚、发布全自动。小团队用「registry 容器 + GitHub Actions + Webhook」三件套就够了,半天搭完,受益一整年。
需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署。延伸阅读:Docker 部署网站实战、Docker 数据卷与网络详解、Git 版本控制与服务器部署。
延伸阅读
- 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
- 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
- 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
- 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
- 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
- RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
- 短链接服务搭建:Shlink 自托管,链接数据自己掌握
- 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道

[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-18 回复
[...]</html>注意:CDN 脚本在国内访问不稳定,建议把 docsify 的 JS/CSS 下载到自己服务器。 Docsify 适合"今晚就要上线"的场景,长期大量文档还是构建型方案(SEO 更好、首屏更快)。五、文档站的通用功课SEO:静态文档站是搜索引擎最友好的形态,但配置要对——每个页面独立 title、配 sitemap.xml、提交收录,方法见网站 SEO 基础优化指南。速度[...]
2026-10-18 回复