使用 Docker Compose 构建及部署多容器应用

内容纲要

查看【Docker & Kubernetes】专题可浏览更多内容

Docker Compose 是一个用于在 Docker 上运行多容器应用程序的工具,使用 Compose 文件格式定义。Compose 文件用于定义组成应用程序的一个或多个容器的配置方式。一旦有了 Compose 文件就可以使用一个单一的命令 docker compose up 创建并启动应用程序。

以下是 Docker Compose 的一些主要优势:

  • 通过提供隔离的项目名称,简化了对多个环境的管理;
  • 通过自动将以前的容器运行数据复制到新的环境中,防止数据丢失;
  • 通过只更新自上次运行以来发生变化的容器,加快了创建时间;
  • 使用定义的环境变量在不同的环境中轻松移植应用程序;

安装

如果你是 Docker Desktop 用户则已经带有 Docker Compose 不需要额外安装

如果你是 Linux Server 用户并已经安装了 Docker Engine 和 Docker CLI 则可以使用包管理器安装 Docker Compose,例如:

# Debian 谱系
sudo apt update
sudo apt install docker-compose-plugin

# Red Hat 谱系
sudo yum update
sudo yum install docker-compose-plugin

也可以手动安装:

sudo curl -SL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

# 赋予运行权限
sudo chmod +x /usr/local/bin/docker-compose

不要直接使用以上链接,而是前往 https://github.com/docker/compose/releases/ 获取对应系统架构的最新版,如上链接就是 x64 架构的 2.16.0,将之替换使用

注意,使用包管理器安装和手动安装所使用的命令不同:

# 使用包管理器安装的 Compose 使用命令
docker compose version

# 使用脚本安装的 Compose 使用命令
docker-compose version

如果看到返回 Docker Compose version v2.16.0 则表示 Docker Compose 安装成功

使用

配置文件

Compose 使用 YAML 格式文件来配置服务,如果你并不熟悉 YAML 格式就需要一个能够验证该文件格式的编辑器,如 VSCode 并安装插件 Docker

Compose 的使用与 Dockerfile 类似,编写好配置文件然后使用命令运行,一个基本的 Compose 文件如下:

version: "3.8"

services: # 容器
  servicename: # 服务名称
    image: # 映像
    command: # 可选,如果设置,则会覆盖默认镜像里的 CMD
    environment: # 可选,相当于 docker run --env
    volumes: # 可选,相当于docker run -v
    networks: # 可选,相当于 docker run --network
    ports: # 可选,相当于 docker run -p
  servicename2: # 第二个服务名称,当运行多个容器时
    image: # 映像
    command: # 可选,如果设置,则会覆盖默认镜像里的 CMD
    environment: # 可选,相当于 docker run --env
    volumes: # 可选,相当于docker run -v
    networks: # 可选,相当于 docker run --network
    ports: # 可选,相当于 docker run -p

volumes: # 可选,相当于 docker volume create

networks: # 可选,相当于 docker network create

第一行的 version 在 Docker Compose 中用于指定 Compose 文件的语法和功能集。每个版本都定义了一组支持的功能和语法规则,以及与 Docker Engine 的兼容性。

可以在 Compose file versions and upgrading - Docker 中查看 Compose 版本与 Docker Engine 所对应的版本

即当你编写的 Compose 文件较新,而使用者所安装的 Docker Engine 版本较旧时会报错。

然后来看一个使用 Compose 的 NGINX 例子:

version: '3'
services:
  webserver:
    image: nginx:alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - "8080:80"

如果使用 docker run 命令它是这样的:

docker run -p 8080:80 --name nginx --restart=unless-stopped nginx:alpine

💡 设想一下使用 Docker Compose 管理一个或多个容器,且容器选项命令繁杂时,是不是就很方便了?

查看 官方文档 可以了解更多 Docker Compose 说明。

编写好配置文件后,将其命名为 compose.yamlcompose.yml,如果同时存在则优先 compose.yaml。为了向后兼容,还支持 docker-compose.yamldocker-compose.yml,也就是说将配置文件以上述 4 种命名皆可,但最推荐使用 compose.yaml

然后在存放该配置文件的目录使用相关命令即可。

管理命令

在存放 Compose 配置文件的目录使用命令 docker compose 就可以进行管理了:

别忘了,根据前文所述安装方式的不同命令可能是 docker composedocker-compose

如果你的配置文件并不使用上述四种命名,也可以使用 -f 选项指定配置文件,如 docker compose -f config.yaml

# 启动
docker compose up
# 在后台启动
docker compose up -d

# 重启
docker compose restart # 重启服务容器

# 停止
docker compose down # 停止并删除容器和网络
# 删除未在 Compose 文件中定义的其他已停止的容器
# 如通过 docker run 启动的容器,慎用
docker compose down --remove-orphans
# 或停止指定服务
docker compose stop <服务名称>

# 查看状态
docker compose ps # 同样可以使用 -a
# 查看服务日志
docker compose logs <服务名称>

# 更新
docker compose pull
docker compose up -d
docker compose up -d --no-deps <服务名称> # 更新多个服务中的指定服务

在 Compose 中使用 Dockerfile

如果 Docker Compose 的映像是通过 Dockerfile 构建的呢?

version: '3'
services:
  webserver: # 服务名称
    build:
      context: . # 当前目录
      dockerfile: Dockerfile # Dockerfile 的文件名
    container_name: nginx
    restart: unless-stopped
    ports:
      - "8080:80"

image 替换成 build 及使用其 contextdockerfile 字段:

  • context 表示 Dockerfile 文件的路口,如 . 表示和 Docker Compose 文件在同个目录,若是当前目录的 config 目录内可以表示为: ./config
  • dockerfile 表示 Dockerfile 的文件名;

然后使用命令:

# 在启动前预算构建以加快启动
docker compose build
docker compose build <服务名称> # 也可以指定构建的服务

# 初次启动时会 build
docker compose up -d

# 如果已经启动了需要更新构建
docker compose up -d --build

使用 .env 设置环境变量

修改 compose.yaml 文件:

version: '3'
services:
  webserver:
    image: nginx:${TAG}
    container_name: nginx
    restart: unless-stopped
    ports:
      - "${PORT}:80"

修改 .env 文件:

TAG=stable
PORT=8080

如上示例通过使用 ${}.env 文件指定了拉取映像的标签和主机上的端口,然后可以使用命令 docker compose config 来查看环境变量的应用

另外如果你不想命名成 .env 文件,可以在启动时使用选项,如命名成 env 文件不带点:docker compose --env-file ./env up -d