DockerCompose详解(DockerCompose简介、docker-compose.yml文件的基本结构、常用的DockerCompose命令、docker-compose.yml文件示例)


更多 Docker 的使用技巧可以查看 Docker 专栏: Docker

1. DockerCompose简介

1.1 DockerCompose是什么

DockerCompose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用 YAML 文件来配置应用程序的服务,这些服务可以是运行在 Docker 容器中的单个服务,也可以是由多个容器组成的服务

DockerCompose 允许用户通过一个简单的命令来启动、停止和重建应用程序中的所有服务

1.2 DockerCompose的作用

Docker 容器本身只是一个特殊进程,如果我们想部署多个容器,而且对这些容器的执行顺序有一定的要求呢?

在这里插入图片描述

例如一个博客系统,需要先启动数据库容器,接着启动身份验证容器,最后启动博客 Web 服务容器。当然,挨个执行 docker run 指令是没问题的,那有没有更优雅的解决方案呢?


没错,DockerCompose 正是为了解决多容器的编排问题。我们只需要在一个 yaml 文件中写清楚要部署哪些容器,容器的部署顺序,最后执行 docker-compose up 命令,就能一键部署多个容器了

在这里插入图片描述

2. docker-compose.yml文件的基本结构

2.1 版本(version)

在新版本的docker-compose 中,version 属性已经被标为启用(version is obsolete)

version: "3.8"  # 指定docker-compose文件的版本

2.2 服务(services)

services:  # 定义所有服务的配置
  # 自定义服务名称,例如 web
  web:
    image: nginx:1.26.2  # 指定服务的镜像
    ports:
      - "80:80"  # 将容器的端口映射到宿主机
    volumes:
      - ./html:/usr/share/nginx/html  # 将宿主机的目录挂载到容器中
    networks:
      - webnet  # 将服务连接到指定的网络

  # 另一个服务,例如 db
  db:
    image: postgres:latest  # 指定服务的镜像
    environment:
      POSTGRES_DB: mydb  # 设置环境变量
      POSTGRES_USER: user
      POSTGRES_PASSWORD: example
    volumes:
      - db_data:/var/lib/postgresql/data  # 使用命名卷持久化数据
    networks:
      - webnet

2.2.1 image

docker-compose.yml 文件中,image 关键字用于指定要启动的容器的镜像

services:
  web:         # 定义一个服务,名称为 web
    image: nginx:1.27.3  # 指定该服务使用的 Docker 镜像为 1.27.3 版本的 nginx
    ports:
      - "80:80"  # 将容器的 80 端口映射到宿主机的 80 端口

2.2.2 build

docker-compose.yml 文件中,build 关键字用于指定 Docker Compose 应该通过一个 Dockerfile 构建服务的镜像,而不是直接使用一个已经存在的镜像

services:
  webapp:
    build:
      context: ./path/to/build/directory
      dockerfile: Dockerfile-alternate
      image: mycustomimage:1.0.0
    ports:
      - "5000:5000"

在这个例子中:

  • build 指定了 Docker Compose 应该使用 Dockerfile 来构建服务的镜像
  • context 是 Dockerfile 所在的路径,默认是 docker-compose.yml 文件所在的目录
  • dockerfile(可选)指定了要使用的 Dockerfile 文件名。如果不指定,Docker Compose 默认会查找名为 Dockerfile 的文件
  • image 指定了构建后镜像的名称和标签。如果不指定 image,Docker Compose 会为构建的镜像生成一个默认名称,通常是 <projectname>_<servicename>

2.2.3 container_name

默认情况下,如果没有为启动的容器指定名称,Docker Compose 会自动为每个容器生成一个唯一的名称,格式通常是 <projectname>_<servicename>_<num>

  • <projectname> 是 Docker Compose 项目名称(默认是当前目录名)
  • <servicename> 是在 docker-compose.yml 文件中定义的服务名称
  • <num> 是一个序号,用于区分同一服务启动的多个实例

docker-compose.yml 文件中,container_name 关键字用于为启动的容器指定一个自定义名称

services:
  web:
    image: nginx:1.27.3
    container_name: my_custom_nginx
    ports:
      - "80:80"

关于 container_name 的注意事项:

  • 如果指定了 container_name,则不能在同一个 Docker Compose 项目中启动该服务的多个实例,因为容器名称必须是唯一的
  • 使用 container_name 会使你的 Docker Compose 项目不那么可移植,因为如果其他人在相同的主机上运行相同的项目,可能会遇到容器名称冲突的问题
  • 使用 container_name 时要小心,并确保它适用于你的特定场景。在大多数情况下,让 Docker Compose 自动生成容器名称是更好的做法

2.2.4 restart

docker-compose.yml 文件中,restart 配置选项用于指定容器重启的策略。当容器退出时,Docker Compose 会根据这个策略决定是否重启容器。以下是 restart 的一些常见值:

  • no: 是默认值,表示容器退出后不会自动重启
  • always: 无论容器退出状态如何,总是重启容器
  • on-failure: 只有当容器以非0状态码退出时才重启容器。可以指定重启的次数
  • unless-stopped: 只有当容器被手动停止时才不会重启,否则总是重启容器
services:
  web:
    image: nginx:1.27.3
    ports:
      - "80:80"
    restart: always

在这个例子中,无论 Nginx 容器何时退出,它都会被 Docker Compose 自动重启


如果你想要容器在失败时尝试重启,但不超过一定的次数,可以这样配置:

services:
  web:
    image: nginx:1.27.3
    ports:
      - "80:80"
    restart: on-failure:10

在这个例子中,如果 Nginx 容器以非0状态码退出,Docker Compose 将尝试重启它,但最多不超过10次

2.2.5 ports

docker-compose.yml 文件中,ports 关键字用于配置容器与宿主机之间的端口映射

services:
  web:
    image: nginx:1.27.3
    ports:
      - "80:80"  # 将宿主机的80端口映射到容器的80端口

2.2.6 depends_on

  • 需要注意的是,depends_on 只确保依赖的服务在当前服务之前启动,而不会等待依赖的服务“就绪”才启动当前服务
  • 这意味着,即使依赖的服务已经启动,它们可能还没有完全准备好接受连接或处理请求

depends_ondocker-compose.yml 文件中的一个指令,用于指定服务之间的依赖关系

当定义一个服务时,可以使用 depends_on 来告诉 Compose 某一个服务应该在哪一个启动之后再启动

services:
  app:
    image: myapp:latest
    depends_on:
      - db
    networks:
      - mynetwork

  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    networks:
      - mynetwork

networks:
  mynetwork:

2.2.7 environment&env_file

docker-compose.yml 文件中,environment 关键字用于定义服务运行时的环境变量。这些环境变量可以在容器内部被应用程序读取,以影响其行为

2.2.7.1 使用列表形式
services:
  web:  # 定义一个服务名称为 web
    image: nginx:1.27.3  # 指定服务使用的镜像
    environment:  # 定义环境变量
      - NGINX_HOST=example.com  # 设置单个环境变量
      - NGINX_PORT=8080  # 设置另一个环境变量
      - DEBUG=true  # 设置布尔值环境变量
2.2.7.2 使用字面量字典形式
services:
  web:
    image: nginx:1.27.3
    environment:
      NGINX_HOST: example.com
      NGINX_PORT: "8080"
      DEBUG: "true"
2.2.7.3 使用环境文件(env_file)

如果你有大量的环境变量,可以将它们放在一个环境变量文件中,并在 docker-compose.yml 中引用该文件:

services:
  web:
    image: nginx:1.27.3
    env_file:
      - web.env  # 引用名为 web.env 的环境变量文件

web.env 文件的内容如下:

NGINX_HOST=example.com
NGINX_PORT=8080
DEBUG=true
2.2.7.4 结合使用 environment 和 env_file

可以同时使用 environmentenv_file 来设置环境变量,其中 environment 中的变量会覆盖 env_file 中的同名变量

services:
  web:
    image: nginx:latest
    environment:
      - DEBUG=true
    env_file:
      - web.env

在这个例子中,如果 web.env 文件中也定义了 DEBUG 变量,那么 environment 中的 DEBUG 变量将覆盖它

2.3 网络(networks)

如果不需要为网络指定任何特殊配置,可以简单地列出网络名称,网络将会使用默认的 bridge 驱动

网络(networks)部分是 docker-compose.yml 文件的可选配置项之一,它允许你定义和配置自定义网络,这些网络可以被你的服务(services)使用

networks:
  - some-network
  - another-network

在服务定义中,可以通过 networks 选项指定服务应该连接到哪些网络

services:
  web:
    image: nginx:1.27.3
    networks:
      - some-network
      - another-network

2.4 数据卷(volumes)

docker-compose.yml 文件中,volumes 部分用于定义 Docker 数据卷,这些数据卷可以用于持久化容器中的数据

volumes:
  web-data:
  logs:

在服务定义中,可以通过 volumes 选项指定服务哪个目录需要挂载哪个数据卷

services:
  web:
    image: nginx:1.27.3
    volumes:
      - web-data:/var/www/html
      - logs:/var/log/nginx

3. 常用的DockerCompose命令

3.1 启动服务(docker-compose up)

docker-compose up
  • 启动所有定义在 docker-compose.yml 文件中的服务
  • 默认情况下,该命令会在前台运行,并显示日志输出

后台运行:如果你想让服务在后台运行,可以加上 -d 参数:

docker-compose up -d

3.2 停止服务(docker-compose down)

docker-compose down

停止并移除所有由 docker-compose up 启动的容器

3.3 查看正在运行的服务(docker-compose ps)

docker-compose ps

列出所有由 docker-compose 管理的容器及其状态

3.4 查看日志(docker-compose logs)

docker-compose logs

查看所有服务的日志输出


如果只想查看某个特定服务的日志,可以指定服务名称:

docker-compose logs <service_name>

实时查看日志:使用 -f 参数可以实时跟踪日志输出:

docker-compose logs -f

3.5 停止正在运行的容器(docker-compose stop)

docker-compose stop

停止正在运行的容器,但不会删除它们。可以使用 docker-compose start 再次启动这些容器


如果想停止某个特定服务,可以指定服务名称:

 docker-compose stop <service_name>

3.6 启动已经停止的容器(docker-compose start)

启动已经停止的容器

docker-compose start

如果想启动某个特定服务,可以指定服务名称:

docker-compose start <service_name>

3.7 重启服务(docker-compose restart)

重启所有服务

docker-compose restart

如果你想重启某个特定服务,可以指定服务名称:

docker-compose restart <service_name>

3.8 列出所有服务(docker-compose images)

列出所有由 docker-compose 管理的镜像

docker-compose images

4. 完整的docker-compose.yml示例

基于 WordPress 和 MySQL 搭建一个博客系统

4.1 编写docker-compose.yml文件

services:
  # WordPress 服务
  wordpress-6.7.2:
    image: wordpress:6.7.2
    container_name: wordpress-6.7.2
    restart: always
    ports:
      - "9090:80"  # 将主机的 9090 端口映射到容器的 80 端口
    environment:
      WORDPRESS_DB_HOST: mysql-8.0.32:3306  # 数据库主机地址(使用服务名)
      WORDPRESS_DB_USER: wp_user        # 数据库用户名
      WORDPRESS_DB_PASSWORD: wp_password # 数据库密码
      WORDPRESS_DB_NAME: wp_database    # 数据库名称
    volumes:
      - wordpress_data:/var/www/html    # 挂载 WordPress 的数据目录
    networks:
      - wordpress_network                # 加入自定义网络
    depends_on:                          # 确保 MySQL 先启动
      - mysql-8.0.32

  # MySQL 数据库服务
  mysql-8.0.32:
    image: mysql:8.0.32                     # 使用 MySQL 8.0.32 版本
    container_name: mysql-8.0.32
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_password # MySQL root 用户密码
      MYSQL_DATABASE: wp_database        # 创建的数据库名称
      MYSQL_USER: wp_user                # 创建的数据库用户
      MYSQL_PASSWORD: wp_password        # 数据库用户的密码
    volumes:
      - mysql_data:/var/lib/mysql         # 挂载 MySQL 数据目录
    networks:
      - wordpress_network                 # 加入自定义网络

# 定义卷
volumes:
  wordpress_data:                         # 用于存储 WordPress 的数据
  mysql_data:                             # 用于存储 MySQL 的数据

# 定义网络
networks:
  wordpress_network:                      # 自定义网络,用于连接 WordPress 和 MySQL
    driver: bridge                        # 使用桥接网络

4.2 启动服务

wordpress镜像和mysql镜像较大,下载耗时可能较长

docker-compose up -d

在这里插入图片描述

4.3 开放防火墙的 9090 端口

  • 如果你使用的是云服务器,请在安全组中放行 9090 端口
  • 如果你安装了宝塔,除了在安全组中放行 9090 端口,可能还要在宝塔中放行 9090 端口

4.4 访问博客系统

不得不说,WordPress 不仅界面丑,而且用起来也很不顺手

在浏览器输入以下地址,就可以访问博客系统了(记得更改 IP 地址)

http://127.0.0.1:9090

在这里插入图片描述

填写完一些必要的信息后点击安装WordPress(默认界面是英文的,可以使用浏览器的翻译功能)

在这里插入图片描述

最后点击Log in

在这里插入图片描述

输入刚才填写的用户名和密码

在这里插入图片描述

看到以下界面,就说明成功了

在这里插入图片描述

4.4.1 修改默认语言

界面默认是英文的,我们可以改成中文

在这里插入图片描述

选择完语言后,点击保存配置,页面就会变成中文了

在这里插入图片描述

4.4.2 修改时区

在设置的常规项中找到时区

在这里插入图片描述

选择上海

在这里插入图片描述

最后点击保存更改

在这里插入图片描述