你是不是也经历过这种痛苦——接手一个新项目,文档写着"三个命令就能跑起来",结果你折腾了一整天,数据库连不上、端口冲突、环境变量配错,最后发现是版本不兼容。
Docker Compose 就是来解决这个问题的。
一个 YAML 文件,定义所有服务。一行命令启动整个开发环境。不需要装 MySQL、Redis、Nginx,它们都在容器里跑得好好的。
我用了两年多 Docker Compose,最大的感受是:它不是银弹,但确实是开发效率提升最明显的工具之一。
什么是 Docker Compose?
先说人话。
Docker 容器是一个个独立的环境。你想同时跑一个 Web 服务、一个数据库、一个缓存,就得开好几个终端窗口,手动配网络、映射端口、管理生命周期。
Docker Compose 让你用一个文件管所有东西。
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
运行 docker compose up,两个服务一起启动。停止 docker compose down,全部清理。就这么简单。
实战一:搭建一个全栈开发环境
假设你要开发一个前后端分离的项目。前端用 Node.js,后端用 Python Flask,数据库用 PostgreSQL。
创建一个 docker-compose.yml 文件:
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://localhost:5000
depends_on:
- backend
backend:
build: ./backend
ports:
- "5000:5000"
volumes:
- ./backend:/app
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/mydb
depends_on:
- db
db:
image: postgres:16
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
volumes:
pgdata:
几个关键点:
volumes 挂载当前目录。这样你改代码后不需要重建镜像,热更新自动生效。
/app/node_modules 匿名卷。防止把宿主机 node_modules 覆盖掉容器内的。
depends_on。保证数据库先启动,后端再启动。注意这只是启动顺序,不代表服务就绪。
运行 docker compose up --build,三个服务一起跑起来。浏览器访问 localhost:3000,搞定。
实战二:用 .env 文件管理配置
硬编码密码在 YAML 里不安全,也不灵活。
在项目根目录创建 .env 文件:
DB_PASSWORD=secret123
API_KEY=abc123xyz
NODE_ENV=development
然后在 docker-compose.yml 里引用:
services:
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
这样每个开发者的配置可以不同,而且 .env 文件加入 .gitignore,不会泄露到仓库里。
实战三:多环境切换
开发环境和生产环境的配置往往不一样。你可以用多个 compose 文件叠加。
创建 docker-compose.prod.yml:
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.prod
ports:
- "80:80"
restart: always
backend:
build:
context: ./backend
dockerfile: Dockerfile.prod
restart: always
开发时用 docker compose up,生产时用 docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d。通过叠加文件实现配置覆盖。
实战四:常用排查命令
服务起不来?用这些命令快速定位问题:
# 查看所有服务状态
docker compose ps
# 查看某个服务的日志
docker compose logs backend
# 实时跟踪日志
docker compose logs -f db
# 进入正在运行的容器
docker compose exec backend bash
# 重启单个服务
docker compose restart backend
# 只启动依赖的服务
docker compose up --no-deps frontend
实战五:数据持久化和备份
数据库容器删了,数据就没了。用命名卷解决这个问题。
前面示例里的 pgdata 就是命名卷。即使容器重建,数据还在。
定期备份:
docker compose exec db pg_dump -U postgres mydb > backup.sql
恢复:
cat backup.sql | docker compose exec -T db psql -U postgres mydb
总结
Docker Compose 的核心价值就一句话:把环境配置变成代码。
不用每次重装系统后重新配环境。不用担心"在我机器上能跑"的问题。团队协作时,新人拉下代码,docker compose up 就能开工。
当然它也有局限——不适合超大规模部署(那是 Kubernetes 的活),调试网络问题有时比较头疼。但对于本地开发和中小型项目,它是目前性价比最高的方案。
你现在的项目里,有哪些重复配置的步骤可以交给 Docker Compose?