一、Docker Compose 是什么
Docker Compose 是用 YAML 文件 (通常是 docker-compose.yml或新版 compose.yaml)定义并一键启停多容器应用 的工具,解决手动 docker run参数繁琐、多服务依赖/网络/卷难管理的问题。
Compose V2(
docker compose命令)已弱化/废弃version字段,旧版 V1(docker-compose)需声明如version: "3.8"。
二、docker-compose.yml 基本结构与完整示例
yaml
yaml
# Compose V2 可不写 version;V1 需写 version: "3.8"
services:
web:
build:
context: ./web
dockerfile: Dockerfile
image: myapp:1.0 # build 构建后打 tag
container_name: web_app
ports:
- "8080:80" # 宿主机:容器
- "127.0.0.1:9090:9090"
expose:
- "80" # 仅容器间可见
environment:
- APP_ENV=prod
- DB_HOST=db
env_file:
- .env
volumes:
- ./web:/app:ro # bind mount 只读
- app_data:/var/www/html # 命名卷
depends_on:
db:
condition: service_healthy # Compose V2 支持
redis:
condition: service_started
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
command: ["nginx", "-g", "daemon off;"]
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: appdb
volumes:
- db_data:/var/lib/mysql
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
retries: 5
redis:
image: redis:7-alpine
networks:
- backend
networks:
backend:
driver: bridge
volumes:
app_data:
db_data:
三、核心配置字段速查
| 字段 | 说明 | 面试注意点 |
|---|---|---|
image |
使用现成镜像,如 nginx:1.25 |
与 build通常二选一,build时可顺带指定 image给构建结果打 tag |
build.context/ dockerfile/ args |
指定 Dockerfile 所在目录及构建参数 | 适合本地开发构建 |
ports |
"宿主机:容器",可限定 IP 如 "127.0.0.1:8080:80" |
expose只对内网开放,不映射宿主机 |
volumes |
./host:/container[:ro]绑定挂载;卷名:/path命名卷 |
命名卷须在顶层 volumes:声明;bind mount 注意宿主机权限 |
environment/ env_file |
内联变量或从 .env文件加载 |
.env中 ${VAR}可在 compose 文件中替换;敏感信息勿提交 Git |
depends_on |
控制启动顺序,不保证应用层就绪 | 只保证先启动依赖容器,不等 DB 完全初始化 → 推荐配合 healthcheck + condition: service_healthy |
healthcheck |
CMD 检测服务是否健康 | 配合 depends_on的 service_healthy使用 |
restart |
no / always / on-failure / unless-stopped |
生产常用 unless-stopped或 always |
networks |
加入自定义 bridge 网络,服务间可用服务名做 DNS 解析 | 默认自动创建 [项目名]_default网络 |
command/ entrypoint |
覆盖容器启动命令 | --- |
container_name |
固定容器名 | 不利于 --scale扩缩容,慎用 |
四、常用命令(面试高频)
bash
bash
docker compose up -d # 后台启动所有服务(自动建网络/卷)
docker compose down # 停并删容器+网络(卷默认保留)
docker compose down -v # 连命名卷一起删
docker compose ps # 查看服务状态
docker compose logs -f 服务名 # 实时看日志
docker compose exec web bash # 进入容器
docker compose stop/start # 启停不删容器
docker compose up --scale web=3 # 扩展副本(单机有限)
五、Docker Compose 简答
Q1:Docker Compose 与 Dockerfile 的区别?
-
Dockerfile → 构建单个镜像的蓝图
-
docker-compose.yml → 编排多个容器(服务/网络/卷),定义它们如何协同运行
Q2:depends_on 有什么局限?怎么解决?
-
仅控制启动顺序,不等待依赖服务"就绪"(如 MySQL 未完成初始化)
-
方案:应用加重试逻辑,或在 Compose V2 中用
healthcheck + depends_on: {condition: service_healthy}
Q3:image 和 build 的区别?能同时写吗?
-
image拉现成镜像;build按本地 Dockerfile 构建 -
可以同时写------
build构建后用image给镜像命名打 tag,但不能混用期望 pull 又 build
Q4:数据如何持久化?bind mount vs named volume?
-
Bind mount(
./data:/var/lib/mysql)→ 挂载宿主机目录,方便开发调试 -
Named volume(
pgdata:/var/lib/postgresql/data,顶层声明)→ Docker 管理,更适合生产,跨容器共享
Q5:服务间怎么通信?
- 同一自定义网络下,直接用服务名(services 下的 key)作为 hostname 通过内部 DNS 解析,如
redis:6379、db:3306
Q6:Docker Compose 适合生产吗?和 K8s/Swarm 区别?
-
Compose 适合本地开发/小型单机部署,不支持自动调度、自愈、大规模扩缩容
-
生产大规模用 Kubernetes 或 Docker Swarm;Compose 可用
docker stack deploy转为 Swarm 模式运行
Q7:.env 文件作用?
- 存放变量供 compose 文件
${VAR}替换,避免硬编码密码/端口;记得加.gitignore
Q8:如何覆盖配置应对不同环境?
-
多文件合并:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -
或自动加载
docker-compose.override.yml(开发环境)