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_onservice_healthy使用
restart no / always / on-failure / unless-stopped 生产常用 unless-stoppedalways
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:6379db: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(开发环境)

相关推荐
qq_452396231 小时前
第九篇:《Dockerfile 指令精讲(二):WORKDIR、ENV、ARG、EXPOSE》
java·开发语言·docker
八代臻1 小时前
docker代理
docker
IT策士1 小时前
第17篇 Docker Compose 进阶实战:多 Compose 文件与环境覆盖
docker·容器·eureka
utf8mb4安全女神1 小时前
磁盘管理(交换分区)(MGR分区)(GPT分区)
linux·运维·服务器
不会就选b1 小时前
linux之vim
linux·运维·vim
humors2212 小时前
聊聊密码为啥会“白设”
大数据·运维·服务器·网络·网络安全
xiaobobo33302 小时前
Ubuntu 26.04下编译s5pv210芯片的linux内核源码,无法进入menuconfig界面
linux·运维·ubuntu
kongba0072 小时前
双轨终端监视系统部署手册tmux + ttyd 实时 SSH 操作可视化方案
运维·ssh
難釋懷2 小时前
Nginx-Https证书配置
运维·nginx·https