Compone
项目是Docker官方的开源项目,负责实现对Docker容器的快速编排。从功能上看,跟OpenStack
中的Heat
十分类似。Compose
定位是定义和运行多个Docker容器的应用,其前身是开源项目Fig。
在之前我们知道,通过Dockerfile我们可以很简单的定义一个单独的应用容器。然而,在日常生活中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如,除了web服务容器之外,还需要数据库服务容器,甚至还需要负载均衡容器等。Compose
恰好满足了这样的需求,他允许用户通过单独的docker-compose.yml
模板文件来定义一组关联的应用容器为一个项目。Compose
有两个重要的概念:
- 服务(service):一个应用的容器,实际上可以包含若干个运行相同镜像的容器实例
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml中定义
Compose
默认管理对象是项目,通过子命令对项目中的一组容器进行便捷的生命周期管理
安装与卸载
- 安装
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
- 卸载
rm /usr/local/bin/docker-compose
举个栗子
最常见的是Web网站,该项目包含Web应用和缓存。下面我们用Python建立一个能够记录页面访问次数的web应用:
# -*- coding: UTF-8 -*-
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello_world():
count = redis.incr('count')
return 'hello world!!! 该页面已被访问{}次'.format(count)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
编写Dockerfile,内容如下:
FROM python:3.6
COPY . /code
RUN pip install flask redis
WORKDIR /code
CMD ["python", "manager.py"]
编写docker-compose.yml
文件,这个是Compose使用的主模板文件
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis"
运行docker-compose项目:
docker-compose up
此时访问本地5000端口,每次刷新页面,计数就会加1。
常用命令参数
- -f,–file FILE:指定使用Compose模板文件,默认为
docker-compose.yml
,可以多次指定 - -p,–project-name NAME:指定项目名称,默认将使用所在目录名称作为项目名称
- –x-networking:使用Docker的可拔插网络后端特性
- –x-network-driver DRIVER:指定网络后端的驱动,默认为bridge
- –verbose:输出更多调试信息
- -v,–version:打印版本并退出
常用命令
up
格式为:docker-compose up [options] [--scale SERVICE=NUM...] [SERVICE...]
该命令十分强大,它将尝试自动完成构建包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。链接的服务都将会被自动启动,除非已经处于运行状态。可以说,大部分时候都可以使用这一命令来启动一个项目。默认情况下,docker-compose up
启动的容器都在前台,控制台将会打印容器的所有输出信息,可以很方便的进行调试。
参数如下:
- -d:后台运行服务容器
- –no-color:不适用颜色来区分不同服务的控制台输出
- –no-deps:不启动服务所链接的容器
- –force-recreate:强制重新创建容器,不能与–no-recreate同时使用
- –no-recreate:如果容器已经存在,则不重新创建,不能与–force-recreate同时使用
- –no-build:不自动构建缺失的服务镜像
- -t,–timeout TIMEOUT:停止容器时候的超时(默认为10s)
down
此命令将停止up命令所启动的容器,并移除网络
build
格式为:docker-compose build [options] [--build-arg key=val...] [SERVICE...]
构建(重新构建)项目中的服务容器。服务容器一旦被构建,将会被添加上一个标记名,例如web项目中的db容器,名称可能将会是web_db
。我们可以随时在项目目录下运行docker-compose build
来重新构建服务
参数如下:
- –force-rm:删除构建过程中的临时容器
- –no-cache:构建过程中将不适用cache(这将加长构建过程)
- –pull:始终尝试通过pull来获取更新版本的镜像
config
验证Compose文件格式是否正确,若正确则显示配置,若错误则显示错误原因。
root@ubuntu:~/docker# docker-compose config
services:
redis:
image: redis
web:
build:
context: /root/docker
ports:
- 5000:5000/tcp
version: '3.0'
exec
进入指定的容器
help
获取一个命令的帮助信息
images
包含Compose文件中包含的镜像,如下
root@ubuntu:~/docker# docker-compose images
Container Repository Tag Image Id Size
-------------------------------------------------------------
docker_redis_1 redis latest 4e8db158f18d 79.5 MB
docker_web_1 docker_web latest 16eff5b08929 886 MB
参数如下:
- -q, –quiet:只显示ID
ps
格式为:docker-compose ps [options] [SERVICE...]
列出项目中目前的所有容器,如下。
root@ubuntu:~/docker# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------
docker_redis_1 docker-entrypoint.sh redis ... Paused 6379/tcp
docker_web_1 python manager.py Paused 0.0.0.0:5000->5000/tcp
参数如下:
- -q, –quiet:只显示ID
- –services:显示服务
- –filter KEY=VAL:过滤显示
kill
格式为:docker-compose kill [options] [SERVICE...]
通过发送SIGKILL
信号来强制停止服务容器。支持通过-s
参数来指定发送的信息,如下,我们可以指定发送SIGINT
信号:
docker-compose kill -s SIGINT
logs
格式为:docker-compose logs [options] [SERVICE...]
查看服务容器的输出。默认情况下,docker-compose
将对不同服务输出进行不同颜色来区分。
参数如下:
- –no-color:关闭颜色
- -f:跟随输出
- -t:显示时间
- –tail=’all’:每个服务容器显示后面几行,默认显示所有
pause
格式为:docker-compose pause [SERVICE...]
暂停一个服务容器。
unpause
格式为:docker-compose unpause [SERVICE...]
恢复处于暂停状态的服务
port
格式为:docker-compose port [options] SERVICE PRIVATE_PORT
打印某个容器端口所映射的公共端口
参数如下:
- –protocol=proto:指定端口协议,tcp或者udp
- –index=index:如果同同一服务存在多个容器,指定命令对象的序号(默认为1)
pull
格式为:docker-compose pull [options] [SERVICE...]
拉取服务依赖的镜像。
参数如下:
- –ignore-pull-failures:忽略镜像拉取过程中的错误
- -q, –quiet:拉取不显示进度信息
- –include-deps:包括拉取依赖项服务
push
格式为:docker-compose push [options] [SERVICE...]
推送服务依赖的镜像到Docker镜像仓库
参数如下:
- –ignore-push-failures:忽略镜像推送过程中的错误
restart
格式为:docker-compose restart [options] [SERVICE...]
重启项目中的服务
参数如下:
- -t, –timeout TIMEOUT:指定重启前停止容器的超时(默认为10s)
rm
格式为:docker-compose rm [options] [SERVICE...]
删除所有(停止状态的)服务容器。推荐先执行docker-compose stop
命令来停止容器
参数如下:
- -f, –force:强制直接删除,包括非停止状态的容器。一般情况下不要使用该选项
- -v:删除容器所挂载的数据卷
- -s, –stop:删除之前会先停止容器
run
格式为:docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...] SERVICE [COMMAND] [ARGS...]
在指定服务上执行一个命令。例如:
docker-compose run ubuntu ping docker.com
将会启动一个Ubuntu服务容器,并执行ping docker.com
命令。在默认情况下,如果存在关联,则所有关联的服务将会自动被启动,除非这些服务已经在运行中。启动容器会运行指定的命令,相关卷、链接等等都会按照指定配置进行自动创建。给定的命令不会覆盖原有的自动运行命令,不会自动创建端口,以避免冲突。
参数如下:
- -d:后台运行容器
- –name NAME:为容器指定一个名字
- –entrypoint CMD:覆盖默认的容器启动指令
- -e KEY=VAL:设置环境变量值,可多次使用选项来设置多个环境变量
- -u,–user=”:指定运行容器的用户名或uid
- –no-deps:不自动启动关联的服务容器
- –rm:运行命令后自动删除容器,
-d
模式将自动忽略 - -p,–publish=[]:映射容器端口到本地主机
- –service-ports:配置服务端口并映射到本地主机
- -T:不分配伪tty,这意味着依赖tty的指令将无法运行
- -w:容器内的工作目录
scale
格式为:docker-compose scale [options] [SERVICE=NUM...]
设置指定服务运行的容器个数。例如:
docker-compose scale web=3 db=2
将启动3个容器运行web服务,两个容器运行db服务
参数如下:
- -t,timeout TIMEOUT:停止容器时的超时时间
start
格式为:docker-compose start [SERVICE...]
启动已经存在的服务容器
stop
格式为:docker-compose stop [options] [SERVICE...]
停止已经处于运行状态的容器,但不删除它。通过docker-compose start
命令可以再次启动这些容器。
参数如下:
- -t,–timeout TIMEOUT:停止容器时候的超时
top
格式为:docker-compose top [SERVICE...]
查看各个服务容器内运行的进程,如下:
root@ubuntu:~/docker# docker-compose top
docker_redis_1
UID PID PPID C STIME TTY TIME CMD
--------------------------------------------------------------------
999 9733 9704 0 19:26 ? 00:00:00 redis-server *:6379
docker_web_1
UID PID PPID C STIME TTY TIME CMD
-------------------------------------------------------------------
root 9451 9410 0 19:25 ? 00:00:00 python manager.py
version
格式为:docker-compose version [--short]
打印版本信息。
参数如下:
- –short:只显示版本号
Compose模板
模板文件是使用Compose
的核心,默认的模板文件名称为docker-compose.yml
,其格式为YAML格式:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis"
注意,每个服务都必须通过image
指令指定镜像或者build
指令等来自动构建生成镜像。下面介绍各个指令的用法:
build
指定Dockerfile所在文件夹的路径(可以是绝对路径,或者相对docker-compose.yml文件的路径)。Compose将会利用它自动构建这个镜像,然后使用这个镜像:
version: '3'
services:
web:
build: ./dir
也可以使用context
指令指定Dockerfile所在文件夹的路径,使用dockerfile
指定Dockerfile文件名,使用args
指令指定构建镜像时的变量:
version: '3'
services:
web:
build:
context: .
dockerfile: Dockerfile.txt
args:
no: 1
使用cache_from
指定构建镜像的缓存:
version: '3'
services:
web:
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
cap_add,cap_drop
指定容器的内核能力(capacity)分配,例如让容器拥有所有能力,如下:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
cap_add:
- ALL
去掉NET_ADMIN能力,如下:
cap_drop:
- NET_ADMIN
command
覆盖容器执行后默认执行的命令:
command: echo "Hello World"
cgroup_parent
指定父cgroup
组,意味着将继承该组的资源限制。例如,创建了一个cgroup
组名称为cgroups_1:
cgroup_parent: cgroups_1
container_name
指定容器名称。默认会使用项目名称_服务名称_序号
这样的格式:
container_name: docker_web_container
注意:指定容器名称之后,该服务将无法进行扩展,因为Docker不允许有相同名称的容器存在
devices
指定设备映射关系,如下:
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
depends_on
解决容器的依赖、先后启动的问题,如下:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
例子中,会先启动redis、db,而后启动web服务。值得注意的是,web服务不会等待redis、db完全启动之后才启动
dns
自定义dns服务器,可以是一个值,也可以是一个列表:
dns: 8.8.8.8
或者:
dns:
- 8.8.8.8
- 114.114.114.114
dns_search
配置dns搜索域,可以是一个值,也可以是一个列表:
dns_search: example.com
或者:
dns_search:
- domain1.example.com
- domain2.example.com
tmpfs
挂载一个tmpfs文件系统到容器中,可以是一个值,也可以是一个列表:
tmpfs: /run
或者:
tmpfs:
- /run
- /var
env_file
从文件中获取环境变量,可以为单独的文件路径或列表:
env_file: ./env_file.env
或者:
env_file:
- ./common.env
- ./env_file.env
环境变量文件中每一行都必须符合格式,支持以#
开头的注释:
# 注释
MODE=test
environment
设置环境变量。你可以使用字典或者数组两种格式:
environment:
ROCK_ENV: development
ROCK_NO: 1
或者:
environment:
- ROCK_ENV=development
- ROCK_NO=1
如果变量名称或者值中用到true|false,yes|no等表达布尔含义的词汇,请将他们放进引号里面,避免YAML自动解析某些内容为对应的布尔语义。
expose
暴露端口,但不映射主机,只被连接的服务访问。仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
external_links
链接到docker-compose.yml外部的容器,甚至并非Compose管理的外部容器:
external_links:
- redis_1
- project_db_1:mysql
不建议使用!!!
extra_hosts
指定额外的host名称映射信息:
extra_hosts:
- "baidudns:8.8.8.8"
- "dockerdns:52.1.157.61"
会在启动后的服务容器中的/etc/hosts添加如下两条内容:
baidudns 8.8.8.8
dockerdns 52.1.157.61
healthcheck
检查容器是否健康运行:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 30s
retries: 3
image
指定镜像名称或者镜像ID,如果镜像本地不存在,那么Compose会尝试去拉取这个镜像:
image: ubuntu
image: orchardup/postgresql
image: 16eff5b08929
labels
为容器添加Docker元数据信息:
labels:
author: "docker"
age: 18
logging
配置日志选项:
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
目前支持三种驱动类型:json-file
、syslog
和none
。options配置日志驱动的相关参数:
options:
max-size: "200k"
max-file: "10"
networks
配置容器连接的网络:
version: "3"
services:
web:
networks:
- some-network
- other-network
或者:
version: "3"
services:
web:
networks:
some-network:
other-network:
network_mode
设置网络模式:
network_mode: "bridge"
pid
跟主机系统共享进程命名空间,打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程ID来进行相互访问和操作:
pid: "host"
ports
暴露端口信息。使用宿主端口:容器端口格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以:
ports:
- "3000"
- "5000:5000"
- "80:80"
- "127.0.0.1:8001:8001"
值得注意的是,如果使用的是宿主端口:容器端口格式进行映射时,如果容器端口小于60并且没放到引号之中,将有可能发生错误!
secrets
存储敏感数据,比如mysql服务密码:
version: "3"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
secrets:
- db_root_password
或者:
version: "3"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
secrets:
my_secret:
file: ./my_secrest.txt
db_root_password:
external: true
security_opt
指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等),例如配置标签的用户名和角色名:
security_opt:
- label:user:USER
- label:role:ROLE
stop_signal
设置另一个信号来停止容器,默认情况下使用的SIGTERM停止容器:
stop_signal: SIGUSR1
sysctls
配置容器内核参数:
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
或者:
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
ulimits
指定容器内的ulimits限制值。
例如,设置最大进程数为65535,指定文件句柄数为20000(软限制,应用可随时进行修改,不能超过硬限制)和40000(系统硬限制,只能root用户提高),如下:
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
volumes
数据卷挂载路径设置:
volumes:
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
注意:ro
为访问模式,另外此路径支持相对路径!
其他指令
此外,还有包括domainname
、entrypoint
、hostname
、ipc
、mac_address
、privileged
、read_only
、shm_size
、restart
、stdin_open
、tty
、user
、working_dir
等指令,基本上跟docker run
对应的参数功能一致。
- 指定服务容器启动后执行的入口文件:
entrypoint: /code/entrypoint.sh
- 指定运行应用的用户名:
user: nginx
- 指定容器中工作目录:
working_dir: /code
- 指定容器中搜索域名、主机名、mac地址等:
domainname: your_website.com
hostname: test
mac_address: 08-00-27-00-0C-0A
- 允许容器中运行一些特权命令:
privileged: true
- 指定重启策略,在生存环境中推荐
always
或者unless-stopped
restart: "always"
- 只读模式挂载容器的root文件系统,意味着不能对容器内容进行修改:
read_only: true
- 打开标准输出,可以接受外部输出:
stdin_open: true
- 模拟一个为终端:
tty: true
读取变量
Compose模板文件支持动态读取主机的系统环境变量和当前目录下的.env文件中的变量。例如,下面的Compose文件将从运行它的环境中读取变量${MONGO_VERSION}
的值,并写入执行的指令当中:
version: "3"
services:
db:
images: "mongo:${MONGO_VERSION}"