Docker Compose
嘿!长安来教你Docker Compose了!这是Docker进阶的必修课,学会了管理多容器就像玩一样简单!🚀
🤔 为什么需要Docker Compose?
痛点场景
假设你要运行一个Web应用,需要:
- Nginx
- Node.js应用
- MySQL数据库
- Redis缓存
传统方式(头疼!):
# 创建网络
docker network create my-network
# 运行MySQL
docker run -d \
--name mysql \
--network my-network \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=mydb \
-v mysql-data:/var/lib/mysql \
mysql:8.0
# 运行Redis
docker run -d \
--name redis \
--network my-network \
-v redis-data:/data \
redis:alpine
# 运行应用
docker run -d \
--name app \
--network my-network \
-e DB_HOST=mysql \
-e REDIS_HOST=redis \
-v $(pwd):/app \
my-app:latest
# 运行Nginx
docker run -d \
--name nginx \
--network my-network \
-p 80:80 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
nginx:alpine
# 😱 命令太长了!记不住!
# 😱 每次启动要敲这么多命令!
# 😱 顺序还不能错!
Docker Compose方式(爽!):
# 一个命令搞定所有!
docker-compose up -d
# ✨ 就这么简单!
📦 安装Docker Compose
Windows/Mac
Docker Desktop已经包含Docker Compose,不需要额外安装!
验证:
docker-compose --version
# 或
docker compose version
Linux
# 下载最新版
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证
docker-compose --version
💡 长安提示:Docker新版本推荐用
docker compose(空格),不带横杠
📝 第一个docker-compose.yml
创建文件
mkdir my-app
cd my-app
touch docker-compose.yml
编写配置
version: '3.8'
services:
# Web服务
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
# 数据库
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
启动服务
# 启动(后台运行)
docker-compose up -d
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs
# 停止服务
docker-compose down
就是这么简单! 🎉
📚 docker-compose.yml详解
基本结构
version: '3.8' # Compose文件版本
services: # 服务定义
service1:
...
service2:
...
networks: # 网络定义(可选)
network1:
...
volumes: # 数据卷定义(可选)
volume1:
...
services(服务)
image - 指定镜像
services:
web:
image: nginx:alpine # 使用镜像
app:
image: node:18-alpine
db:
image: mysql:8.0
build - 构建镜像
services:
app:
build: . # 当前目录的Dockerfile
app:
build:
context: ./app # 构建上下文
dockerfile: Dockerfile.dev # 指定Dockerfile
args: # 构建参数
NODE_VERSION: 18
ports - 端口映射
services:
web:
ports:
- "80:80" # 宿主机:容器
- "443:443"
- "8080:80" # 宿主机8080映射到容器80
environment - 环境变量
services:
db:
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
# 或者从文件读取
app:
env_file:
- .env
volumes - 数据卷
services:
db:
volumes:
- mysql-data:/var/lib/mysql # 命名数据卷
- ./config:/etc/mysql/conf.d # 绑定挂载
- /var/log:/var/log:ro # 只读挂载
volumes:
mysql-data: # 定义数据卷
networks - 网络
services:
web:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
depends_on - 依赖关系
services:
app:
depends_on:
- db
- redis
db:
image: mysql
redis:
image: redis
注意:depends_on只保证启动顺序,不保证服务就绪!
restart - 重启策略
services:
web:
restart: always # 总是重启
app:
restart: on-failure # 失败时重启
db:
restart: unless-stopped # 除非手动停止
command - 覆盖默认命令
services:
app:
command: npm start
db:
command: --default-authentication-plugin=mysql_native_password
🎯 实战案例
案例1:完整的Web应用栈
项目结构:
my-web-app/
├── docker-compose.yml
├── app/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
├── nginx/
│ └── nginx.conf
└── .env
docker-compose.yml:
version: '3.8'
services:
# Nginx反向代理
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
networks:
- frontend
restart: unless-stopped
# Node.js应用
app:
build: ./app
environment:
NODE_ENV: production
DB_HOST: db
DB_PORT: 3306
DB_NAME: mydb
DB_USER: user
DB_PASSWORD: ${DB_PASSWORD}
REDIS_HOST: redis
REDIS_PORT: 6379
depends_on:
- db
- redis
networks:
- frontend
- backend
restart: unless-stopped
# MySQL数据库
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
- backend
restart: unless-stopped
# Redis缓存
redis:
image: redis:alpine
volumes:
- redis-data:/data
networks:
- backend
restart: unless-stopped
networks:
frontend:
backend:
volumes:
mysql-data:
redis-data:
.env文件:
MYSQL_ROOT_PASSWORD=super-secret-password
DB_PASSWORD=user-password
启动:
docker-compose up -d
一个命令,整个应用栈都起来了! 🎉
案例2:开发环境
docker-compose.dev.yml:
version: '3.8'
services:
app:
build:
context: ./app
dockerfile: Dockerfile.dev
volumes:
- ./app:/app # 代码热更新
- /app/node_modules # node_modules不挂载
ports:
- "3000:3000"
- "9229:9229" # 调试端口
environment:
NODE_ENV: development
command: npm run dev
db:
image: mysql:8.0
ports:
- "3306:3306" # 暴露端口方便调试
environment:
MYSQL_ROOT_PASSWORD: dev123
MYSQL_DATABASE: dev_db
使用:
# 启动开发环境
docker-compose -f docker-compose.dev.yml up -d
# 查看应用日志
docker-compose -f docker-compose.dev.yml logs -f app
案例3:WordPress + MySQL
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_pass
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress-data:/var/www/html
depends_on:
- db
restart: always
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root_pass
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_pass
volumes:
- db-data:/var/lib/mysql
restart: always
volumes:
wordpress-data:
db-data:
两分钟搭建一个WordPress! 🚀
🎮 Docker Compose命令
基本命令
# 启动服务
docker-compose up # 前台运行
docker-compose up -d # 后台运行
# 停止服务
docker-compose stop # 停止(不删除容器)
docker-compose down # 停止并删除容器
docker-compose down -v # 停止并删除容器和数据卷
# 重启服务
docker-compose restart # 重启所有服务
docker-compose restart app # 重启指定服务
查看状态
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs # 所有服务的日志
docker-compose logs -f # 实时查看
docker-compose logs -f app # 查看指定服务
docker-compose logs --tail=100 app # 最后100行
执行命令
# 在运行的容器中执行命令
docker-compose exec app bash
docker-compose exec app npm install
docker-compose exec db mysql -uroot -p
# 运行一次性命令
docker-compose run app npm test
docker-compose run --rm app npm install
构建和拉取
# 构建镜像
docker-compose build
docker-compose build --no-cache app
# 拉取镜像
docker-compose pull
# 构建+启动
docker-compose up --build
扩容
# 扩容服务(运行多个实例)
docker-compose up -d --scale app=3
# 现在有3个app容器在运行!
💡 最佳实践
1. 使用.env文件
# .env
DB_PASSWORD=secret
REDIS_PASSWORD=secret
NODE_ENV=production
# docker-compose.yml
services:
app:
environment:
DB_PASSWORD: ${DB_PASSWORD}
NODE_ENV: ${NODE_ENV}
记得把.env加入.gitignore!
2. 分环境配置
# 基础配置
docker-compose.yml
# 开发环境
docker-compose.dev.yml
# 生产环境
docker-compose.prod.yml
使用:
# 开发
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# 生产
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
3. 健康检查
services:
app:
image: my-app
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
4. 资源限制
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
5. 日志管理
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
🔧 高级技巧
使用模板变量
services:
app:
image: my-app:${APP_VERSION:-latest}
environment:
API_URL: ${API_URL:-http://localhost:3000}
扩展服务配置
# 基础配置
x-common: &common
restart: unless-stopped
networks:
- app-network
services:
web:
<<: *common
image: nginx
app:
<<: *common
build: ./app
等待服务就绪
services:
app:
depends_on:
db:
condition: service_healthy
db:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 5
💡 小结
今天长安教你精通Docker Compose:
核心概念
- 作用:管理多容器应用
- 配置文件:docker-compose.yml
- 常用命令:up、down、logs、exec
- 最佳实践:环境变量、健康检查、资源限制
必会命令
docker-compose up -d # 启动
docker-compose down # 停止
docker-compose ps # 状态
docker-compose logs -f # 日志
docker-compose exec <服务> bash # 进入容器
配置要点
services: # 定义服务
service:
image: # 镜像
build: # 构建
ports: # 端口
environment: # 环境变量
volumes: # 数据卷
networks: # 网络
depends_on: # 依赖
restart: # 重启策略
🚀 下一步
Docker Compose搞定了!想让镜像更小更快?下一章长安教你 多阶段构建!
💬 长安的Compose心得:
我第一次用Docker Compose的时候,激动得要死!
以前启动项目要敲十几行命令,现在一个
docker-compose up -d就搞定了!而且配置都写在文件里,新同事来了给他一个docker-compose.yml, 一秒钟就能跑起整个项目,不用我手把手教了😂
Docker Compose是生产力工具,必须学!
建议你把自己的项目都用Compose管理起来,真的超级方便!
有问题来 编程指南 交流!
下一章见!💪
