Docker Compose

什么是Docker compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用编排的工具。它使得开发者可以使用一个单独的 YAML 文件来定义应用所需的所有服务、网络和卷,从而简化了多容器应用的配置和管理。

它的核心用途是:通过一个 YAML 文件(docker-compose.yml),定义、配置和启动由多个 Docker 容器组成的完整应用程序栈。

简单来说,如果你需要手动运行 3-4 条 docker run 命令来启动一个包含数据库、缓存和后端服务的系统,Docker Compose 允许你把这些命令写在一个文件里,然后只需执行一条命令 docker compose up 即可一键启动整个系统。

Compose 的设计理念是"声明式管理",不是"附加上去管理"

Compose 要求容器由它创建(打标签),手动创建的容器无法被识别。

已安装的容器迁移Compose:

  • 停掉原容器

  • 删除原容器(数据卷保留)

  • 用 Compose 创建新容器(挂载原来的数据卷)

形象比喻

  • 如果Docker是"单个房间",那么Docker Compose就是"整栋房子的建筑图纸"
  • 如果Docker容器是"单个演员",那么Docker Compose就是"整部戏的导演脚本"
操作方式 命令示例 适用场景
Docker CLI docker run ... (执行多次) 单个容器,临时测试
Docker Compose docker compose up (执行一次) 微服务、完整应用栈、开发/生产环境

核心功能

Docker Compose 主要解决"多容器协作"的复杂性:

1. 一键启停整个应用栈:

不再需要依次手动启动数据库、缓存、后端、前端。一条命令 docker compose up -d 全部搞定。
2. 服务依赖管理:

可以定义"先启动数据库,等数据库就绪了,再启动后端服务"。
3. 内部网络自动互通:

自动创建一个专属网络,容器之间可以通过服务名直接互相访问(DNS 解析),无需暴露端口给宿主机。
4. 数据持久化统一配置:

统一管理数据卷(Volumes),确保数据库重启后数据不丢失。
5. 环境隔离与复用:

开发、测试、生产环境可以使用不同的配置文件(如 docker-compose.dev.yml, docker-compose.prod.yml)进行叠加,保证环境一致性。

局限性

单机限制 :Docker Compose 主要用于单节点 (单台服务器 )编排。如果需要跨多台服务器(集群)部署,通常需要结合 Docker SwarmKubernetes (K8s)

工作原理
**1. 解析 YAML:**Docker Compose 读取 docker-compose.yml 文件,解析其中定义的服务(Services)、网络(Networks)和数据卷(Volumes)。

2. 调用 Docker API: 它本质上是一个 Python/Go 编写的客户端,通过 Docker Daemon 的 API 发送指令。
3. 资源创建顺序:

  • 首先创建定义的 Networks(默认创建一个桥接网络)。
  • 其次创建定义的 Volumes(用于数据持久化)。
  • 最后按照依赖关系(depends_on)依次创建并启动 Containers。

**4. 服务发现:**在创建的网络中,Docker 内置的 DNS 服务器会将服务名解析为对应的容器 IP。例如,服务名为 db,其他容器 ping db 就能通。

实现方案架构

一个典型的 Compose 架构包含三个层级:

  • 定义层 (YAML):用户编写声明式配置。
  • 编排层 (Compose Engine):处理依赖逻辑、生命周期管理、日志聚合。
  • 执行层 (Docker Daemon):真正创建 Linux 命名空间、Cgroup、网络桥接和文件系统挂载。

常用命令速查表

|-------------------------------------------|------------------------------------|
| 命令 | 说明 |
| docker compose up -d | 后台启动所有服务 |
| docker compose up -d --build | 重新构建镜像并启动 (当 Dockerfile 变更时) |
| docker compose ps | 查看当前运行的服务状态 |
| docker compose logs -f [service_name] | 实时查看指定服务的日志 |
| docker compose exec [service_name] bash | 进入指定容器内部 (如 exec wordpress bash) |
| docker compose stop | 暂停服务 (不删除容器) |
| docker compose start | 启动已暂停的服务 |
| docker compose down | 停止并删除容器、网络 (保留数据卷) |
| docker compose down -v | 停止并删除容器、网络、数据卷 (数据清空) |
| docker compose top | 查看容器内的进程资源占用 |

Docker Compose安装(若未安装)

若服务器未安装Docker Compose,执行以下步骤安装(外网环境推荐方式1,内网环境推荐方式2)。

方式1:官方脚本安装(外网环境,推荐)

  1. 下载Docker Compose二进制文件(版本选用稳定版v2.24.5): curl -SL https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

  2. 添加执行权限: chmod +x /usr/local/bin/docker-compose

  3. 验证安装: docker-compose --version输出类似 docker-compose version v2.24.5, build 15d4f8c 即为安装成功。

方式2:离线安装(内网环境)

  1. 外网机器下载二进制文件:wget https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-x86_64

  2. 上传至服务器并命名: scp docker-compose-linux-x86_64 用户名@服务器IP:/usr/local/bin/docker-compose

  3. 添加执行权限并验证(同方式1步骤2、3)。

安装异常处理

  • 提示"curl: command not found":安装curl,CentOS执行 yum install -y curl,Ubuntu执行 apt install -y curl

  • 提示"command not found":建立软链接,执行 ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

核心配置:编写docker-compose.yml文件(MySQL+Redis+Jar联动)

docker-compose.yml是三者联动的核心,统一定义MySQL、Redis、Jar服务的启动参数、网络、挂载目录,确保启动顺序合理、连接正常,分两种配置场景(适配不同配置来源)。

场景1:数据库配置由Docker Compose管理(无Nacos或无需动态配置)

适合无Nacos配置中心,或数据库配置无需动态调整的场景,所有数据库连接参数由Compose注入,避免冲突。

  1. 创建统一配置目录(便于管理):

创建

mkdir -p /data/docker-compose/all-service

# 进入

cd /data/docker-compose/all-service

  1. 创建并编辑docker-compose.yml文件(vim编辑):

    version: '3.8' # 适配Docker 19.03+,可根据Docker版本调整
    services:

    1. MySQL服务(数据持久化,适配Jar服务连接)

    mysql:
    image: mysql:8.0 # 官方镜像,版本可替换为8.0+稳定版
    container_name: mysql-service # 如已存在容器,必须和原容器名一致
    restart: always # 开机自启,异常自动重启
    ports:
    - "3306:3306" # 端口映射,宿主机:容器(默认3306,可修改)
    volumes:
    - /data/mysql/data:/var/lib/mysql # 数据持久化,避免容器删除数据丢失
    - /data/mysql/conf:/etc/mysql/conf.d # 配置文件挂载(可自定义MySQL配置)
    - /data/mysql/log:/var/log/mysql # 日志挂载,便于排查问题
    environment:
    - MYSQL_ROOT_PASSWORD=123456 # MySQL root密码(自定义,需与Jar配置一致)
    - MYSQL_DATABASE=test_db # 初始化Jar服务所需数据库(自定义)
    - MYSQL_USER=jar_user # 给Jar服务分配的MySQL用户(可选,提升安全性)
    - MYSQL_PASSWORD=jar_pwd # Jar服务连接MySQL的密码(自定义)
    networks:
    - app-network # 统一网络,确保三者互通
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # 设置字符集,避免中文乱码

    2. Redis服务(数据持久化,适配Jar服务连接)

    redis:
    image: redis:6.2 # 官方镜像,版本可替换为6.2+稳定版
    container_name: redis-service
    restart: always
    ports:
    - "6379:6379" # 端口映射,默认6379
    volumes:
    - /data/redis/data:/data # 数据持久化(RDB/AOF模式)
    - /data/redis/conf:/etc/redis # 配置文件挂载(可自定义Redis配置)
    command: redis-server --requirepass 123456 --appendonly yes # 设密码+开启AOF持久化
    networks:
    - app-network

    3. Jar后端服务(联动MySQL、Redis)

    jar-app:
    image: my-jar-app:v1.0 # Jar服务镜像(若未打包,见4.3)
    container_name: jar-service
    restart: always
    ports:
    - "8080:8080" # Jar服务端口(自定义,与现有一致)
    volumes:
    - /data/jar/log:/app/log # Jar日志挂载
    - /data/jar/config:/app/config # Jar配置文件挂载(若有)
    environment:
    - JAVA_OPTS="-Xms512m -Xmx1024m" # JVM参数,根据服务器配置调整
    - SPRING_PROFILES_ACTIVE=prod # 多环境配置(prod/test,根据实际修改)
    # MySQL连接参数(与上方MySQL配置一致)
    - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    - SPRING_DATASOURCE_USERNAME=jar_user
    - SPRING_DATASOURCE_PASSWORD=jar_pwd
    # Redis连接参数(与上方Redis配置一致)
    - SPRING_REDIS_HOST=redis
    - SPRING_REDIS_PORT=6379
    - SPRING_REDIS_PASSWORD=123456
    depends_on: # 关键:确保MySQL、Redis先启动,再启动Jar服务
    - mysql
    - redis
    networks:
    - app-network

    统一自定义网络:确保MySQL、Redis、Jar服务互通,避免网络冲突

    networks:
    app-network:
    driver: bridge

场景2:数据库配置由Nacos管理(推荐,已有Nacos场景)

适合已有Nacos配置中心,数据库参数需动态调整的场景,删除Compose中Jar服务的数据库配置,避免与Nacos冲突(优先级参考第九章)。

复制代码
version: '3.8'
services:
  # 1. MySQL服务(配置不变)
  mysql:
    image: mysql:8.0
    container_name: mysql-service   # 如已存在容器,必须和原容器名一致
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - /data/mysql/data:/var/lib/mysql
      - /data/mysql/conf:/etc/mysql/conf.d
      - /data/mysql/log:/var/log/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=test_db
      - MYSQL_USER=jar_user
      - MYSQL_PASSWORD=jar_pwd
    networks:
      - app-network
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

  # 2. Redis服务(配置不变)
  redis:
    image: redis:6.2
    container_name: redis-service
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - /data/redis/data:/data
      - /data/redis/conf:/etc/redis
    command: redis-server --requirepass 123456 --appendonly yes
    networks:
      - app-network

  # 3. Jar后端服务(删除数据库相关配置,由Nacos提供)
  jar-app:
    image: my-jar-app:v1.0
    container_name: jar-service
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - /data/jar/log:/app/log
      - /data/jar/config:/app/config
    environment:
      - JAVA_OPTS="-Xms512m -Xmx1024m"
      - SPRING_PROFILES_ACTIVE=prod
      - SPRING_CLOUD_NACOS_CONFIG_SERVER-ADDR=192.168.1.100:8848  # Nacos地址(自定义)
      - SPRING_CLOUD_NACOS_CONFIG_NAMESPACE=public  # Nacos命名空间(自定义)
    depends_on:
      - mysql
      - redis
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

说明:需确保Nacos中已配置MySQL、Redis连接参数,且参数与Compose中MySQL、Redis的配置一致(如数据库地址写mysql服务名、Redis地址写redis服务名)。

补充:Jar服务未打包为Docker镜像的处理

若Jar服务未打包为镜像,需在配置目录下创建Dockerfile,先构建镜像,步骤如下:

  1. 在 /data/docker-compose/all-service 目录下创建Dockerfile:

    基础镜像(选择与Jar兼容的JDK版本,如JDK11)

    FROM openjdk:11-jre-slim

    工作目录

    WORKDIR /app

    复制Jar文件到容器(Jar文件名根据实际修改,如app.jar)

    COPY app.jar /app/app.jar

    暴露Jar服务端口(与docker-compose.yml中一致)

    EXPOSE 8080

    启动命令(与宿主机启动命令一致,若有Nacos,无需修改)

    ENTRYPOINT ["java", "-jar", "/app/app.jar", "--spring.profiles.active=prod"]

  2. 将Jar文件(如app.jar)上传至该目录,执行构建命令:

    docker build -t my-jar-app:v1.0 .
    构建成功后,执行
    docker images
    可看到 my-jar-app:v1.0 镜像,即可用于上述docker-compose.yml配置。

配置文件检查(必做)

配置文件编写完成后,检查语法是否正确,避免启动失败:

复制代码
cd /data/docker-compose/all-service
docker-compose config

若输出配置内容且无报错,说明语法正确;若有报错,根据提示修改(如缩进错误、参数遗漏、端口冲突)。

部署实施(一键启动,平滑联动)

部署步骤严格按顺序执行,重点确保MySQL、Redis先启动,Jar服务正常联动,避免业务中断(建议选择低峰期操作)。

提前创建挂载目录并授权

为避免权限不足导致服务启动失败,提前创建挂载目录并赋予读写权限:

复制代码
# 创建MySQL、Redis、Jar挂载目录
mkdir -p /data/mysql/data /data/mysql/conf /data/mysql/log
mkdir -p /data/redis/data /data/redis/conf
mkdir -p /data/jar/log /data/jar/config

# 赋予目录读写权限(避免启动失败)
chmod -R 777 /data/mysql /data/redis /data/jar

一键启动所有服务

  1. 进入配置文件目录: cd /data/docker-compose/all-service

  2. 后台启动服务(推荐,不占用终端): docker-compose up -d说明:-d 表示后台运行,启动过程约1-3分钟(取决于服务器性能)。

  3. 查看服务启动状态:docker-compose ps若三个服务(mysql-service、redis-service、jar-service)的State均为"Up",说明启动成功;若为"Exit",执行 docker-compose logs 服务名称排查错误(如 docker-compose logs mysql-service)。

验证三者联动可用性(关键步骤)

启动成功后,需验证Jar服务能正常连接MySQL、Redis,确保服务可正常提供业务。

  1. 端口验证:检查三个服务的端口是否正常监听:

    MySQL端口

    netstat -an | grep 3306

    Redis端口

    netstat -an | grep 6379

    Jar服务端口若均显示"LISTEN",说明端口正常。

    netstat -an | grep 8080

  2. MySQL连接验证(进入Jar容器验证):

    进入Jar服务容器

    docker exec -it jar-service /bin/bash

    安装MySQL客户端(若容器内无)

    apt install -y mysql-client # Ubuntu镜像

    或 yum install -y mysql # CentOS镜像

    连接MySQL(参数与Compose配置一致)

    mysql -h mysql -u jar_user -pjar_pwd若能成功进入MySQL命令行,说明Jar服务能正常连接MySQL。

  3. Redis连接验证(进入Jar容器验证):

    进入Jar服务容器

    docker exec -it jar-service /bin/bash

    安装Redis客户端(若容器内无)

    apt install -y redis-tools # Ubuntu镜像

    连接Redis(参数与Compose配置一致)

    redis-cli -h redis -p 6379 -a 123456

    测试Redis连接(输入ping,返回PONG即为正常)

    ping

  4. Jar服务接口验证:

    访问Jar服务健康检查接口(若有SpringBoot Actuator)

    curl http://localhost:8080/actuator/health若返回 {"status":"UP"},说明Jar服务正常运行,且已成功联动MySQL、Redis。

后续配置(优化与维护)

设置Docker Compose开机自启

为避免服务器重启后服务无法自动启动,通过systemctl设置开机自启(推荐):

创建系统服务文件:

vim /etc/systemd/system/docker-compose-all.service

写入以下内容(修改路径为实际配置目录):

复制代码
[Unit]
Description=Docker Compose MySQL+Redis+Jar Service
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/docker-compose -f /data/docker-compose/all-service/docker-compose.yml up -d
ExecStop=/usr/local/bin/docker-compose -f /data/docker-compose/all-service/docker-compose.yml down
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

启用并启动服务:

复制代码
systemctl daemon-reload
systemctl enable docker-compose-all  # 开机自启
systemctl start docker-compose-all  # 启动服务
systemctl status docker-compose-all  # 查看状态

日常维护常用命令

进入配置目录(cd /data/docker-compose/all-service)后,执行以下命令管理服务:

复制代码
# 1. 启动所有服务(后台)
docker-compose up -d

# 2. 停止所有服务(停止并删除容器)
docker-compose down

# 3. 停止所有服务(仅停止,不删除容器)
docker-compose stop

# 4. 重启所有服务
docker-compose restart

# 5. 查看单个服务日志(如Jar服务,实时日志)
docker-compose logs -f jar-service

# 6. 查看单个服务详情(如MySQL)
docker-compose inspect mysql-service

# 7. 更新服务(修改配置文件后,强制重建容器)
docker-compose up -d --force-recreate

# 8. 查看容器占用资源
docker-compose top

数据与日志维护

  • 数据备份:定期备份MySQL、Redis挂载目录(数据持久化目录),避免数据丢失:

    复制代码
    # 备份MySQL数据
    cp -r /data/mysql/data /data/mysql/data_backup_$(date +%Y%m%d)
    # 备份Redis数据
    cp -r /data/redis/data /data/redis/data_backup_$(date +%Y%m%d)
  • 日志清理:定期清理MySQL、Redis、Jar服务的日志,避免磁盘占满,可设置定时任务:

    复制代码
    crontab -e
    # 新增:每月1号清理30天前的日志
    0 0 1 * * find /data/mysql/log /data/redis/data /data/jar/log -name "*.log" -mtime +30 -delete

常见问题排查(MySQL+Redis+Jar联动专属)

  • 问题1:Jar服务启动失败,日志提示"Could not connect to MySQL" 解决:① 检查MySQL服务是否正常启动(docker-compose ps mysql-service);② 确认Jar服务environment中的MySQL参数(地址、账号、密码)与Compose中MySQL配置一致;③ 检查网络是否互通(进入Jar容器,执行 ping mysql,能ping通即为正常)。

  • 问题2:Jar服务启动失败,日志提示"Could not connect to Redis" 解决:① 检查Redis服务是否正常启动;② 确认Jar服务中Redis密码、端口与Compose配置一致;③ 进入Jar容器,执行 ping redis 验证网络互通。

  • 问题3:MySQL启动失败,日志提示"权限不足" 解决:重新赋予MySQL挂载目录权限,执行chmod -R 777 /data/mysql,然后重启服务 docker-compose restart mysql-service

  • 问题4:Jar服务能启动,但无法访问接口 解决:① 检查防火墙是否开放Jar服务端口(firewall-cmd --add-port=8080/tcp --permanent,再 firewall-cmd --reload);② 检查Jar服务日志,排查业务代码错误;③ 确认Jar服务与MySQL、Redis联动正常。

  • 问题5:重启服务器后,服务未自动启动 解决:① 检查Docker是否开机自启(systemctl is-enabled docker);② 检查docker-compose-all服务是否正常(systemctl status docker-compose-all);③ 重新启用开机自启 systemctl enable docker-compose-all

补充:Compose与Nacos配置冲突解决方案

若使用Nacos管理数据库配置,需重点注意以下两点,避免冲突:

  1. 优先级规则:Compose environment配置 > Nacos配置 > Jar本地配置,若两者均配置数据库参数,Nacos配置会被覆盖。

  2. 规避冲突:

    1. 方案1(推荐):删除Compose中Jar服务的所有数据库、Redis相关配置,统一由Nacos提供。

    2. 方案2:删除Nacos中数据库、Redis相关配置,统一由Compose environment注入。

    3. 注意:Nacos中配置的MySQL地址需写 mysql(Compose中MySQL服务名),Redis地址需写 redis(Compose中Redis服务名),避免连接失败。

相关推荐
释怀不想释怀2 小时前
安装Docker(Centos)
docker·eureka·centos
Mr成文2 小时前
【Linux/Ubuntu】OpenCode +Oh My OpenAgent安装配置实践
linux·运维·ubuntu
yhole2 小时前
Nginx解决前端跨域问题
运维·前端·nginx
小白学鸿蒙2 小时前
服务器可视化部署静态网站或者搭建博客论坛-小白版
运维·服务器
何中应2 小时前
Grafana展示服务器数据
运维·服务器·grafana
搬砖魁首2 小时前
Fabric系列 - HSM之2 容器化
docker·fabric·hsm·bccsp·pkcs11
难搞哦~2 小时前
绿联NAS一键部署SQMusic免费下载无损音质(FLAC/APE)+高码率MP3(320kbps)音乐,搭建个人高品质音乐库
docker·nas·绿联nas·sqmusic
竹之却2 小时前
【Linux】Linux 中 .service 文件核心介绍
linux·运维·服务器·systemd·.service 文件
全栈攻略2 小时前
老版本Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12)
macos·docker·容器