Please enable Javascript to view the contents

从零开始使用 Docker 打包 Django 开发环境 (3) Docker Compose

 ·  ☕ 4 分钟

1. 基本概念

Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。使用 Docker Compose,可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

Docker Compose 定位是 ‘defining and running complex applications with Docker’,前身是 Fig,兼容 Fig 的模板文件。

Docker Compose 发展至今,有 Version 1、Version 2、Version 3 三个大版本。如果不声明版本,默认为 Version 1。Version 1 不能使用 volumes,、networks、 build参数。Version 2,必须在版本中申明,所有的服务,都必须申明在 service 关键字下。Version 3 删除了 volume_drivervolumes_fromcpu_sharescpu_quotacpusetmem_limitmemswap_limitextendsgroup_add 关键字,新增了 deploy,全面支持 Swarm mode。更详细的比较可以查看参考链接。

本文中主要以 Version 2 为例学习 Docker Compose 容器的编排。

2. 工作原理

Docker Compose 将所管理的容器分为三层,工程(project),服务(service)以及容器(contaienr)。Docker Compose 运行的目录下的所有文件(docker-compose.yml、extends文件、环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。

一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务当中可包括多个容器实例,Docker Compose 并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡。

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
version: '2'
services:
    web:
        build: .
        ports:
          - "80:90"
        volumes:
          - .:/code
        links:
          - redis
    redis:
        image: redis

其定义了两个服务 web 和 redis。web 服务的镜像需要使用当前目录的 Dockerfile 实时构建,其容器运行时需要在宿主机开放端口 80 并映射到容器端口 90 ,并且挂载存储卷 /code 以及关联服务
redis。redis 服务通过镜像 redis 启动。

Docker Compose 是由 Python 语言实现的,它通过调用 docker-py 库(可参考
https://github.com/docker/docker-py )与 docker engine 通信实现构建 docker 镜像,启动停止 docker 容器等。Docker-py 库调用 docker remote API(可参考
https://docs.docker.com/reference/api/docker_remote_api/ )与 Docker Daemon
通信,可通过 DOCKER_HOST 配置本地或远程 Docker Daemon 的地址。

3 Docker Compose 常用命令

命令 解释
docker-compose build 构建 yml 中服务的镜像
docker-compose ps 查看已经启动的服务状态
docker-compose kill 停止某个服务
docker-compose logs 可以查看某个服务的log
docker-compose port 打印绑定的public port
docker-compose pull pull服务镜像
docker-compose up 启动yml定义的所有服务
docker-compose stop 停止yml中定义的所有服务
docker-compose start 启动被停止的yml中的所有服务
docker-compose kill 强行停止yml中定义的所有服务
docker-compose rm 删除yml中定义的所有服务
docker-compose restart 重启yml中定义的所有服务
docker-compose scale 扩展某个服务的个数,可以向上或向下
docker-compose version 查看compose的版本

4. YAML 常用关键字

4.1 build

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

1
build: /path/to/build/dir

4.2 command

覆盖容器启动后默认执行的命令。

1
command: echo "hello world"

4.3 dockerfile

如果需要指定额外的编译镜像的 Dockefile 文件,可以通过该指令来指定。例如:

1
dockerfile: Dockerfile-alternate

注意,该指令不能跟 image 同时使用,否则 Compose 将不知道根据哪个指令来生成最终的服务镜像。

4.4 env_file

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

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

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

1
2
3
4
5
6
env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

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

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

4.5 environment

设置环境变量。你可以使用数组或字典两种格式。

只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。例如:

1
2
3
environment:
  RACK_ENV: development
  SESSION_SECRET:

或者

1
2
3
environment:
  - RACK_ENV=development
  - SESSION_SECRET

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

http://yaml.org/type/bool.html 中给出了这些特定词汇,包括

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

4.6 expose

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

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

4.7 image

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

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

链接到其它服务中的容器。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式都可以。

1
2
3
4
links:
 - db
 - db:database
 - redis

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

1
2
3
172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

被链接容器中相应的环境变量也将被创建。

4.9 volumes

数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。该指令中路径支持相对路径。例如

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

4.10 volumes_from

从另一个服务或容器挂载它的数据卷。

1
2
3
volumes_from:
 - service_name
 - container_name

5. 参考


微信公众号
作者
微信公众号