Portfolio
← 返回博客列表
# 镜像构建与部署全流程

2026-08-06 · 阅读 19

# 镜像构建与部署全流程

docker,acr

镜像构建与部署全流程

本文档说明如何在本地打包 Docker 镜像、推送到阿里云容器镜像服务(ACR)、并在服务器上拉取部署。


一、前置条件

项目说明
本地环境Windows + Docker Desktop(已安装并运行)
ACR 仓库crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio
服务器阿里云 ECS,已安装 Docker + docker-compose
项目根目录c:\Users\sun\Desktop\个人简历项目

1.1 确保 ACR 已登录(本地 + 服务器都需要)

# 本地 Windows PowerShell
 docker login --username=nick9138409197 crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com
# 输入密码(ACR 固定密码,不是阿里云登录密码) 
# 服务器 SSH
docker login --username=你的阿里云账号名 crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com

登录成功后会提示 Login Succeeded,凭证缓存在本地,后续无需重复登录。


二、本地构建镜像

2.1 定义镜像仓库地址(简化后续操作)

# 在 PowerShell 中设置变量(每次打开新终端需重新设置)
$REGISTRY = "crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio"

2.2 构建后端镜像(server)

cd "c:\Users\sun\Desktop\个人简历项目\server"

# 构建镜像(指定版本号)
docker build -t ${REGISTRY}/server:v1.0.2 .

# 验证镜像构建成功
docker images | findstr server

说明

  • Dockerfile 使用多阶段构建(builder → runner),最终镜像仅包含生产依赖 + 编译产物
  • 基础镜像使用 docker.1ms.run 国内加速地址
  • 构建时间约 2-5 分钟(取决于网络和机器性能)

2.3 构建前端镜像(web)

cd "c:\Users\sun\Desktop\个人简历项目\web"

# 构建镜像(传入构建参数)
docker build `
  --build-arg NEXT_PUBLIC_API_URL=https://api.kxp.o9k.cn `
  --build-arg NEXT_PUBLIC_SITE_URL=https://kxp.o9k.cn `
  -t ${REGISTRY}/web:v6 .

# 验证镜像构建成功
docker images | findstr web

说明

  • NEXT_PUBLIC_API_URLNEXT_PUBLIC_SITE_URL构建时变量,会嵌入到前端产物中,不可运行时修改
  • 如果这些值发生变化,必须重新构建镜像
  • 如果只是业务代码变更且 API 地址不变,直接构建即可(使用 Dockerfile 中的默认值)

2.4 查看构建结果

docker images | findstr my-project-portfolio

应看到类似输出:

my-project-portfolio/server   v1.0.2   abc123def456   3 minutes ago   180MB
my-project-portfolio/web       v6       def789abc012   5 minutes ago   220MB

三、推送镜像到阿里云 ACR

# 推送后端镜像
docker push ${REGISTRY}/server:v1.0.2

# 推送前端镜像
docker push ${REGISTRY}/web:v6

推送时间取决于镜像大小和网络,通常 1-3 分钟。

推送完成后可在 阿里云 ACR 控制台 查看镜像列表和各版本的 tag。


四、服务器拉取镜像并部署

4.1 SSH 连接到服务器

ssh root@120.77.222.102

4.2 拉取最新镜像

# 拉取后端镜像
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/server:v1.0.2

# 拉取前端镜像
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/web:v6

4.3 更新 docker-compose.yml 中的版本号

不要 把下面的 YAML 内容粘贴到终端执行,那不是命令。

使用 sed 一键替换版本号(在服务器上执行):

cd /root   # 或你放置 docker-compose.yml 的目录

# 替换后端镜像版本(根据实际旧版本号修改)
sed -i 's|my-project-portfolio/server:v1.0.1|my-project-portfolio/server:v1.0.2|g' docker-compose.yml

# 替换前端镜像版本(根据实际旧版本号修改)
sed -i 's|my-project-portfolio/web:v5|my-project-portfolio/web:v6|g' docker-compose.yml

# 确认修改成功
grep image docker-compose.yml

或者用 vi 手动编辑:vi docker-compose.yml,找到 serverweb 下的 image 行,修改末尾的版本号 tag。

4.4 重新启动服务

# 仅重建更新了镜像的服务(不停基础设施)
docker compose up -d server web

# 如果不确定哪些服务需要更新,可以全部重建
docker compose up -d

docker compose up -d 的行为:

  • 检测到 image tag 变化 → 自动 pull 新镜像 → 重新创建容器
  • 基础设施服务(postgres、redis、nginx)镜像没变 → 不受影响
  • 数据卷(pgdata、redisdata、uploads)不受影响

4.5 验证部署成功

# 查看容器状态(确认新镜像正在运行)
docker compose ps

# 查看后端日志(确认启动无报错)
docker compose logs --tail=50 server

# 查看前端日志
docker compose logs --tail=50 web

# 测试接口可用性
curl http://localhost:3001/api/health   # 通过 nginx-proxy 代理访问

# 测试外部访问
curl https://kxp.o9k.cn                # 前端
curl https://api.kxp.o9k.cn/api/health # 后端 API

五、完整部署命令速查(Copy & Paste)

后端更新

# ========== 本地执行 ==========
$REGISTRY = "crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio"
cd "c:\Users\sun\Desktop\个人简历项目\server"
docker build -t ${REGISTRY}/server:v1.0.2 .
docker push ${REGISTRY}/server:v1.0.2
# ========== 服务器执行 ==========
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/server:v1.0.2
# 编辑 docker-compose.yml 更新 server 的 image tag
docker compose up -d server
docker compose logs --tail=30 server

前端更新

# ========== 本地执行 ==========
$REGISTRY = "crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio"
cd "c:\Users\sun\Desktop\个人简历项目\web"
docker build --build-arg NEXT_PUBLIC_API_URL=https://api.kxp.o9k.cn --build-arg NEXT_PUBLIC_SITE_URL=https://kxp.o9k.cn -t ${REGISTRY}/web:v6 .
docker push ${REGISTRY}/web:v6
# ========== 服务器执行 ==========
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/web:v6
# 编辑 docker-compose.yml 更新 web 的 image tag
docker compose up -d web
docker compose logs --tail=30 web

同时更新前后端

# ========== 本地执行 ==========
$REGISTRY = "crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio"

# 后端
cd "c:\Users\sun\Desktop\个人简历项目\server"
docker build -t ${REGISTRY}/server:v1.0.2 .
docker push ${REGISTRY}/server:v1.0.2

# 前端
cd "c:\Users\sun\Desktop\个人简历项目\web"
docker build --build-arg NEXT_PUBLIC_API_URL=https://api.kxp.o9k.cn --build-arg NEXT_PUBLIC_SITE_URL=https://kxp.o9k.cn -t ${REGISTRY}/web:v6 .
docker push ${REGISTRY}/web:v6
# ========== 服务器执行 ==========
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/server:v1.0.2
docker pull crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com/my-project-portfolio/web:v6
# 编辑 docker-compose.yml 更新两个 image tag
docker compose up -d
docker compose ps

六、版本号管理建议

策略格式示例适用场景
语义化版本v主.次.修v1.0.0v1.0.1v1.1.0正式项目
递增数字v1, v2, v3简单直接个人项目(当前使用)
Git SHAabc1234精确对应提交CI/CD 自动化

建议:每次部署都使用新 tag,不要覆盖已有 tag。旧 tag 保留在 ACR 中,方便快速回滚。

回滚示例:只需在 docker-compose.yml 中将 image tag 改回旧版本,然后 docker compose up -d


七、常见问题

Q1:本地 docker build 失败,提示网络超时

基础镜像 docker.1ms.run 可能不可用,打开 Dockerfile 替换为其他国内镜像源:

# 替换方案
FROM docker.1ms.run/library/node:22-alpine
# ↓ 改为
FROM registry.cn-hangzhou.aliyuncs.com/library/node:22-alpine

Q2:docker push 失败,提示 unauthorized

重新登录 ACR:

docker login --username=你的阿里云账号名 crpi-7znqdwo2lmmjl5kg.cn-shenzhen.personal.cr.aliyuncs.com

Q3:服务器 docker pull 失败

  1. 确认已登录 ACR(见 Q2)
  2. 确认镜像 tag 拼写正确
  3. 检查服务器到 ACR 的网络连通性:curl https://cr.console.aliyun.com

Q4:更新后前端页面没有变化

清除浏览器缓存或使用无痕模式访问。Next.js standalone 模式下静态资源有缓存。

Q5:更新后 API 接口报错

# 查看后端容器日志
docker compose logs --tail=100 server

# 常见原因:
# - 数据库连接失败(检查 .env 文件和 postgres 容器状态)
# - 环境变量缺失(检查 .env 文件)
# - 数据库表结构未同步(检查 SYNC_DB 配置)

Q6:需要回滚到旧版本

# 1. 编辑 docker-compose.yml,将 image 改回旧版本 tag
# 2. 重新启动
docker compose up -d

八、流程图

本地 Windows                           阿里云 ACR                            服务器 ECS
─────────────                          ──────────                            ──────────
  代码修改
     │
     ▼
 docker build                             │
 (构建镜像)                                │
     │                                     │
     ▼                                     ▼
 docker tag ──────────→ docker push ──→  镜像仓库
                             │               │
                             │               ▼
                             │           docker pull
                             │               │
                             │               ▼
                             │        更新 docker-compose.yml
                             │               │
                             │               ▼
                             │        docker compose up -d
                             │               │
                             │               ▼
                             │          验证部署成功

文档生成日期:2026-08-07