Docker 容器化项目标准部署指南
文档版本: v1.0
适用场景: 后端服务容器化部署
演示项目: Galaxy-API (虚拟示例项目)
开发环境: macOS (Apple Silicon M4 Pro - ARM64架构)
生产环境: Linux Server (Ubuntu - AMD64/x86_64架构)
1. 核心概念回顾
在进入部署流程前,我们需要统一对 Docker 核心资产的理解。
| 核心概念 | 类比说明 | 技术定义 |
|---|---|---|
| 镜像 (Image) | 软件安装包 | 一个只读的模板,包含代码、运行时环境、系统库和配置。一旦构建,内容不可变。 |
| 容器 (Container) | 运行中的软件进程 | 镜像运行时的实例。它是隔离的、可写的、临时的。删除容器后,容器内产生的数据会丢失(除非使用了挂载卷)。 |
| 仓库 (Registry) | 应用商店 | 存放镜像的地方,如 Docker Hub、阿里云镜像服务 (ACR)、Harbor 等。 |
2. 部署方案一:离线镜像传输 (Offline Transfer)
适用场景:服务器无法连接外网、私有化部署、或没有搭建私有镜像仓库的小型项目。 特点:操作简单,无需依赖第三方仓库,但文件传输耗时较长(每次都是全量传输)。
2.1 跨平台构建 (关键步骤)
由于开发机是 Mac (ARM64),而服务器是 Linux (AMD64),必须使用 buildx 进行交叉编译。如果直接构建,服务器上运行时会报错 exec format error。
# 在本地 Mac 终端执行
# -t 指定镜像名称和标签
# --platform 强制指定目标平台为 linux/amd64
docker buildx build --platform linux/amd64 -t galaxy-api:v1.0 .
2.2 导出镜像
将构建好的镜像保存为 tar 归档文件。
# -o 指定输出文件名
docker save -o galaxy-api.tar galaxy-api:v1.0
2.3 传输文件
使用 scp 或 SFTP 工具将镜像包和编排文件上传到服务器。
# 上传镜像包
scp galaxy-api.tar root@your-server-ip:/opt/galaxy/
# 上传编排文件
scp docker-compose.yml root@your-server-ip:/opt/galaxy/
2.4 服务器端加载
登录服务器,解压并加载镜像。
# 加载镜像到服务器的 Docker 引擎
docker load -i /opt/galaxy/galaxy-api.tar
# 验证镜像是否加载成功
docker images | grep galaxy-api
3. 部署方案二:镜像仓库分发 (Registry Distribution) —— 推荐
适用场景:正规互联网项目、需要频繁更新迭代、团队协作开发。 特点:利用 Docker 的分层存储特性,更新时只需下载变动的数据层(增量下载),速度快,且具备版本管理能力。
3.1 准备工作
你需要一个镜像仓库。可以使用:
- Docker Hub (公有,免费版有拉取次数限制)
- 云厂商镜像服务 (如阿里云 ACR、腾讯云 TCR,推荐国内使用,速度快且私有)
- Harbor (自建私有仓库)
3.2 登录仓库
# 在本地 Mac 和 远程服务器上都需要登录
docker login registry.example.com --username=yourname
3.3 构建并推送 (Build & Push)
直接将构建好的镜像推送到云端。
# 1. 标记镜像 (Tag),将其指向远程仓库地址
# 格式: docker tag [本地镜像名]:[版本] [仓库地址]/[命名空间]/[镜像名]:[版本]
docker tag galaxy-api:v1.0 [registry.example.com/myteam/galaxy-api:v1.0](https://registry.example.com/myteam/galaxy-api:v1.0)
# 2. 推送镜像 (会自动处理跨平台问题,前提是 build 时指定了 platform 或使用了 buildx push)
# 推荐使用 buildx 直接推送多架构镜像:
docker buildx build --platform linux/amd64 -t [registry.example.com/myteam/galaxy-api:v1.0](https://registry.example.com/myteam/galaxy-api:v1.0) --push .
3.4 服务器端拉取 (Pull)
在服务器的 docker-compose.yml 中,将 image 字段修改为远程仓库地址,然后直接启动。
# Docker 会自动检测本地是否有该镜像,如果没有或版本不同,会自动去仓库拉取
docker compose up -d
4. 生产环境运行配置 (Orchestration)
无论使用哪种方案,在服务器上运行容器时,建议使用 docker-compose.yml 进行管理。
4.1 配置文件示例
假设我们要部署 galaxy-api,并且它需要连接宿主机的 MySQL 数据库。
version: '3.8'
services:
galaxy-service:
# 如果是方案一,直接写镜像名:galaxy-api:v1.0
# 如果是方案二,写完整仓库地址:[registry.example.com/myteam/galaxy-api:v1.0](https://registry.example.com/myteam/galaxy-api:v1.0)
image: galaxy-api:v1.0
container_name: galaxy-prod
restart: always
# --- 网络模式选择 (二选一) ---
# 选项 A: Host 模式 (推荐用于需要高性能或直连宿主机DB的场景)
# 容器共享宿主机 IP,端口直接暴露,无需映射
network_mode: "host"
# 选项 B: Bridge 模式 (默认模式,隔离性更好)
# ports:
# - "8080:8080"
# extra_hosts:
# - "host.docker.internal:host-gateway" # 允许通过 host.docker.internal 访问宿主机
volumes:
- ./config/prod.yaml:/app/config.yaml # 挂载配置文件
- ./logs:/app/logs # 挂载日志目录
environment:
- TZ=Asia/Shanghai # 设置时区
- APP_ENV=production
4.2 服务管理命令
# 启动服务 (后台运行)
docker compose up -d
# 查看实时日志
docker compose logs -f
# 停止服务
docker compose down
# 更新镜像后重启 (无缝更新)
docker compose down && docker compose up -d
5. 常见问题排查 (Troubleshooting)
5.1 架构不兼容 (Exec format error)
- 现象:容器状态为
Exited,日志显示exec format error。 - 原因:你在 Mac (ARM64) 上使用了默认构建命令
docker build .,导致生成的镜像只能在 ARM 芯片上跑,在 Intel/AMD 服务器上跑不起来。 - 解决:务必使用
docker buildx build --platform linux/amd64。
5.2 数据库连接失败 (Connection Refused)
- 场景:代码配置写的是
127.0.0.1:3306,但在容器里连不上宿主机的 MySQL。 - 原因:
- 在默认 Bridge 模式下,容器的
localhost是容器自己,不是宿主机。 - 宿主机的 MySQL 可能绑定了
bind-address = 127.0.0.1,拒绝外部(容器IP)连接。
- 在默认 Bridge 模式下,容器的
- 解决:
- 方法 1 (最简单):使用
network_mode: "host"。 - 方法 2 (更安全):使用
extra_hosts映射,代码连接地址改为host.docker.internal,并确保 MySQL 允许非本地连接。
- 方法 1 (最简单):使用
5.3 端口冲突 (Address already in use)
- 现象:启动失败,提示端口被占用。
- 解决:
- 检查服务器上是否已经有其他进程(如 Nginx 或旧的 Java 程序)占用了该端口:
netstat -tulpn | grep 8080。 - 检查是否没有删除旧的容器:
docker ps -a。
- 检查服务器上是否已经有其他进程(如 Nginx 或旧的 Java 程序)占用了该端口:
6. 两种方案对比总结
| 特性 | 方案一:离线传输 (Docker Save/Load) | 方案二:仓库分发 (Registry/Hub) |
|---|---|---|
| 依赖环境 | 无需外网,仅需 SSH | 服务器需能访问镜像仓库 |
| 传输效率 | 低 (每次传输整个文件包,约几百MB) | 高 (仅下载变更的层,通常几十MB) |
| 版本管理 | 困难 (依赖手动文件命名) | 优秀 (Tag 管理,可回滚) |
| 安全性 | 高 (完全物理隔离) | 依赖仓库权限管理 |
| 自动化支持 | 较难集成 CI/CD | 天然支持 CI/CD 流水线 |
| 推荐指数 | ⭐⭐⭐ (适合私有化/单机交付) | ⭐⭐⭐⭐⭐ (适合互联网/团队开发) |