Docker Compose

🐳 Docker Compose

阅读原文 https://www.xiaozaoshu.top/articles/docker/compose


一、什么是 Docker Compose?

Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。你只需用一个 docker-compose.yml 文件,描述好服务的配置,然后一条命令就可以启动整个系统。

适用场景:

  • 需要运行多个服务(如 Web 服务 + 数据库 + 缓存)
  • 希望用配置文件统一管理部署
  • 开发、测试、部署环境一致性

二、安装 Docker Compose

1. 检查 Docker 是否已安装

bash 复制代码
docker -v

2. 检查 Docker Compose 是否集成(推荐使用 Docker Compose V2)

bash 复制代码
docker compose version

如果你看到版本号(如 Docker Compose version v2.27.1),说明已安装。

3. 手动安装(Linux 下,如果未集成)

bash 复制代码
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
  -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version

三、Docker Compose 文件结构详解(docker-compose.yml

一个典型的配置文件如下:

yaml 复制代码
version: "3.9"  # 指定Compose文件的语法版本

services:
  # docker run -d --name redis -p 16379:6379 redis:7.2   redis-server --requirepass 1234@qwer
  redis:
    image: redis:7.2
    container_name: xiaozaoshu-redis
    ports:
      - "16379:6379"

关键字段解释

字段 含义
version Compose 文件版本
services 定义多个服务,每个服务类似一个 docker run 容器
image 使用的镜像
build 指定 Dockerfile 构建镜像
ports 端口映射:宿主机:容器
volumes 挂载卷(主机路径:容器路径)
environment 设置环境变量
depends_on 设置服务间依赖关系
networks 指定服务所属网络(用于服务间通信)

version

Docker Compose 文件的 语法版本(Compose File Format),用于指定当前 YAML 文件使用的是哪一套规则。

Compose 文件的版本取决于你所使用的:

  1. Docker Engine 的版本
  2. Compose 的版本(V1 或 V2)
  3. 你需要使用的功能是否支持某个版本

Compose 版本历史速查

Version 新增特性
3.9 支持 init 字段(容器用 tini 初始化)
3.8 支持 profiles 分组启动服务
3.7 支持 cpu_countcpu_percent
3.4 ~ 3.6 添加 configssecrets(Swarm)
2.4 支持 healthcheck.testdepends_on.condition(V2 专属)
  • 查看 Docker 的版本命令 docker version
  • 查看 docker compose 的版本命令 docker compose version

如果你使用的是 Docker Compose V2 (Docker Desktop 2022+ 已默认内置),Compose V2 会自动使用当前 Docker 引擎支持的最新语法,无需手动指定。

建议

  • 如果你使用的是 Docker Compose V2 (大多数用户),可以 省略 version
  • 如果你需要保持兼容性(比如部署在服务器上),建议使用 version: "3.9"

四、Docker Compose 常用命令速查表

命令 功能说明 示例
docker compose up 构建并启动所有服务 docker compose up
docker compose up -d 后台运行(detach 模式) ✅ 推荐用于开发
docker compose down 停止并删除所有容器、网络、匿名卷 docker compose down
docker compose stop 停止服务,但不删除容器 docker compose stop
docker compose start 启动已停止的服务容器 docker compose start
docker compose restart 重启所有服务 docker compose restart
docker compose build 手动构建服务镜像 docker compose build
docker compose pull 拉取最新镜像 docker compose pull
docker compose push 推送镜像到远程仓库 docker compose push
docker compose ps 查看服务容器状态 docker compose ps
docker compose logs 查看日志 docker compose logs redis
docker compose logs -f 实时追踪日志 docker compose logs -f app
docker compose exec 在容器中执行命令(支持交互) docker compose exec redis redis-cli
docker compose run 启动一个一次性容器运行命令 docker compose run app npm install
docker compose config 查看合并后的配置(调试用) docker compose config
docker compose top 查看容器的进程信息 docker compose top

docker compose up

执行此命令,Docker 会在当前目录下查找:

  • docker-compose.yml(默认)
  • 也支持 docker-compose.yaml(扩展名不同)

如果你用的是默认名称,上述命令就可以直接使用,无需任何参数。

你可以自定义文件名,比如 myapp-compose.yml,然后使用 -f 指定:

docker compose -f myapp-compose.yml up

甚至可以组合多个文件:

docker compose -f docker-compose.yml -f docker-compose.override.yml up

这在区分开发 / 测试 / 生产环境时非常有用。

常见用法建议:

文件名 用途
docker-compose.yml 默认配置,推荐统一使用
docker-compose.override.yml 默认自动合并(可选)
docker-compose.prod.yml 生产环境配置
docker-compose.dev.yml 本地开发配置
docker-compose.test.yml 测试环境配置

五、实战案例

示例:部署一个 Spring Boot + MySQL + Redis 应用

项目结构

复制代码
xiaozaoshu/
├── docker-compose.yml
├── mysql/
│   └── init.d/
│       ├── 01_sys_config.sql
│       └── 02_sys_data.sql
├── app/
│   ├── Dockerfile
│   └── jar/
│       └── spring-demo.jar
app/Dockerfile
Dockerfile 复制代码
FROM openjdk:8-jdk-alpine
COPY jar/spring-demo.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose.yml
yaml 复制代码
services:
  redis:
    image: redis:7.2
    container_name: xiaozaoshu-redis
    networks:
      - docker-backend-network
    ports:
      - "16379:6379"
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]

  # Nacos config
  nacos:
    image: xiaozaoshu-nacos:v1
    container_name: xiaozaoshu-nacos
    networks:
      - docker-backend-network
    ports:
      - "18848:8848"
      - "9848:9848"
    environment:
      - MODE=standalone
    volumes:
      - ./nacos/data:/home/nacos/data  # ✅ 数据.久化
    depends_on:
      - mysql
    restart: unless-stopped

  # MySQL config
  mysql:
    image: mysql:5.7
    container_name: xiaozaoshu-mysql
    networks:
      - docker-backend-network
    ports:
      - "13306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}  # 从 .env 读取密码
    volumes:
      - ./mysql/data:/var/lib/mysql         # 数据持久化
      - ./mysql/log:/var/log/mysql           # 日志挂载
      - ./mysql/conf:/etc/mysql/conf.d       # 自定义配置
      - ./mysql/init.d:/docker-entrypoint-initdb.d  # 初始化脚本(*.sql) 脚本会按照文件名称排序后一次执行
    restart: unless-stopped

  xiaozaoshu-system:
    image: xiaozaoshu-system-shanghai:v1
    container_name: xiaozaoshu-system
    networks:
      - docker-backend-network
    extra_hosts:
      - "test-xiaozaoshu.com.cn:192.168.2.100"
    ports:
      - "8181:8181"
    environment:
      NACOS_PASSWORD: 123@Qwe
      NACOS_HOST: test-xiaozaoshu.com.cn
      NACOS_PORT: 18848
    depends_on:
      - nacos
    entrypoint: ["/wait-for-nacos.sh"]
    command: ["java", "-jar", "app.jar"]
    restart: unless-stopped

networks:
  docker-backend-network:
    external: true

由于 Docker 的 docker-entrypoint-initdb.d/ 目录中脚本是按照 文件名字典序(ASCII 排序) 自动执行的,需要通过 重命名文件 的方式来确保执行顺序。

启动项目
bash 复制代码
docker compose up -d

项目将自动启动:

  • Spring Boot 应用运行在 test-xiaozaoshu.com.cn:8181
  • MySQL 在 localhost:13306
  • Redis 在 localhost:16379

六、进阶用法

1. .env 配置环境变量

可以写在 .env 文件中:

env 复制代码
MYSQL_ROOT_PASSWORD=123456

然后在 compose 文件中使用:

yaml 复制代码
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}  # 从 .env 读取密码

2. 多个 Compose 文件组合部署(如:测试环境)

bash 复制代码
docker compose -f docker-compose.yml -f docker-compose.test.yml up

3. 自动重启策略

yaml 复制代码
restart: unless-stopped

七、常见问题排查

  • 启动依赖问题

depends-on 只能保证顺序启动,不能保证nacos 已经可以启动完成可以正常提供服务了,所以增加了 wait-for-nacos.sh,监测nacos服务的状态。

entrypoint: ["/wait-for-nacos.sh", "java", "-jar", "app.jar"]

最初使用上述配置编写Dockerfile,可能被忽略或合并不当 ,导致直接逃过了监测,直接启动应用,所以在镜像中不要定义默认的 ENTRYPOINT,或 用 Compose 的 command 明确指定启动命令

entrypoint: ["/wait-for-nacos.sh"]

command: ["java", "-jar", "app.jar"]

LinuxmacOS 下,环境变量名称(即变量名)不能以点号 (.) 开头,也不能包含点号,这是 POSIX 标准规定的。

  • 环境变量名规则问题
    • 只能包含:字母数字下划线(不能包含.
    • 必须以 字母或下划线 开头
    • 变量名区分大小写

以下变量名是非法的:

nacos.password=abc # 错误:包含点号

正确做法(示例):

你可以用下划线 _ 代替点号:

NACOS_PASSWORD: 1234qweR

Spring Boot 支持将 NACOS_PASSWORD 映射为配置属性 nacos.password

例如你可以在 Spring Boot 中这样读取:

yaml 复制代码
nacos:
  password: ${NACOS_PASSWORD}

八、卸载 Docker Compose

如果是手动安装的,可以删除:

bash 复制代码
rm ~/.docker/cli-plugins/docker-compose

九、总结

优势 说明
简洁 一份配置文件,统一管理多个服务
可移植 docker-compose.yml 可轻松复制部署
跨平台 支持 Linux / Windows / macOS
适合开发 快速启动开发环境,模拟微服务系统
相关推荐
JAVA学习通1 小时前
【JavaEE进阶】使用云服务器搭建Linux环境
linux·运维·服务器
basketball6161 小时前
Linux C 多线程基本操作
linux·运维·c语言·ubuntu
芥子沫2 小时前
ROS 与 Ubuntu 版本的对应关系
linux·运维·ubuntu
苦逼IT运维2 小时前
Jenkins 不同节点间文件传递:跨 Job 与 同 Job 的实现方法
linux·运维·ci/cd·jenkins·运维开发
杰克逊的日记2 小时前
大数据集群运维常见的一些问题以及处理方式
大数据·运维·gpu·算力
JIAKSK2 小时前
宝塔利用 Git + WebHook 实现Vitepress自动部署
运维·vitepress
m0_694845573 小时前
服务器系统时间不准确怎么办?
linux·运维·服务器·游戏·云计算
专注API从业者3 小时前
自动化商品监控:利用淘宝API开发实时价格库存采集接口
大数据·运维·前端·数据库·数据挖掘·自动化
90后小陈老师3 小时前
网络安全实验06 部署防火墙主备备份双机热备,提高网络可靠性
运维·网络·华为·ensp
睡觉z3 小时前
Kubernetes Pod调度基础
云原生·容器·kubernetes