Docker(4) Compose

一、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(开发环境)

相关推荐
闲云自留地5 小时前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
讯捷蓝达5 小时前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
爱和冰阔落7 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
lisanmengmeng8 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮9 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹9 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_9 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_9 小时前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS9 小时前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无忧_wy9 小时前
MoneyPrinterTurbo 自动化视频生成实战指南
运维·人工智能·自动化·音视频