docker-compose-file

docker-compose-file
docker-compose.yml配置文件

compose文件示例

1
2
3
4
5
6
7
8
9
10
11
12
version: "3.8"
services:

nginx:
image: nginx:1.20.1-alpine
restart: always
volumes:
- ./data/:/usr/share/nginx/html
- demo-logs:/logs

volumes:
demo-logs:

compose文件标签

一级标签

version

指定compose版本,低版本可能不支持部分标签

services

定义服务配置,可定义多个服务来组成一个具有完整功能的项目

networks

定义网络配置,用于多服务容器的网络连接

volumes

定义数据卷配置,用于多服务容器之间的数据共享

secrets

定义密码文件配置

二级标签

service_name-自定义的服务名称,如nginx,db
network_name-自定义的网络名称,如front-net,back-net
volume_name-自定义的卷名称,如web-data,db-data
secret_name-自定义的密码名称,如mysql-passwd,redis-passwd

三级标签,以下主要是二级标签services的扩展

build

指定Dockerfile文件用于自动构建镜像,可选以下参数
context: 指定Dockerfile文件目录,默认为当前目录,即和compose文件同级的目录
dockerfile: 指定Dockerfile文件名称
args: 指定构建时变量,等同于ARG指令
labels: 指定镜像标签

1
2
3
4
5
6
version: "3.8"
services:
webapp:
build:
context: ./app
dockerfile: Dockerfile-app

image

指定服务容器的镜像

1
2
3
4
image: redis
image: redis:5
image: library/redis
image: registry.local:5000/redis

restart

指定服务重启策略,可选以下参数
no: 始终不重启,注意”no”需要使用双引号括起来以表示为字符串
always: 始终自动重启
on-failure: 容器启动失败时自动重启
unless-stopped: 当容器被手动停止或docker服务停止(或重启)时不重启容器

1
2
3
4
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

container_name

指定容器名称,默认为项目名_服务名_序号,如demo_webapp_1

1
container_name: webapp

ports

指定容器暴露的端口,格式为本地IP和端口:容器端口/协议

1
2
3
4
5
6
7
8
9
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"

network_mode

指定容器网络模式,可选以下参数
none: 不连接任何容器网络
host: 连接到主机网卡
service:[service name] 连接到指定服务

1
2
3
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"

networks

指定容器连接的网络

1
2
3
4
5
6
7
8
9
10
11
services:
webapp:
image: nginx:1.20.1
networks: front-net

db:
image: mysql:5.7
networks: front-net

networks:
front-net

volumes

指定数据卷挂载路径,格式为本地路径:容器路径:权限,权限可选ro,rw
本地路径支持指定为相对路径(相对于compose文件的路径)

1
2
3
4
5
6
7
8
9
services:
webapp:
image: nginx:1.20.1
volumes:
- webdata:/usr/share/nginx/html:ro
- ./logs:/var/logs/nginx

volumes:
webdata:

volumes_from

指定从其他服务容器挂载数据卷

1
2
3
4
5
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw

working_dir

指定容器中工作目录

1
working_dir: /data

deploy

指定服务部署和运行相关的配置,如负载策略,重启策略,资源分配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
services:
frontend:
image: awesome/webapp
ports:
- "8080:80"
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip
resources:
limits:
cpus: '0.50'
memory: 50M
pids: 1
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s

depends_on

指定服务依赖关系,即优先启动依赖的服务

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

command

覆盖容器启动后的默认命令,支持以下两种格式,推荐使用第二种和Dockerfile格式保持一致

1
2
3
command: nginx -g daemon off;
# or
command: ["nginx", "-g", "daemon off;"]

environment

指定容器环境变量,如果值为布尔值yes或no,1或0建议使用双引号”yes”表示,避免yaml自动转义
支持以下两种格式,推荐使用第二种

1
2
3
4
5
6
7
8
9
10
11
# Map syntax:
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:

# Array syntax:
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT

env_file

从文件中读取容器环境变量,注意.env文件的格式为VAR=VALUE

1
2
3
4
5
6
7
8
9
10
$ cat .env
IMAGE_VERSION=1.2.0
ENV=dev

$ cat docker-compose.yml
env_file: .env

env_file:
- ./comm.env
- ./dev.env

secrets

配置密码等安全信息,默认compose会加载配置文件到容器中的/run/secrets/

1
2
3
4
5
6
7
8
9
10
11
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret

secrets:
my_secret:
file: ./my_secret.txt

dns

指定DNS服务器

1
2
3
4
5
dns: 8.8.8.8
# or
dns:
- 8.8.8.8
- 114.114.114.114

指定DNS搜索域

1
2
3
4
5
dns_search: example.com
# or
dns_search:
- dc1.example.com
- dc2.example.com

entrypoint

指定CMD命令,将替换镜像默认的CMD指令

1
entrypoint: /data/entrypoint.sh

expose

指定容器运行时监听的端口,注意端口需要使用双引号括起来

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

extra_hosts

指定hosts主机名映射,默认会添加到容器的/etc/hosts文件中,注意格式为”主机名:容器IP”

1
2
3
extra_hosts:
- "nginx:172.17.10.10"
- "mysql:172.17.10.20"

healthcheck

指定健康检查策略,可选以下参数
test: 指定检查命令,注意格式
interval: 指定间隔时间
timeout: 指定超时时间
retries: 重试此书
start_period: 启动容器后多久开始检查

1
2
3
4
5
6
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s

labels

指定容器标签

1
2
3
4
labels:
desc="web server"
type=frontend
service=nginx

compose目录结构

docker-compose创建容器时会默认读取当前目录下的.env文件中的变量(如果文件存在的话),用于compose文件中的变量替换,变量名一般为大写,如MYSQL_PASSWD=admin
注意区分compose变量和容器的系统环境变量,后者需要通过env_file或environment标签来指定

1
2
3
4
5
6
docker-compose.yml  # 主配置文件
docker-compose-data.yml # 数据容器配置文件
data/ # 数据目录
conf/ # 配置目录
.env # 变量配置文件
README.md # 项目说明文件

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# alpine set timezone
1. apk add tzdata
2. export TZ=Asia/Shanghai

# alpine base
FROM alpine:3.13
ENV TZ=Asia/Shanghai
RUN addgroup -g 10001 -S nonroot \
&& adduser -u 10000 -S -G nonroot -h /home/nonroot nonroot
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache tini tzdata
USER nonroot
ENTRYPOINT ["/sbin/tini", "--"]

# TZ变量可以在构建镜像的Dockerfile中设置,也可以在运行容器时指定,按需选择
docker build -t test .
docker run -it --rm test date
docker run -it --rm -e TZ=Asia/Shanghai nginx:1.20.1-alpine date

####

考虑到服务镜像的通用性和代码安全性,不要将代码或配置文件直接ADD或COPY到服务镜像中,而是使用挂载或关联数据镜像的方式
挂载的话直接使用docker run -v local_path:container_path或者在compose文件中配置volumes标签
关联数据镜像的方式需要构建镜像,流程如下:
1.构建数据镜像,添加代码或配置到数据镜像中
2.通过数据镜像创建对应的数据容器,注意容器名称不能重复,建议指定为代码版本或添加时间标识
3.创建并运行服务容器,挂载数据容器中的volume
注意数据容器不需要启动,只需创建即可,服务容器在挂载时可以设置只读属性

docker命令关联数据镜像,需构建两个镜像data-image,service-image
docker create data-container
docker run -d service-container

docker-compose命令关联数据镜像,需配置两个compose文件docker-compose.yml,docker-compose-data.yml
docker-compose up --no-start -f docker-compose-data.yml
docker-compose up -d

注意需要定期清除宿主机上的数据卷目录
docker volume ls
docker volume prune -f
或者在删除容器时指定-v选项
docker rm -v data-container
docker-compose down -v

基础镜像: alpine,nginx等官方默认镜像
服务镜像: 修改后的基础镜像,如优化配置,添加自定义配置,符合当前环境要求,可随意组合使用
数据镜像: 专用于存储代码,配置文件,数据库等数据,用于提供给服务镜像调用

####

定义默认变量`${VARIABLE:-default}`
如下的${NGX_TAG:-1.20.1}表示如果没有定义变量NGX_TAG,则默认为1.20.1

$ cat .env
TAG=1.2.0

$ cat docker-compose.yml
version: "3.8"
services:
web:
image: "webapp:${TAG}"

nginx:
image: "nginx:${NGX_TAG:-1.20.1}"

使用NFS存储

1
2
3
4
5
6
7
8
9
10
11
12
services:
backend:
image: webapp:1.2.0
volumes:
- db-data:/data

volumes:
db-data:
driver_opts:
type: "nfs"
o: "addr=172.17.10.11,nolock,soft,rw,nfsvers=4"
device: ":/docker/db"

参考

https://docs.docker.com/compose/compose-file/
https://docs.docker.com/compose/environment-variables/
https://docs.docker.com/storage/
https://docs.docker.com/compose/faq/
https://kebingzao.com/2019/02/25/docker-volume/#%E6%8C%82%E8%BD%BD%E6%95%B0%E6%8D%AE%E5%8D%B7%E5%AE%B9%E5%99%A8