🐳 Docker 部署完全指南 - 从本地开发到云服务器
📌 前言
很多开发者在学习 Docker 时,经常会被 docker-compose.yml 和 docker-compose.production.yml 这两个配置文件搞糊涂。他们看起来很相似,但用途却完全不同。本文将从第一性原理出发,帮你彻底理解 Docker 部署的全过程。
🎯 核心问题
为什么需要两个 Docker Compose 配置文件?
这个问题的答案,就是理解 Docker 部署的关键。
第一部分:理解镜像和容器
什么是 Docker 镜像?
Docker 镜像是一个不可变的快照,包含:
- 操作系统(如 openjdk:21-slim)
- 应用代码
- 依赖库
- 配置文件
类比:镜像就像一个蓝图或模板。
什么是 Docker 容器?
Docker 容器是镜像的运行实例。
类比:容器就像根据蓝图建造的房子。
关键区别
镜像(Image)- 蓝图
↓
docker run
↓
容器(Container)- 房子
重要:一个镜像可以启动多个容器,但所有容器都是基于同一个镜像。
第二部分:镜像的两种获取方式
方式 1: 本地构建(build)
yaml
backend:
build:
context: ./services/backend
dockerfile: Dockerfile
过程:
- 读取 Dockerfile
- 执行 Dockerfile 中的命令
- 生成镜像
- 启动容器
时间:2-5 分钟
用途:本地开发
方式 2: 远程拉取(image)
yaml
backend:
image: williamdsy/tianyan-backend:latest
过程:
- 从 Docker Hub 拉取镜像
- 启动容器
时间:30 秒
用途:云服务器部署
第三部分:完整的工作流
步骤 1: 本地开发
bash
# 修改代码
# 本地测试
docker-compose up
发生了什么:
- 读取
docker-compose.yml - 看到
build: ./services/backend - 构建镜像:
williamdsy/tianyan-backend:latest - 启动容器
- 挂载本地代码(volumes)
- 支持热重启
步骤 2: 构建镜像
bash
docker build -t williamdsy/tianyan-backend:latest ./services/backend
发生了什么:
- 读取
./services/backend/Dockerfile - 执行 Dockerfile 中的命令
- 生成镜像:
williamdsy/tianyan-backend:latest
步骤 3: 推送到 Docker Hub
bash
docker login
docker push williamdsy/tianyan-backend:latest
发生了什么:
- 登录 Docker Hub
- 上传镜像到 Docker Hub
- 镜像现在可以从任何地方拉取
步骤 4: 云服务器部署
bash
# 云服务器上
docker-compose -f docker-compose.production.yml pull
docker-compose -f docker-compose.production.yml up -d
发生了什么:
- 读取
docker-compose.production.yml - 看到
image: williamdsy/tianyan-backend:latest - 从 Docker Hub 拉取镜像
- 启动容器
第四部分:两个配置文件的区别
docker-compose.yml(本地开发)
yaml
version: '3.8'
services:
backend:
build:
context: ./services/backend
dockerfile: Dockerfile
container_name: tianyan-backend
ports:
- "8081:8080"
volumes:
- ./services/backend:/app
environment:
- SPRING_PROFILES_ACTIVE=dev
关键特点:
- ✅
build:- 本地构建镜像 - ✅
volumes:- 挂载本地代码,支持热重启 - ✅
SPRING_PROFILES_ACTIVE=dev- 开发环境配置
docker-compose.production.yml(云服务器)
yaml
version: '3.8'
services:
backend:
image: williamdsy/tianyan-backend:latest
container_name: tianyan-backend
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
关键特点:
- ✅
image:- 使用预先构建的镜像 - ❌ 没有
volumes:- 不需要挂载本地代码 - ✅
SPRING_PROFILES_ACTIVE=prod- 生产环境配置
第五部分:核心洞察
它们使用的是同一个镜像!
这是最重要的理解:
docker-compose.yml(本地)
↓
构建镜像:williamdsy/tianyan-backend:latest
↓
docker push
↓
Docker Hub
↓
docker-compose.production.yml(云服务器)
↓
拉取镜像:williamdsy/tianyan-backend:latest
↓
启动容器
关键点:
- ✅ 镜像只构建一次(在本地)
- ✅ 镜像通过 Docker Hub 传输到云服务器
- ✅ 两个配置文件使用的是同一个镜像
- ✅ 区别只是如何获取镜像
为什么需要两个配置文件?
| 方面 | 本地开发 | 云服务器 |
|---|---|---|
| 镜像来源 | 本地构建 | Docker Hub 拉取 |
| 代码挂载 | 有(支持热重启) | 无(代码已在镜像中) |
| 环境配置 | dev | prod |
| 构建时间 | 2-5 分钟 | 0 分钟 |
| 启动时间 | 快 | 快 |
第六部分:为什么这样设计?
本地开发为什么使用 build?
✅ 频繁修改代码
✅ 需要快速反馈
✅ 支持热重启
✅ 不需要推送到 Docker Hub
云服务器为什么使用 image?
✅ 代码已经在镜像中
✅ 不需要构建工具(Java、Node.js 等)
✅ 部署速度快(只需拉取镜像)
✅ 镜像已经在本地充分测试
第七部分:完整的工作流示例
场景:修改登录功能
bash
# 1. 本地修改代码
# 编辑 services/backend/src/main/kotlin/com/tianyan/api/controller/UserController.kt
# 2. 本地测试
docker-compose up
# 容器启动,代码自动挂载,支持热重启
# 3. 测试完成后,提交代码
git add .
git commit -m "feat: 改进登录功能"
git push origin feature/dev
# 4. 构建镜像
docker build -t williamdsy/tianyan-backend:latest ./services/backend
# 5. 推送到 Docker Hub
docker login
docker push williamdsy/tianyan-backend:latest
# 6. 云服务器部署
ssh root@你的服务器IP
cd /opt/tianyan
git pull origin feature/dev
docker-compose -f docker-compose.production.yml pull
docker-compose -f docker-compose.production.yml up -d
# 7. 验证部署
curl https://api.comettrail.store/api/auth/login
第八部分:常见问题
Q1: 为什么本地开发不需要 Docker Hub?
A : 因为本地开发频繁修改代码,每次修改都需要重新构建。使用 build: 方式更方便,不需要推送到 Docker Hub。
Q2: 为什么云服务器不能直接构建?
A: 可以,但不推荐。原因:
- ❌ 云服务器需要安装 Java、Node.js 等工具
- ❌ 部署速度慢(2-5 分钟)
- ❌ 构建失败会影响生产环境
Q3: 镜像可以在本地和云服务器上同时运行吗?
A: 可以。因为它们使用的是同一个镜像。
Q4: 如何回滚到之前的版本?
A: 使用镜像标签:
bash
# 推送不同版本的镜像
docker build -t williamdsy/tianyan-backend:v1.0 ./services/backend
docker push williamdsy/tianyan-backend:v1.0
# 云服务器回滚
docker-compose -f docker-compose.production.yml pull
# 修改 docker-compose.production.yml 中的镜像标签
# image: williamdsy/tianyan-backend:v1.0
docker-compose -f docker-compose.production.yml up -d
第九部分:总结
核心概念
- 镜像是不可变的快照,包含操作系统、代码、依赖等
- 容器是镜像的运行实例
- 镜像有两种获取方式:本地构建或远程拉取
- 两个配置文件使用同一个镜像,区别只是获取方式
工作流
本地开发 → 构建镜像 → 推送到 Docker Hub → 云服务器拉取 → 启动容器
优势
- ✅ 本地充分测试
- ✅ 云服务器部署快
- ✅ 支持版本管理
- ✅ 支持快速回滚
📚 参考资源
希望这篇文章能帮助你彻底理解 Docker 部署!