# Docker 镜像构建与部署指南
适用于:本地 Windows 开发机构建 → 阿里云容器镜像服务托管 → Linux 服务器拉取部署。
---
## 整体流程
```
┌─────────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 本地 Windows (PS) │ │ 阿里云镜像仓库 │ │ Linux 服务器 │
│ │ │ │ │ │
│ 1. docker build │────▶│ 2. 镜像托管存储 │────▶│ 3. docker pull │
│ docker push │ │ │ │ docker run │
└─────────────────────┘ └──────────────────┘ └─────────────────┘
```
---
## 1. 前置准备
### 1.1 阿里云容器镜像服务
- 登录 [阿里云容器镜像服务](https://cr.console.aliyun.com/)
- 创建**个人实例**(免费),选择区域(如华东1-杭州)
- 创建**命名空间**(如 `myhui`)
- 创建**镜像仓库**(如 `auto-first-backend`),代码源选"本地仓库"
- 获取仓库地址,格式:`crpi-<实例ID>.<区域>.personal.cr.aliyuncs.com/<命名空间>/<仓库名>`
### 1.2 本地 Docker 登录
```powershell
# 登录阿里云镜像仓库(密码是阿里云容器镜像服务的固定密码,不是阿里云账号密码)
docker login crpi-<实例ID>.<区域>.personal.cr.aliyuncs.com
```
### 1.3 服务器 Docker 登录
```bash
docker login crpi-<实例ID>.<区域>.personal.cr.aliyuncs.com
```
---
## 2. 环境配置文件
每个环境一份 `.env` 文件,放在项目后端目录下:
```
backend/
├── .env.example # 模板(提交到 Git)
├── .env.test # 测试环境(不提交,含真实密钥)
└── .env.pro # 生产环境(不提交,含真实密钥)
```
**步骤**:
```bash
# 从模板复制
cp backend/.env.example backend/.env.test
cp backend/.env.example backend/.env.pro
# 编辑,填入对应环境的真实密钥和配置
```
> `.gitignore` 中确保已排除 `.env.test` 和 `.env.pro`。
---
## 3. Dockerfile
在 `backend/` 目录下创建 `Dockerfile`,关键点:
```dockerfile
# 构建参数:环境标识 + env 文件名
ARG CONFIG_ENV=test
ARG ENV_FILE=.env.test
# 将 env 文件打入镜像(构建时注入,运行时无需挂载)
ARG ENV_FILE
COPY ${ENV_FILE} .env
```
构建时通过 `--build-arg` 指定环境和 env 文件:
```powershell
# 测试环境
docker build --build-arg CONFIG_ENV=test --build-arg ENV_FILE=.env.test -t <镜像名>:test ./backend
# 生产环境
docker build --build-arg CONFIG_ENV=pro --build-arg ENV_FILE=.env.pro -t <镜像名>:pro ./backend
```
---
## 4. 构建脚本(本地 Windows PowerShell)
在项目根目录创建两个脚本:
### build-backend-test.ps1(测试环境)
```powershell
$ErrorActionPreference = "Stop"
$env:DOCKER_BUILDKIT = 1
# ---- 配置区(按项目修改) ----
$CONFIG_ENV = "test"
$ENV_FILE = ".env.test"
$IMAGE_REPO = "crpi-<实例ID>.<区域>.personal.cr.aliyuncs.com/<命名空间>/<仓库名>"
$TAG = "test"
# ------------------------------
$IMAGE = "${IMAGE_REPO}:${TAG}"
$BACKEND_DIR = Join-Path $PSScriptRoot "backend"
$ENV_PATH = Join-Path $BACKEND_DIR $ENV_FILE
if (-not (Test-Path $ENV_PATH)) {
throw "Env file not found: $ENV_PATH"
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Building: $IMAGE" -ForegroundColor Yellow
Write-Host "Env file: $ENV_FILE" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
# 构建
docker build --build-arg CONFIG_ENV=$CONFIG_ENV --build-arg ENV_FILE=$ENV_FILE -t $IMAGE $BACKEND_DIR
if ($LASTEXITCODE -ne 0) { exit 1 }
# 推送
Write-Host "Pushing $IMAGE ..."
docker push $IMAGE
if ($LASTEXITCODE -ne 0) { exit 1 }
Write-Host "Done!" -ForegroundColor Green
```
### build-backend-pro.ps1(生产环境)
将上面脚本中的 `$CONFIG_ENV`、`$ENV_FILE`、`$TAG` 改为:
```powershell
$CONFIG_ENV = "pro"
$ENV_FILE = ".env.pro"
$TAG = "pro"
```
---
## 5. 服务器部署命令
### 5.1 首次部署
SSH 到目标服务器后执行:
```bash
# 拉取最新镜像
docker pull <镜像仓库地址>:<tag>
# 启动容器
docker run -d \
--name <容器名> \
-p <宿主端口>:<容器端口> \
--restart unless-stopped \
<镜像仓库地址>:<tag>
# 查看日志确认启动成功
docker logs -f <容器名>
```
### 5.2 更新部署(重新部署)
```bash
# 拉取最新镜像
docker pull <镜像仓库地址>:<tag>
# 停止并删除旧容器
docker rm -f <容器名>
# 启动新容器(参数与首次部署一致)
docker run -d \
--name <容器名> \
-p <宿主端口>:<容器端口> \
--restart unless-stopped \
<镜像仓库地址>:<tag>
# 查看日志
docker logs -f <容器名>
```
> 一行版(适合快速粘贴):
> ```bash
> docker pull <镜像>:<tag> && docker rm -f <容器名> 2>/dev/null; docker run -d --name <容器名> -p <端口映射> --restart unless-stopped <镜像>:<tag>
> ```
---
## 6. 完整操作速查
```
# ===== 本地 Windows =====
# 1. 确认 env 文件存在且配置正确
# backend/.env.test → 测试环境
# backend/.env.pro → 生产环境
# 2. 执行构建脚本
.\build-backend-test.ps1 # 测试环境
.\build-backend-pro.ps1 # 生产环境
# ===== 服务器 Linux =====
# 3. SSH 登录后,拉取并重启
docker pull <镜像>:test && docker rm -f <容器名> 2>/dev/null; docker run -d --name <容器名> -p 18008:18008 --restart unless-stopped <镜像>:test
# 4. 检查
docker logs -f <容器名>
```
---
## 7. 常见问题
### Q: docker push 报 "unauthorized"
重新登录:`docker login <镜像仓库地址>`
### Q: 服务器 docker pull 报 "unauthorized"
服务器也需要登录:`docker login <镜像仓库地址>`
### Q: 如何查看容器运行状态
```bash
docker ps # 运行中的容器
docker logs --tail 100 <容器名> # 最近100行日志
docker inspect <容器名> # 容器详细信息
```
### Q: 如何回滚到上一个版本
阿里云镜像服务会保留历史版本,通过 digest 拉取指定版本:
```bash
# 查看镜像历史
docker images <镜像名>
# 指定 digest 拉取
docker pull <镜像名>@<digest>
```
### Q: 容器内环境变量不想打入镜像怎么办
用 `-e` 参数在运行时覆盖,或挂载 env 文件:
```bash
docker run -d --name <容器名> --env-file /path/to/.env -p 18008:18008 <镜像>
```
Docker 镜像构建与部署指南
_
新故事即将发生
U盘文件系统格式对比
2026-03-24