简介

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。Compose通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。

Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。

Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。

使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。

源码:https://github.com/docker/compose

安装与卸载

官网链接:https://docs.docker.com/compose/install/

方法一

下载docker-compose
[root@ns 1 ~]# curl - L
"https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname - s)-$(uname - m)" - o /usr/local/bin/docker-compose
#安装docker-compose
[root@ns 1 ~]# chmod +x /usr/local/bin/docker-compose
#查看版本
[root@ns 1 ~]# docker-compose version
docker-compose version 1. 25. 0 , build 0 a 186604
docker-py version: 4. 1. 0
CPython version: 3. 7. 4
OpenSSL version: OpenSSL 1. 1. 0 l  10 Sep 2019

方法二

#安装pip
yum - y install epel-release
yum - y install python-pip
#确认版本
pip - -version
#更新pip
pip install - -upgrade pip
#安装docker-compose
pip install docker-compose
#查看版本
docker-compose version

卸载

rm /usr/local/bin/docker-compose
#或者
pip uninstall docker-compose

使用Compose基本上是一个三步过程。

  1. 使用Dockerfile定义应用程序的环境,以便可以在任何地方复制。
  2. 在docker-compose.yml中定义组成应用程序的服务,以便它们可以在独立的环境中一起运行。
  3. 最后,运行docker-compose up,compose将启动并运行整个应用程序。

一个docker-compose.yml看起来如下所示:

version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}

docker-compose源码实例:

#docker-Compse的版本
version: '3'
#建立2个service 一个wordpress 一个 mysql
services:
  wordpress:
    image: wordpress
#端口映射80 映射到8080端口
    ports:
    - 8080:80
#环境变量2个
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD: root
    networks:
    - my-bridge
  mysql:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:
    - mysql-data:/var/lib/mysql
    networks:
    - my-bridge
#建立一个volumes
volumes:
  mysql-data:
#建立一个networks
networks:
  my-bridge:

模板文件

Compose允许用户通过一个docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Compose模板文件是一个定义服务(services)、网络(networks)和卷(volumes)的YAML文件。Compose模板文件默认路径是当前目录下的docker-compose.yml,可以使用.yml或.yaml作为文件扩展名。

Docker-Compose标准模板文件应该包含version、services、networks三大部分,最关键的是services和networks两个部分。

1. version

version是compose的版本,下表是compose版本与docker版本对照表:

Compose file format Docker Engine
1 1.9.0+
2.0 1.10.0+
2.1 1.12.0+
2.2, 3.0, 3.1, 3.2 1.13.0+
2.3, 3.3, 3.4, 3.5 17.06.0+
2.4 17.12.0+
3.6 18.02.0+
3.7 18.06.0+

2. services

services是用来配置定义每个容器启动参数,每个service就是一个容器,services下一级配置即是服务名称,例如上面示例中的wordpress, mysql。

2.1 image

image是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。

services:
  web:
    image: hello-world
    #以下格式也都是可以的
    image: redis
    image: ubuntu: 14. 04
    image: tutum/influxdb
    image: example-registry.com: 4000 /postgresql
    image: a 4 bc 65 fd

2.2 build

服务除了可以基于指定的镜像,还可以基于一份 Dockerfile,在使用 up 启动之时执行构建任务,这构建标签就是 build,它可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。

build: /path/to/build/dir
#也可以是相对路径,只要上下文确定就可以读取到Dockerfile
build: ./dir
#还可以设定上下文根目录,然后以该目录为准指定Dockerfile
build:
  context: ../
  dockerfile: path/of/Dockerfile
注意
  • build 都是一个目录,如果你要指定 Dockerfile 文件需要在 build 标签的子级标签中使用dockerfile 标签指定,如上面的例子
  • 如果你同时指定了 image 和 build 两个标签,那么 Compose 会构建镜像并且把镜像命名为image 后面的那个名字。
ARGS

添加构建参数,这些是只能在构建过程中可访问的环境变量。

  1. 首选,在你的Dockerfile文件中指定这些参数
ARG buildno
ARG gitcommithash

RUN echo "Build number: $buildno"
RUN echo "Based on commit: $gitcommithash"
  1. 然后在build下面指定这些值。你能传递一个映射或列表。
build:
  context: .
  args:
    buildno: 1
    gitcommithash: cdc3b19
    
  
    
build:
  context: .
  args:
    - buildno=1
    - gitcommithash=cdc3b19

您可以在指定构建参数时忽略该值,在这种情况下,构建时的值就是运行Compose的环境中的值。

args:
  - buildno
  - gitcommithash

注意:

YAML布尔值(true,false,yes,no,on,off)必须用引号括起来,这样分析器会将它们解释为字符串。

2.3 command

使用command可以覆盖容器启动后默认执行的命令。

command: bundle exec thin - p 3000

也可以写成类似于Dockerfile中列表格式:

command: ["bundle", "exec", "thin", "-p", " 3000 "]

2.4 container_name

Compose的容器默认名称格式是:<项目名称><服务名称><序号>指定自定义容器名称,而不是生成的默认名称。

container_name: my-web-container

由于Docker容器名称必须唯一,因此如果您指定了自定义名称,则不能将服务扩展到 1 个以上的容器。尝试这样做会导致错误。

2.5 depends_on

在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。

例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。

version: "3.7"
services:
  web:
    build: .
      depends_on:
      - db
      - redis
   redis:
     image: redis
   db:
     image: postgres
  • docker-compose up以依赖性顺序启动服务。在示例中,db和redis在web之前启动。
  • docker-compose up SERVICE自动包含SERVICE的依赖项。在示例中,docker-compose up web还将创建并启动db和redis。
  • docker-compose stop按依赖关系顺序停止服务。在示例中,web在db和redis之前停止。
  • depends_on在web启动之前,它不会等待db和redis“准备就绪”。

2.6 dns

自定义DNS服务器,可以是单一的值或者一个列表。

dns: 8.8.8.8
#或者
dns:
  - 8.8.8.8
  - 9.9.9.9

dns_search 自定义DNS搜索域,可以是一个值或者一个列表:

dns_search: example.com
#或者
dns_search:
  - dc1.example.com
  - dc2.example.com

2.7 environment

添加环境变量。您可以使用数组或字典。任何布尔值(true、false、yes no)都需要用引号括起来,以确保它们不会被YML解析器转换为true或false。

只有一个键的环境变量被解析为Compose正在运行的计算机上的值,这对机密值或主机特定值很有帮助。

和 arg 有几分类似,这个标签的作用是设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置,这是与 arg 最大的不同。一般 arg 标签的变量仅用在构建过程中。而environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:
#或者
environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

2.8 extra_hosts

添加主机名映射。类似于docker客户端的–add-host参数。

extra_hosts:
  - "somehost:162.242.195.82"
  - "otherhost:50.31.209.229"

会在内部的容器中的/etc/hosts中创建IP地址和主机名映射项:

162. 242. 195. 82 somehost
50. 31. 209. 229 otherhost

2.9 lables

添加元数据到构建产生的镜像中。可以使用数组或者字典。建议使用反向DNS符号,以防止您的标签与其他软件使用的标签冲突。注:这个选项是3.3版本的新选项

build:
  context:.
  labels:
    com.example.description: "Accounting webapp"
    com.example.department: "Finance"
    com.example.label-with-empty-value: ""
build:
  context: .
  labels:
  - "com.example.description=Accounting webapp"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"

2.10 ports

暴露端口

短语法

要么指定两个端口(主机:容器),要么仅指定容器端口(主机选择临时端口)。

注意:当使用HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为 60 进制。所以建议采用字符串格式。

ports:
  - "3000"
  - "3000-3005"
  - "8000:8000"
  - "9090-9091:8080-8081"
  - "49100:22"
  - "127.0.0.1:8001:8001"
  - "127.0.0.1:5000-5010:5000-5010"
  - "6060:6060/udp"
长语法

长格式语法允许配置其他不能以短格式表示的字段。长语法是v3.2中的新增功能。

  • target:容器内的端口
  • published:公开端口
  • protocol:端口协议(tcp或udp)
  • mode:host 用于在每个节点上发布主机端口,或 ingress 为一个swarm群集模式端口,能被负载平衡。
ports:
  - target: 80
    published: 8080
    protocol: tcp
    mode: host

2.11 volumes

挂载主机路径或者是已被命名的卷,指定其为一个service的子选项。

您可以将主机路径挂载为单个服务定义的一部分,而无需在顶级volumes中定义它。但是,如果要跨多个服务重用卷,应该在顶级volumes中定义命名卷。

version: "3.7"
services:
  web:
  image: nginx:alpine
  volumes:
    - type: volume
    source: mydata #mydata为顶级命名的volumes
    target: /data
    volume:
      nocopy: true
    - type: bind
      source: ./static
      target: /opt/app/static
db:
  image: postgres:latest
  volumes:
    - "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock" #只为db服务的数据卷
    - "dbdata:/var/lib/postgresql/data" #dbdata为顶级volumes,采用的是旧字符串形式
volumes: #定义顶级volumes
  mydata:
  dbdata:
短语法

可选择性的指定一个host主机上的路径(HOST:CONTAINER),或者一个访问的权限(HOST:CONTAINER:ro)。

volumes:
  # 只是指定一个路径,docker引擎会创建一个数据卷
  - /var/lib/mysql
  # 指定一个绝对路径的映射
  - /opt/data:/var/lib/mysql
  # 主机上的路径,相对于compose文件
  - ./cache:/tmp/cache
  # 使用用户的相对路径
  - ~/configs:/etc/configs/:ro
  # 顶级的命名数据卷
  - datavolume:/var/lib/mysql

可以是主机host上的相对路径,相对于被使用的compose配置文件的目录。

长格式

长格式语法允许配置不能用短格式表示的其他字段。

  • type : 挂载的类型:volume,bind,tmgfs,npipe
  • source : 挂载的源,可以是主机上的一个路径,或者是顶级volumes中定义的一个值,不能是tmpfs挂载。
  • target : 挂载的卷的容器中的路径
  • read_only : 设置这个卷是只读的
  • bind : 配置额外的bind选项
    • propagation : the propagation mode used for the bind
  • volume : 配置额外的卷选项
    • nocopy: 用于在创建卷时禁用从容器复制数据的标志
  • tmpfs : 配置额外的tmpfs选项
    • size: tmpfs挂载时的大小(字节)
  • onsistency :挂载时的一致性要求。
    • consistent:主机和容器有完全一致的显示
    • cached: 读缓存,主机显示是权威的
    • delegated: 读写缓存,容器的显示是权威的
version: "3.7"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
       - type: bind
         source: ./static
         target: /opt/app/static
networks:
  webnet:
volumes:
  mydata:
volume配置参考

虽然可以将文件中的volumes声明为service声明的一部分,但允许您创建可跨多个service重用的命名卷(不依赖volumes_from),并且可以使用docker命令行或API轻松检索和检查这些命名卷。

下面是两个服务设置的示例,其中数据库的数据目录作为卷与另一个服务共享,以便可以定期备份:

version: "3.7"
services:
  db:
    image: db
  volumes:
    - data-volume:/var/lib/db
  backup:
    image: backup-service
    volumes:
      - data-volume:/var/lib/backup/data
  volumes:
    data-volume:

顶级volumes下的项的值能够被设置成空,在这种情况下,它使用由引擎配置的默认驱动程序(在大多数情况下,是local驱动程序)。

3. networks

顶级networks的值,让你指定的网络被创建。可以使用driver指定这个网络的驱动,默认的驱动依赖于docker引擎,大多数情况下,单一主机是bridge,swarm集群是overlay。

services:
  web1:
    image: nginx
    ports:
      - "6061:80"
    container_name: "web1"
    networks:
      - caiwubu
networks:
  caiwubu:
    driver: bridge

常用命令

docker-compose命令可以通过以下命令大致看一下:

$  docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   Show more output
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

常用的命令如下:

4.1 build

当修改dockerfile或者docker-compose时,运行docker-compose build 重建镜像。 生成镜像后,可使用docker-compose up启动

4.2 ps

显示所有容器信息,默认显示name、command、state、ports.

4.3 kill

强制停止某个正在运行的服务.

4.4 logs

打印服务日志.

4.5 up

构建,(重新)创建,启动,链接一个服务相关的容器。链接的服务都将会启动,除非他们已经运行。默认情况, docker-compose up 将会整合所有容器的输出,并且退出时,所有容器将会停止。如果使用 docker-compose up -d ,将会在后台启动并运行所有的容器。

默认情况,如果该服务的容器已经存在, docker-compose up 将会停止并尝试重新创建他们(保持使用 volumes-from 挂载的卷),以保证 docker-compose.yml的修改生效。如果你不想容器被停止并重新创建,可以使用 docker-compose up –no-recreate。如果需要的话,这样将会启动已经停止的容器。

语法:

Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...]

参数:
$  docker-compose up -h 

Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...]

Options:
    -d                         Detached mode: Run containers in the background,
                               print new container names. Incompatible with
                               --abort-on-container-exit and --timeout.
    --no-color                 Produce monochrome output.
    --no-deps                  Don't start linked services.
    --force-recreate           Recreate containers even if their configuration
                               and image haven't changed.
                               Incompatible with --no-recreate.
    --no-recreate              If containers already exist, don't recreate them.
                               Incompatible with --force-recreate.
    --no-build                 Don't build an image, even if it's missing.
    --no-start                 Don't start the services after creating them.
    --build                    Build images before starting containers.
    --abort-on-container-exit  Stops all containers if any container was stopped.
                               Incompatible with -d.
    -t, --timeout TIMEOUT      Use this timeout in seconds for container shutdown
                               when attached or when containers are already.
                               Incompatible with -d.
                               running. (default: 10)
    --remove-orphans           Remove containers for services not
                               defined in the Compose file
    --exit-code-from SERVICE   Return the exit code of the selected service container.
                               Implies --abort-on-container-exit.
    --scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the `scale`
                               setting in the Compose file if present.

4.6 create

为服务创建容器.只是单纯的create,还需要使用start启动compose.

语法:
Usage: create [options] [SERVICE...
参数:
Options:
    --force-recreate       Recreate containers even if their configuration and
                           image haven't changed. Incompatible with --no-recreate.
    --no-recreate          If containers already exist, don't recreate them.
                           Incompatible with --force-recreate.
    --no-build             Don't build an image, even if it's missing.
    --build                Build images before creating containers.

4.7 down

停止和删除容器、网络、卷、镜像,这些内容是通过docker-compose up命令创建的. 默认值删除容器网络,可以通过指定 rmi volumes参数删除镜像和卷。

语法:
Usage: down [options]
参数:
Options:
    --rmi type              Remove images. Type must be one of:
                              'all': Remove all images used by any service.
                              'local': Remove only images that don't have a
                              custom tag set by the `image` field.
    -v, --volumes           Remove named volumes declared in the `volumes`
                            section of the Compose file and anonymous volumes
                            attached to containers.
    --remove-orphans        Remove containers for services not defined in the
                            Compose file
    -t, --timeout TIMEOUT   Specify a shutdown timeout in seconds.
                            (default: 10)

4.8 start

启动一个已经存在的服务容器

4.9 stop

停止一个已经运行的容器,但不删除它。通过 docker-compose start可以再次启动这些容器。

4.10 pause

暂停容器服务,docker-compose pause 暂停所有服务。docker-compose pause web,暂停web服务的容器。

4.11 uppause

恢复容器服务,docker-compose unpause 恢复所有服务,docker-compose unpause web,恢复web服务的容器。

4.12 restart

重启docker-compose.yml中定义的所有的已停止的和正在运行的服务。

4.13 rm

删除已经停止的容器,如果服务在运行,需要先docker-compose stop 停止容器,默认情况下,已挂载的volume中的数据不会被删除,可以使用docker volume ls查看所有的volume情况。所有在容器中并未在volume中的数据将被删除。

4.14 run

在一个服务上执行一个命令。

语法:
Usage:
    run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...]
        SERVICE [COMMAND] [ARGS...]
参数:
Options:
    -d                    Detached mode: Run container in the background, print
                          new container name.
    --name NAME           Assign a name to the container
    --entrypoint CMD      Override the entrypoint of the image.
    -e KEY=VAL            Set an environment variable (can be used multiple times)
    -l, --label KEY=VAL   Add or override a label (can be used multiple times)
    -u, --user=""         Run as specified username or uid
    --no-deps             Don't start linked services.
    --rm                  Remove container after run. Ignored in detached mode.
    -p, --publish=[]      Publish a container's port(s) to the host
    --service-ports       Run command with the service's ports enabled and mapped
                          to the host.
    -v, --volume=[]       Bind mount a volume (default [])
    -T                    Disable pseudo-tty allocation. By default `docker-compose run`
                          allocates a TTY.
    -w, --workdir=""      Working directory inside the container
例如:

docker-compose run ubuntu ping docker.com