# 一、概述

Docker Compose 是一个用于定义和运行多容器Docker应用程序的工具,负责实现对Docker容器集群的快速编排。可以在一个YAML文件中定义所有配置,然后使用一个命令启动所有容器。

在日常工作中,经常会碰到需要使用多个容器,且需要多个容器相互配合来完成某项任务的情况。例如实现一个WEB服务,可能还需要数据库服务容器、缓存服务容器等。Compose恰好满足了这样的需求。

Docker Compose 不是将所有服务都放在一个大容器中,而是允许将它们拆分为可单独管理的容器。这对于构建和部署都更好,并且不需要手动启动每个单独的容器。

# 二、安装与卸载

手动从官网下载安装包或直接使用系统命令安装,选择其一即可:
【1】手动安装: Linux上安装十分简单,从Docker Compose GitHub官方仓库直接下载编译好的二进制文件即可。官方地址:链接

Docker

【2】系统命令安装: 下载docker-compose

sudo curl -L "https://github.com/docker/compose/releases/download/v2.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
1

增加权限: 我们上传二进制文件后,要添加可执行权限,才可以在Linux中正常使用。命令如下:

#进入到文件目录[安装文件的目录]
cd /usr/local/bin
#改名
mv docker-compose-linux-x86_64 docker-compose
#增加可执行权限
chmod +x docker-compose
1
2
3
4
5
6

执行ll命令后,我们可以看到docker-compose二进制文件有了可执行权限

root@ubuntu:/usr/local/bin# ll
total 25208
drwxr-xr-x  2 root root     4096 Aug 15 20:56 ./
drwxr-xr-x 13 root root     4096 Jul 27 23:16 ../
-rwxr-xr-x  1 root root 25804800 Aug 15 20:50 docker-compose*
1
2
3
4
5

查看docker-compose版本

root@ubuntu:/usr/local/bin# docker-compose -v
Docker Compose version v2.9.0
1
2

卸载: 二进制包方式安装的,删除二进制文件即可

rm -fr /usr/local/bin/docker-compose
1

# 三、使用

我们使用Docker Compose来构建一个自己的Nginx
【1】创建文件夹:

mkdir -p /usr/local/docker/nginx
1

【2】创建index.html

echo 'Hello Docker Compose!' > index.html
1

【3】创建Dockerfile

vi Dockerfile
1

【4】内容如下:

FROM nginx:latest

MAINTAINER Micromaple <zzx@vip.qq.com>

COPY index.html /usr/share/nginx/html/index.html

EXPOSE 80
1
2
3
4
5
6
7

【5】创建docker-compose.yml

version: '3.1'
services:
    nginx:
    build: .
    ports:
        - "80:80"
1
2
3
4
5
6

【6】运行Docker Compose项目

docker-compose up
1

【7】访问:此时访问 http://ip 可以看到页面如下

Docker

# 四、模板文件

模板文件是使用Compose的核心,涉及到的指令关键字也比较多。默认的模板文件名称为docker-compose.yml,格式为YAML格式。

version: "3"
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - "./html:/usr/share/nginx/html"
1
2
3
4
5
6
7
8

每个服务都必须通过image指令指定镜像或build指令(需要 Dockerfile)等来自动构建生成镜像。

使用build指令,在Dockerfile中设置的选项(例如: CMD ,EXPOSE,VOLUME,ENV等) 将会自动被获取,无需在docker-compose.yml中再次设置。

常用指令:
【1】build: 指定Dockerfile所在文件夹的路径(可以是绝对路径,或者相对docker-compose.yml文件的路径)。Compose将会利用它自动构建这个镜像,然后使用这个镜像。

version: '3.1'
services:
  nginx:
    build: .
1
2
3
4

也可以使用context指定Dockerfile所在文件夹的路径。使用dockerfile指令指定Dockerfile文件名。使用arg指令指定构建镜像时的变量。如下:

version: '3.1'
services:
  nginx:
    build:
      context: ./dir
      dockerfile: Dockerfile-nginx
      args:
        buildno: 1
1
2
3
4
5
6
7
8

【2】command:覆盖容器启动后默认执行的命令。

version: "3.1"
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    command: echo "hello world"
1
2
3
4
5
6
7

【3】container_name:指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。

version: "3.1"
services:
  nginx:
    image: nginx
    container_name: nginx_web
    ports:
      - "80:80"
    command: echo "hello world"
1
2
3
4
5
6
7
8

【4】depends_on:解决容器的依赖、启动先后的问题。以下例子中会先启动redis db在启动web

version: '3.1'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres
1
2
3
4
5
6
7
8
9
10
11

注意:web服务不会等待redis db完全启动之后才启动。

【5】env_file:从文件中获取环境变量,可以为单独的文件路径或列表。

如果通过docker-compose -f FILE方式来指定Compose模板文件,则env_file中变量的路径会基于模板文件路径。

如果有变量名称与environment指令冲突,则按照惯例,以后者为准。

env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env
1
2
3
4
5
6

环境变量文件中每一行必须符合格式,支持#开头的注释行。

# common.env: Set development environment
PROG_ENV=development
1
2

【6】environment:设置环境变量。你可以使用数组或字典两种格式。只给定名称的变量会自动获取运行Compose主机上对应变量的值,可以用来防止泄露不必要的数据。

environment:
  RACK_ENV: development
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SESSION_SECRET
1
2
3
4
5
6
7

如果变量名称或者值中用到true|falseyes|no等表达布尔含义的词汇,最好放到引号里,避免YAML自动解析某些内容为对应的布尔语义。这些特定词汇,包括如下:

y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
1

【7】expose:暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数

expose:
 - "3000"
 - "8000"
1
2
3

【8】image:指定为镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取这个镜像。

image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
1
2
3

【9】networks:配置容器链接的网络

version: "3.1"
services:
  some-service:
    networks:
     - some-network
     - other-network
networks:
  some-network:
  other-network:
1
2
3
4
5
6
7
8
9

【10】ports:暴露端口信息。使用宿主端口:容器端口 (HOST:CONTAINER) 格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"
1
2
3
4
5

注意:当使用HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于60并且没放到引号里,可能会得到错误结果,因为YAML会自动解析xx:yy这种数字格式为60进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。

【11】secrets:存储敏感数据,例如mysql服务密码。

version: "3.1"
services:

mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
  secrets:
    - db_root_password
    - my_other_secret

secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

【12】volumes:数据卷所挂载路径设置。可以设置宿主机路径,宿主机路径:容器内路径 HOST:CONTAINER或加上访问模式HOST:CONTAINER:ro

宿主机路径可以为相对路径,相对路径基于 Compose 模板文件路径。

volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro
1
2
3
4

【13】privileged:允许容器中运行一些特权命令。

privileged: true
1

【14】restart:指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境中推荐配置为always或者unless-stopped

restart: always
1

变量读取: Compose模板文件支持动态读取主机的系统环境变量和当前目录下的.env文件中的变量。使用Compose文件从运行的环境中读取变量${nginx_version}的值,并写入执行的指令中。

version: "3.1"
services:
  web:
    image: "nginx:${nginx_version}"
1
2
3
4

执行nginx_version=1.20 docker-compose up则会启动一个nginx:1.20镜像的容器

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
c1f23dd35d51        nginx:1.20          "/docker-entrypoint.…"   10 seconds ago      Up 10 seconds       80/tcp              nginx2-web-1
1
2
3

若当前目录存在.env文件,执行docker-compose命令时将从该文件中读取变量。

Compose模板文件路径新建.env文件,并写入以下内容

nginx_version=1.22
1

执行docker-compose up则会启动一个nginx:1.22镜像的容器。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
86fe34faf119        nginx:1.22          "/docker-entrypoint.…"   4 seconds ago       Up 4 seconds        80/tcp              nginx2-web-1
1
2
3

# 五、常用命令

前台运行

docker-compose up
1

后台运行

docker-compose up -d
1

启动容器

docker-compose start
1

停止容器

docker-compose stop
1

停止并移除容器

docker-compose down
1

# 六、实战

以安装运行MySQL5.7为例: 创建Docker Compose模板文件

#创建文件夹
mkdir /usr/local/docker/mysql
cd /usr/local/docker/mysql

#创建模板文件
vi docker-compose.yml
1
2
3
4
5
6

内容如下:

version: '3.1'
services:
  # mysql
  mysql:
    image: mysql:5.7.38
    container_name: mysql
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./data:/var/lib/mysql
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123456
    command:
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
      --max_allowed_packet=128M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

运行容器

docker-compose up -d
1

查看容器运行状态

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
mysql               "docker-entrypoint.s…"   mysql               running             0.0.0.0:3306->3306/tcp, 33060/tcp
1
2
3

连接MySQL: 使用MySQL数据库连接工具连接。如果连接失败请检查防火墙

Docker
(adsbygoogle = window.adsbygoogle || []).push({});