☰
docker:docker-compose是什么怎么用?
2026/10/10 1:15:08 网站建设 项目流程

一、什么是 Docker Compose

Docker Compose 是 Docker 官方提供的容器编排工具,用于通过一个 YAML 配置文件定义和管理多个容器。

在实际开发中,一个应用往往不只有一个服务。例如,一个典型的后端项目可能包含:

  • Spring Boot:后端应用
  • MySQL:关系型数据库
  • Redis:缓存服务
  • Nginx:反向代理

如果使用 Docker 单独管理这些服务,需要分别创建容器、配置网络、挂载数据卷以及设置启动顺序。服务越多,管理成本越高。

Docker Compose 可以将这些配置统一写入compose.yaml文件,通过一条命令启动整个应用。

dockercompose up-d

核心价值:使用声明式配置管理多个容器,让应用环境更容易部署、迁移和维护。

注意:Docker Compose 主要用于单机多容器管理,并不是 Kubernetes 这类面向集群的容器编排平台。

二、Docker Compose 的核心概念

Docker Compose 配置文件主要由以下几个部分组成。

配置项作用
services定义应用包含哪些服务及其运行配置
image指定使用的镜像
build根据 Dockerfile 构建镜像
ports配置宿主机与容器之间的端口映射
volumes挂载数据卷或宿主机目录
environment设置容器环境变量
networks配置容器网络
depends_on定义服务之间的启动依赖
restart配置容器退出后的重启策略

其中,services是最核心的配置项。每个 service 通常对应一个应用服务,并由一个或多个容器实例运行。

例如:

services:app:image:nginx:alpineports:-"8080:80"redis:image:redis:7-alpine

这份配置定义了两个服务:Nginx 和 Redis。

三、安装与版本说明

Docker Compose 目前主要使用 Compose V2,通过 Docker CLI 插件的形式运行。

安装 Docker Engine 后,可以执行以下命令检查是否可用:

docker--versiondockercompose version

如果第二条命令能够正常输出版本信息,说明 Docker Compose 已经可以使用。

需要注意,现代 Compose 文件通常使用compose.yaml或compose.yml,也兼容常见的docker-compose.yaml文件名。

以前经常使用的独立命令是:

docker-composeup-d

现代版本推荐使用:

dockercompose up-d

两者属于不同的命令形式,实际支持情况取决于安装的版本。

四、编写第一个 Docker Compose 配置

下面通过一个 Nginx 示例,演示如何使用 Docker Compose 启动服务。

创建项目目录:

mkdircompose-democdcompose-demo

创建compose.yaml文件:

services:nginx:image:nginx:alpinecontainer_name:demo-nginxports:-"8080:80"restart:unless-stopped

配置说明:

  • services:定义服务集合。
  • nginx:服务名称,可以自定义。
  • image:指定使用 Nginx Alpine 镜像。
  • container_name:指定固定的容器名称。
  • ports:将宿主机的 8080 端口映射到容器的 80 端口。
  • restart:除非手动停止容器,否则在符合重启策略的情况下自动重启。

启动服务:

dockercompose up-d

浏览器访问:

http://localhost:8080

如果看到 Nginx 欢迎页面,说明部署成功。

查看运行状态:

dockercomposeps

停止并删除 Compose 创建的容器和网络:

dockercompose down

注意,down默认不会删除命名数据卷,因此通常不会直接清除保存在命名卷中的数据库数据。

五、Docker Compose 常用命令

这是日常开发和运维中最常用的一组命令。

1. 启动服务

# 启动服务并在前台输出日志dockercompose up# 后台启动服务dockercompose up-d# 重新构建镜像后启动dockercompose up-d--build

up会根据配置创建或更新所需的容器、网络等资源。

2. 查看服务状态

# 查看当前项目的容器dockercomposeps# 查看镜像dockercompose images# 查看服务日志dockercompose logs# 持续跟踪日志dockercompose logs-f# 查看指定服务日志dockercompose logs-fapp

如果需要排查启动失败的问题,通常先执行docker compose ps,再查看对应服务的日志。

3. 停止和启动服务

# 停止服务容器,但保留容器dockercompose stop# 重新启动已停止的容器dockercompose start# 重启服务dockercompose restart

这些命令适用于临时停止、恢复或重启服务。

4. 删除服务

# 停止并删除容器、Compose 管理的网络dockercompose down# 删除容器前,同时删除由该项目创建的匿名卷dockercompose down-v

使用-v时需要格外谨慎。它可能删除数据库等服务使用的数据卷,导致数据丢失。删除前应确认数据是否需要保留。

5. 进入容器执行命令

# 进入 app 容器执行 Shelldockercomposeexecappsh# 如果容器安装了 Bashdockercomposeexecappbash# 执行一次性命令dockercomposeexecappls-l

exec适用于进入正在运行的容器排查问题。如果容器已经退出,则不能直接通过exec进入。

6. 其他实用命令

# 查看最终生效的 Compose 配置dockercompose config# 拉取镜像dockercompose pull# 构建镜像dockercompose build# 查看服务进程dockercomposetop

其中,docker compose config尤其适合检查 YAML 格式、变量替换以及最终配置结果。

六、实战:部署 Spring Boot + MySQL + Redis

下面使用一个常见的后端项目作为示例,演示如何将应用、数据库和缓存统一管理。

项目结构:

my-project/ ├── compose.yaml ├── Dockerfile └── app.jar

假设已经将 Spring Boot 项目打包为app.jar。

1. 编写 Dockerfile

FROM eclipse-temurin:21-jre WORKDIR /app COPY app.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]

这里使用 Java 21 运行环境。实际项目应根据应用使用的 Java 版本选择合适的镜像。

2. 编写 compose.yaml

services:app:build:.ports:-"8080:8080"environment:SPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/demoSPRING_DATASOURCE_USERNAME:demoSPRING_DATASOURCE_PASSWORD:${DB_PASSWORD:?请设置DB_PASSWORD}SPRING_DATA_REDIS_HOST:redisSPRING_DATA_REDIS_PORT:6379depends_on:mysql:condition:service_healthyredis:condition:service_healthyrestart:unless-stoppedmysql:image:mysql:8.4environment:MYSQL_DATABASE:demoMYSQL_USER:demoMYSQL_PASSWORD:${DB_PASSWORD:?请设置DB_PASSWORD}MYSQL_ROOT_PASSWORD:${MYSQL_ROOT_PASSWORD:?请设置MYSQL_ROOT_PASSWORD}volumes:-mysql-data:/var/lib/mysqlhealthcheck:test:["CMD","mysqladmin","ping","-h","127.0.0.1","--silent"]interval:10stimeout:5sretries:10start_period:30srestart:unless-stoppedredis:image:redis:7-alpinehealthcheck:test:["CMD","redis-cli","ping"]interval:5stimeout:3sretries:10restart:unless-stoppedvolumes:mysql-data:

3. 理解关键配置

服务之间如何通信?

Compose 默认会为项目创建网络。同一个网络中的服务可以通过服务名相互访问。

例如:

Spring Boot → mysql:3306 Spring Boot → redis:6379

这里的mysql和redis是服务名,不需要填写容器 IP 地址。

为什么 MySQL 不需要配置 ports?

示例中没有将 MySQL 端口暴露到宿主机,因为应用可以直接通过 Compose 内部网络访问数据库。

如果确实需要在宿主机上使用数据库客户端连接,可以增加:

ports:-"127.0.0.1:3307:3306"

此时宿主机可以通过127.0.0.1:3307连接 MySQL,而其他 Compose 服务仍通过mysql:3306访问。将端口绑定到回环地址有助于避免直接向外部网络开放数据库。

为什么使用 healthcheck?

容器启动不代表服务已经可以正常处理请求。MySQL 可能需要时间初始化,Redis 也可能尚未准备就绪。

healthcheck用于检测服务的健康状态,而:

depends_on:mysql:condition:service_healthy

表示等待 MySQL 的健康检查通过后,再启动依赖它的应用。

需要注意,这只能解决启动阶段的依赖问题。应用运行期间仍应具备连接重试、异常处理和数据库断线恢复机制。

为什么使用命名数据卷?

volumes:-mysql-data:/var/lib/mysql

MySQL 数据存放在 Docker 管理的命名卷中,而不是仅依赖容器可写层。

删除容器后,数据卷通常仍然保留,便于重新创建容器时继续使用原有数据。

4. 启动项目

先设置环境变量:

exportDB_PASSWORD='替换为安全的数据库密码'exportMYSQL_ROOT_PASSWORD='替换为安全的root密码'

然后执行:

dockercompose up-d--build

查看启动状态:

dockercomposeps

查看应用日志:

dockercompose logs-fapp

如果需要停止项目:

dockercompose down

这条命令默认保留mysql-data,但它不是数据库备份方案。重要数据仍应定期备份。

生产环境中不应将真实密码提交到 Git 仓库。示例使用环境变量仅用于演示,实际部署还应结合密钥管理、访问控制和备份策略。

七、Docker Compose 中的网络机制

Docker Compose 默认会为项目创建一个专用网络,通常使用 bridge 网络驱动。

假设项目中有三个服务:

┌────────────────────────────┐ │ Compose Network │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ app │ │ mysql │ │ │ └─────────┘ └─────────┘ │ │ │ │ │ ▼ │ │ ┌─────────┐ │ │ │ redis │ │ │ └─────────┘ │ └────────────────────────────┘

在默认网络中,各服务可以通过服务名进行 DNS 解析。

需要特别区分两个概念:

  • 容器端口:服务在容器内部监听的端口。
  • 宿主机端口:通过ports映射后,宿主机对外提供访问的端口。

例如:

ports:-"8081:8080"

含义是:

宿主机 8081 → 容器 8080

其他同网络容器通常直接访问目标服务的容器端口,无须绕道宿主机映射端口。

如果需要将前端网络和数据库网络隔离,也可以自定义网络:

services:app:image:my-app:latestnetworks:-frontend-backendmysql:image:mysql:8.4networks:-backendnetworks:frontend:backend:

此时 MySQL 不在frontend网络中,只有连接到backend网络的服务才能通过该网络直接访问它。

八、Docker Compose 中的 Volume

Volume 用于持久化容器数据,是部署数据库等有状态服务时的重要机制。

常见的数据挂载方式有两种。

1. 命名卷

services:mysql:image:mysql:8.4volumes:-mysql-data:/var/lib/mysqlvolumes:mysql-data:

特点:

  • 由 Docker 管理实际存储位置。
  • 容器重建后可以继续使用数据。
  • 适合数据库等需要持久化的数据。

2. 绑定挂载

services:app:image:nginx:alpinevolumes:-./html:/usr/share/nginx/html:ro

将宿主机当前目录下的html映射到容器内的网站目录,并设置为只读。

特点:

  • 可以直接操作宿主机上的文件。
  • 适合开发时挂载源代码、配置文件或静态资源。
  • 需要注意宿主机路径、文件权限及目录结构。

两种方式不能简单地认为谁更好。数据库持久化通常适合命名卷,开发过程中的文件共享则经常使用绑定挂载。

九、环境变量与多环境配置

实际项目通常存在开发、测试、生产等多个环境。如果所有配置都直接写入一个 YAML 文件,维护起来会比较困难。

可以利用环境变量和不同的 Compose 配置文件进行管理。

例如,默认配置文件为:

compose.yaml

生产环境覆盖文件为:

compose.prod.yaml

启动生产环境:

dockercompose\-fcompose.yaml\-fcompose.prod.yaml\up-d

后面的配置文件会覆盖或合并前面的配置,具体结果取决于配置项的合并规则。

另外,Compose 默认可以读取项目目录中的.env文件,用于解析 YAML 中的变量表达式,例如:

services:app:image:my-app:${APP_VERSION:-latest}

对应的.env文件:

APP_VERSION=1.0.0

这里的.env主要用于 Compose 配置中的变量替换。它与服务内部的environment、env_file并不是同一个概念:

  • .env:为 Compose 配置提供变量值。
  • environment:显式设置容器内部的环境变量。
  • env_file:从指定文件读取环境变量并传递给容器。

这三者可以配合使用,但要注意配置优先级和敏感信息保护。

十、Docker Compose 的常见问题

1. 修改 compose.yaml 后,为什么服务没有变化?

修改配置文件不意味着所有正在运行的容器都会自动更新。

可以执行:

dockercompose up-d

如果修改了 Dockerfile 或应用构建内容,则可以执行:

dockercompose up-d--build

如果应用使用外部镜像,也可以先拉取最新镜像:

dockercompose pulldockercompose up-d

注意,拉取新镜像不等于应用数据会自动迁移。涉及数据库结构变化时,仍应执行相应的迁移流程。

2. 为什么应用连接 MySQL 失败?

常见原因包括:

  • 数据库尚未完成初始化。
  • 数据库地址错误,误用了localhost。
  • 用户名、密码或数据库名称错误。
  • 服务没有连接到同一个 Docker 网络。
  • 数据库健康检查失败。

在容器内部,localhost指的是当前容器本身,而不是宿主机或另一个容器。

因此,Spring Boot 容器连接 Compose 中的 MySQL 时,通常应使用:

jdbc:mysql://mysql:3306/demo

而不是:

jdbc:mysql://localhost:3306/demo

3. 为什么删除容器后数据还在?

因为命名卷的生命周期通常独立于容器。

执行:

dockercompose down

不会默认删除命名卷。

如果确实需要删除项目使用的命名卷,可以执行:

dockercompose down-v

这可能导致数据库数据永久丢失,因此执行前必须确认。

4. depends_on 为什么不能完全解决服务依赖问题?

简单的:

depends_on:-mysql

主要控制服务启动顺序,不保证 MySQL 已经可以接受连接。

对于支持健康检查的服务,可以使用:

depends_on:mysql:condition:service_healthy

但即使服务启动成功,网络波动、数据库重启等情况仍可能导致连接中断。应用本身应具备合理的重试和恢复机制。

十一、Docker Compose 的最佳实践

  1. 一个服务尽量只负责一个主要职责。例如,应用、数据库、缓存分别使用独立容器。
  2. 优先使用明确的镜像版本。避免在生产环境无意间拉取不兼容的新版本。
  3. 持久化重要数据。数据库使用命名卷或适当的持久化存储,并建立独立备份机制。
  4. 不要将敏感信息提交到代码仓库。使用安全的环境变量注入方式或专用密钥管理系统。
  5. 合理设置健康检查。区分容器启动、服务就绪和应用真正可用这几个状态。
  6. 控制端口暴露范围。数据库和缓存通常不需要直接暴露到公网。
  7. 使用日志进行问题排查。熟悉docker compose ps、logs、exec和config。
  8. 为生产环境做好资源和安全配置。根据需求配置资源限制、日志轮转、权限、网络隔离和备份恢复流程。
  9. 避免依赖固定容器 IP。优先通过服务名访问容器。
  10. 谨慎使用down -v。它可能删除重要的持久化数据。

十二、总结

Docker Compose 解决的是多容器应用的统一定义与生命周期管理问题。

通过一个 YAML 配置文件,可以集中描述应用服务、网络、数据卷、端口映射、环境变量和依赖关系,再通过简单命令完成启动、停止、更新和排查。

日常开发中,最值得优先掌握的内容包括:

  • 使用services定义多个容器。
  • 使用ports配置端口映射。
  • 使用volumes持久化数据。
  • 使用服务名实现容器间通信。
  • 使用depends_on和healthcheck管理启动依赖。
  • 使用docker compose up -d、logs、ps和down管理应用生命周期。

对于个人项目、开发测试环境以及中小型单机部署,Docker Compose 是一种简单且实用的方案。随着应用规模扩大、部署节点增加以及高可用需求提升,再根据实际需要考虑 Kubernetes 等更复杂的编排平台。

举例

version:'3'services:wordpress:image:wordpressports:-8080:80depends_on:-mysqlenvironment:WORDPRESS_DB_HOST:mysqlWORDPRESS_DB_PASSWORD:rootnetworks:-my-bridgemysql:image:mysql:5.7environment:MYSQL_ROOT_PASSWORD:rootMYSQL_DATABASE:wordpressvolumes:-mysql-data:/var/lib/mysqlnetworks:-my-bridgevolumes:mysql-data:networks:my-bridge:driver:bridge

安装

官网
mac 和 windows 安装 docker 的时候默认会安装,linux 没有,请安装上面官网的去安装。

1、编写 docker-compose.yml 文件,目前分为三个 verson,可以自行官网查看编写规则 官网
2、命令行管理 docker-compose(启动停止等),可以在这里查看相关 API 官网

常用命令

docker-compose --help你会看到很多命令

docker-compose up -d nginx 构建建启动nignx容器 docker-compose exec nginx bash 登录到nginx容器中 docker-compose down 删除所有nginx容器,镜像 docker-compose ps 显示所有容器 docker-compose restart nginx 重新启动nginx容器 docker-compose run --no-deps --rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器 docker-compose build nginx 构建镜像 。 docker-compose build --no-cache nginx 不带缓存的构建。 docker-compose logs nginx 查看nginx的日志 docker-compose logs -f nginx 查看nginx的实时日志 docker-compose config -q 验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。 docker-compose events --json nginx 以json的形式输出nginx的docker日志 docker-compose pause nginx 暂停nignx容器 docker-compose unpause nginx 恢复ningx容器 docker-compose rm nginx 删除容器(删除前必须关闭容器) docker-compose stop nginx 停止nignx容器 docker-compose start nginx 启动nignx容器

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询