Docker Compose实战:从零到一,轻松编排你的第一个微服务栈
1. 为什么你需要Docker Compose
第一次接触微服务开发时,我最头疼的就是要同时启动五六个服务。每个服务都要单独运行docker run命令,还得记住各种端口映射和环境变量。直到发现了Docker Compose这个神器,才明白原来容器编排可以这么简单。
Docker Compose就像是个智能管家,你只需要在一个YAML文件里写好所有服务的配置,它就能帮你一键启动整个应用栈。比如一个典型的电商系统可能包含:
- 前端Web服务
- 用户服务
- 商品服务
- 订单服务
- Redis缓存
- MySQL数据库
手动管理这些容器不仅容易出错,还特别浪费时间。而用Docker Compose,你只需要定义一次配置,就能在任何环境快速复现完整的服务集群。我去年负责的一个物流项目,从开发到上线全程使用Compose编排,部署时间从原来的2小时缩短到5分钟。
2. 环境准备与安装
2.1 安装Docker引擎
在开始之前,我们需要先安装Docker引擎。以Ubuntu系统为例:
# 更新软件包索引
sudo apt-get update
# 安装依赖包
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加Docker官方GPG密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 设置稳定版仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
安装完成后,运行docker version检查是否安装成功。建议将当前用户加入docker组,避免每次都要sudo:
sudo usermod -aG docker $USER
newgrp docker # 刷新用户组
2.2 安装Docker Compose
现在Docker Compose已经作为插件集成到Docker CLI中,安装更简单:
# 安装最新稳定版
sudo apt-get update
sudo apt-get install docker-compose-plugin
# 验证安装
docker compose version
如果系统不支持插件方式,也可以用传统方法安装:
# 下载二进制文件
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 创建软链接(可选)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
3. 第一个微服务栈实战
3.1 项目结构设计
我们来构建一个简单的博客系统,包含以下服务:
- 前端:React应用
- 后端:Node.js API服务
- 数据库:MongoDB
- 缓存:Redis
创建项目目录结构:
mkdir blog-system && cd blog-system
mkdir frontend backend
touch docker-compose.yml
3.2 编写docker-compose.yml
打开编辑器,输入以下配置:
version: '3.8'
services:
mongodb:
image: mongo:6
container_name: blog_db
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
redis:
image: redis:7
ports:
- "6379:6379"
volumes:
- redis_data:/data
backend:
build: ./backend
ports:
- "3001:3001"
depends_on:
- mongodb
- redis
environment:
DB_URL: "mongodb://root:example@mongodb:27017"
REDIS_URL: "redis://redis:6379"
frontend:
build: ./frontend
ports:
- "3000:3000"
depends_on:
- backend
volumes:
mongodb_data:
redis_data:
这个配置做了几件重要的事:
- 定义了两个数据服务(MongoDB和Redis)
- 声明了前后端服务
- 设置了服务间的依赖关系
- 配置了数据持久化卷
- 暴露了必要的服务端口
3.3 编写Dockerfile
在backend目录创建Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3001
CMD ["npm", "start"]
在frontend目录创建类似的Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
4. 运行与调试技巧
4.1 启动服务栈
在项目根目录运行:
docker compose up -d
这个命令会:
- 构建自定义镜像(frontend和backend)
- 拉取公共镜像(mongo和redis)
- 按依赖顺序启动所有容器
- -d参数表示后台运行
查看运行状态:
docker compose ps
4.2 常见问题排查
问题1:服务启动顺序导致连接失败
虽然我们用了depends_on,但它只保证容器启动顺序,不保证服务就绪。可以在backend服务中添加健康检查:
healthcheck:
test: ["CMD", "curl", "-f", "http://mongodb:27017"]
interval: 10s
timeout: 5s
retries: 5
问题2:端口冲突
如果端口被占用,可以:
- 修改docker-compose.yml中的端口映射
- 停止占用端口的服务
- 使用
netstat -tulnp | grep <端口号>查找冲突进程
问题3:容器间网络不通
确保:
- 所有服务在同一个网络(默认会自动创建)
- 使用服务名而非IP进行通信
- 检查防火墙设置
4.3 常用操作命令
# 查看日志
docker compose logs -f backend
# 执行命令
docker compose exec backend sh
# 重建服务
docker compose up -d --build frontend
# 停止服务
docker compose down
# 清理无用资源
docker system prune -f
5. 进阶配置技巧
5.1 多环境配置
可以创建多个Compose文件实现环境隔离:
docker-compose.yml # 基础配置
docker-compose.override.yml # 开发环境(默认加载)
docker-compose.prod.yml # 生产环境
开发环境配置示例:
# docker-compose.override.yml
version: '3.8'
services:
backend:
volumes:
- ./backend:/app
environment:
NODE_ENV: development
生产环境配置示例:
# docker-compose.prod.yml
version: '3.8'
services:
backend:
environment:
NODE_ENV: production
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
启动时指定配置文件:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
5.2 资源限制与扩展
services:
backend:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
memory: 256M
5.3 使用环境变量文件
创建.env文件:
DB_USER=admin
DB_PASS=secret
在compose文件中引用:
environment:
DB_USER: ${DB_USER}
DB_PASS: ${DB_PASS}
6. 真实项目经验分享
去年我在一个电商项目中使用了Docker Compose编排了12个微服务。最大的收获是学会了如何合理设计服务依赖关系。比如支付服务依赖订单服务,而订单服务又依赖商品服务,这种复杂依赖如果处理不好就会导致启动失败。
我的经验是:
- 将基础服务(数据库、消息队列等)放在独立的compose文件中
- 为每个业务域创建单独的compose文件
- 使用
depends_on结合健康检查确保启动顺序 - 为关键服务配置重启策略
restart: unless-stopped
另一个实用技巧是使用docker compose config命令验证配置文件语法,这个命令会合并所有配置并输出最终结果,非常适合调试复杂的多文件配置。
更多推荐
所有评论(0)