1. 什么是docker-compose

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

官方文档 - Docker Compose

2. 安装

docker-compose安装可以参考官方文档:Install Docker Compose

2.1. macOs

Docker Desktop for Mac 和 Docker Toolbox 已集成了docker-compose, 所以只要安装了docker是不需要安装的,直接就可以用。

2.2. Linux

在Linux系统中,可以通过源码来安装docker-compose

  1. 从github下载最新版docker-compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  1. 给docker-compose赋予可执行权限

sudo chmod +x /usr/local/bin/docker-compose

最后可以通过以下命令来验证是否安装成功:

docker-compose --version

3. 语法

docker-compose 文件命名以.yml.yaml为后缀。

下面先欣赏一下官方文档中的一个示例:

version: "3"services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]

  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  frontend:
  backend:

volumes:
  db-data:

从上述示例看,整个文档分为4部分,versionservicesnetworksvolumes, 其中services中内容最长,下面将一一做个简单介绍

3.1. version

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

Compose file formatDocker Engine release
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
1.0 1.9.1.+

3.2. services

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

3.2.1. image

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

例如下面这些格式都是可以的:

image: redisimage: ubuntu:14.04image: tutum/influxdbimage: example-registry.com:4000/postgresqlimage: a4bc65fd

3.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 后面的那个名字。

既然可以在 docker-compose.yml 中定义构建任务,那么一定少不了 arg 这个标签,就像 Dockerfile 中的 ARG 指令,它可以在构建过程中指定环境变量,但是在构建成功后取消,在 docker-compose.yml 文件中也支持这样的写法:

build:
  context: .
  args:
    buildno: 1
    password: secret

下面这种写法也是支持的,一般来说下面的写法更适合阅读。

build:
  context: .
  args:
    - buildno=1
    - password=secret

与 ENV 不同的是,ARG 是允许空值的。例如:

args:
  - buildno
  - password

这样构建过程可以向它们赋值。

注意:YAML 的布尔值(true, false, yes, no, on, off)必须要使用引号引起来(单引号、双引号均可),否则会当成字符串解析。

3.2.3. command

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

command: bundle exec thin -p 3000

也可以写成类似 Dockerfile 中的格式:

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

3.2.4. container_name

Compose 的容器名称格式是:<项目名称><服务名称><序号>
虽然可以自定义项目名称、服务名称,但是如果你想完全控制容器的命名,可以使用这个标签指定:

container_name: app

这样容器的名字就指定为 app 了。

3.2.5. depends_on

在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:

version: '2'services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。

3.2.6.dns

和 --dns 参数一样用途,格式如下:

dns: 8.8.8.8

也可以是一个列表:

dns:  - 8.8.8.8
  - 9.9.9.9

此外 dns_search 的配置也类似:

dns_search: example.comdns_search:  - dc1.example.com
  - dc2.example.com

3.2.7. environment

和 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

3.2.8. extra_hosts

添加主机名的标签,就是往/etc/hosts文件中添加一些记录,与Docker client的--add-host类似:

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

启动之后查看容器内部hosts:

162.242.195.82  somehost
50.31.209.229   otherhost

3.2.9. labels

向容器添加元数据,和Dockerfile的LABEL指令一个意思,格式如下:

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

3.2.10 links

还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的--link一样效果,会连接到其它服务中的容器。
格式如下:

links: - db
 - db:database
 - redis

使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:

172.12.2.186  db172.12.2.186  database172.12.2.187  redis

相应的环境变量也将被创建。

3.2.11 ports

映射端口的标签。
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。

ports: - "3000" - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

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

3.2.12. volumes

挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式,或者使用 [HOST:CONTAINER:ro] 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统。
Compose的数据卷指定路径可以是相对路径,使用 . 或者 .. 来指定相对目录。
数据卷的格式可以是下面多种形式:

volumes:  // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql 
  // 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql 
  // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
  - ./cache:/tmp/cache 
  // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro 
  // 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql

如果你不使用宿主机的路径,你可以指定一个volume_driver。

volume_driver: mydriver

3.2.13. networks

加入指定网络,格式如下:

services:
  some-service:
    networks:
     - some-network
     - other-network

关于这个标签还有一个特别的子标签aliases,这是一个用来设置服务别名的标签,例如:

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2

相同的服务可以在不同的网络有不同的别名。

3.2.14. network_mode

网络模式,与Docker client的--net参数类似,只是相对多了一个service:[service name] 的格式。
例如:

network_mode: "bridge"network_mode: "host"network_mode: "none"network_mode: "service:[service name]"network_mode: "container:[container name/id]"

可以指定使用服务或者容器的网络。

4. 常用命令

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

docker-compose --help

结果如下:

Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--helpOptions:
  -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
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --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
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert deploy
                              keys in v3 files to their non-Swarm equivalent

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

打印服务日志

语法:

logs [options] [SERVICE...]

参数:

--no-color          Produce monochrome output.
-f, --follow        Follow log output
-t, --timestamps    Show timestamps
--tail="all"        Number of lines to show from the end of the logs                    for each container.

4.5. up

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

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

语法:

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

参数:

    -d                         后台运行,输出容器的名字.
                               Incompatible with --abort-on-container-exit.
    --no-color                  单色输出.
    --no-deps                  不启动link服务.
    --force-recreate           强制重新创建compose服务,即使没有任何改变。重新创建后启动容器
                               Incompatible with --no-recreate.
    --no-recreate               如果容器已经存在,不重新创建.
                               Incompatible with --force-recreate.
    --no-build                 不创建重启,即使镜像不存在.
    --build                    重新创建镜像,然后生成容器.
    --abort-on-container-exit  任何容器停止,自动停止所有容器.
                               Incompatible with -d.
    -t, --timeout TIMEOUT      超时时间. (default: 10)
    --remove-orphans           移除compose文件中未定义服务的容器

4.6. create

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

语法:

create [options] [SERVICE...]

参数

    --force-recreate       重新创建容器,即使他的配置和镜像没有改变,不兼容--no-recreate参数
    --no-recreate          如果容器已经存在,不需要重新创建. 不兼容--force-recreate参数
    --no-build             不创建镜像,即使缺失.
    --build                创建容器前,生成镜像

4.7. down

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

语法:

down [options]

参数:

--rmi type          删除镜像,类型必须是:                        'all': 删除compose文件中定义的所以镜像.                        'local': 删除镜像名为空的镜像
-v, --volumes       删除卷
                        attached to containers.
--remove-orphans    Remove containers for services not defined in the
                        Compose file

4.8. start

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

4.9. stop

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

4.10. pause

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

4.11. unpause

恢复容器服务,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

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

语法:

run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...]
        SERVICE [COMMAND] [ARGS...]

参数:

-d                    后台运行,输出容器名.
-e KEY=VAL            设置环境变量参数,可以使用多次
-u, --user=""         指定运行的用户
--no-deps             不启动link服务,只启动run的服务.
--rm                  运行后删除容器,后台运行模式除外(-d).
-p, --publish=[]      开放端口
--service-ports       compose文件中配置什么端口,就映射什么端口.
-T                    禁用TTY.
-w, --workdir=""      设置工作目录

例如:

docker-compose run ubuntu ping docker.com

4.15. scale

设置同一个服务运行的容器个数。通过 service=num 的参数来设置数量。

 



posted on 2020-02-16 18:14  砖头哥-  阅读(1018)  评论(0编辑  收藏  举报