Docker-compose学习

Docker Compose 文件解释

Compose 文件是一个 YAML 格式的文件,

  • 后缀可以为 .yml.yaml

有三个 Top-level 顶级 key :(其他 key 都是这三个 key 的子主题 sub-topics)

  • services
  • networks
  • volumes

默认命名文件为: docker-compose.yml

  • 这样 docker-compose up -d 时,会自动读取所在目录下的该文件;

services

services 的作用:

定义服务启动需要的配置,这些配置作用于服务所在容器上。

  • 需要自定义一个服务名,可以通过指定服务名来启动特定服务。

  • 可以定义多个 service;

compose 文件中支持使用 环境变量替换

具体查看后面章节

image

指定启动容器需要的镜像

例如:

1
2
3
4
# 最新版本
image: redis
# 指定特定版本的镜像
image: ubuntu:22.04

container_name

自定义容器名,而不是默认生成。

  • 如果不通过该 key 自定义一个容器名,那么 docker-compose 启动的容器会自动生成一个容器名。

command

会覆盖 image 的默认命令,当需要覆盖 container 启动后的默认命令时设置该 key。

语法

1
command: 命令

样例:

1
command: 

depends_on

表示服务间的依赖关系。

  • docker-compose up 启动时,会根据依赖关系启动服务,例如,dbredis 会在 web 之前启动;
  • docker-compose up SERVICE 启动服务时,会自动启动服务的依赖,例如,docker-compose up web 时会自动创建并启动 dbredis
  • docker-compose stop 停止服务时,会根据依赖顺序反向停止服务。例如,web 会先停止,然后才是 dbredis

依赖的样例:

1
2
3
4
5
6
7
8
9
10
11
version: "3"
services:
web:
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

labels

  • 添加 metadata 到指定的image中,用于启动 container 。

    • 就像是命令行程序及支持配置文件,又支持指定命令行参数一样;

    • key 推荐使用反向DNS表示法;

    • 有两种书写方式:

      • array
      • dictionary
      1
      2
      3
      4
      5
      6
      7
      labels:
      com.example.department: "Finance"
      xxxx: "xxxx"

      labels:
      - "com.example.department=Finance"
      - "xxxx=xxx"

entrypoint

覆盖 image 的默认 entrypoint,

1
2
3
entrypoint: /code/entrypoint.sh
或者使用 list 的形式,类似于 Dockerfile 文件格式
entrypoint: ["php", "-d", "memory_list=-1","vender/bin/entrypoint"]

注意,设置 entrypoint 既可以覆盖 image 在 Dockerfile 设置的默认 entrypoint,又可以清除 image 中设置的所有命令(即当 Dockerfile 中设置了 CMD,如果设置了 entrypoint 这个 key 后,文件中设置的 CMD 命令会被清除)。

env_file

指定环境变量所在文件,可以是单个文件,也可以是 list。

注意,当通过 docker-compose -f FILE 指定 compose 文件时,env_file 的文件需要是相对于 compose 文件的相对路径。

1
2
3
4
5
6
7
env_file: .env

或者是 list
env_file:
- ./common.env
- ./apps/web.env
- /opt/runtime_opts.env

env 文件的格式为:

KEY=value 的形式,一行一个,

# 号后的内容为注释,

空行忽略,

注,如果值需要有特殊字符例如#,那么整个 value 需要使用双引号"" 包裹起来。

注意: 如果 env_file 的值是一个 list ,那么需要注意文件的加载顺序,从上到下加载,如果不同文件出现相同的 变量 KEY,那么后面出现的值会覆盖前面出现的值。

environment

与 env_file 的效果一样,添加环境变量,不过这里是通过 map 形式或者 array 形式。

1
2
3
4
5
6
# map 的形式 key:value
environment:
RACK_ENV: development
# 注意,如果是 boolean 值,即 true,false,yes,no,需要使用括号包裹起来,防止 YAML 解析器将其解析成 True 或 False 的形式。
SHOW: 'true'
SESSION_SECRET:
1
2
3
4
5
6
# array 的形式 key=value
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET

expose

暴露端口,但是仅用于 linked 服务可以访问,并不对宿主机暴露,仅用于内部端口访问?

  • 问题:这与处于相同 network 不对外暴露的区别是什么?
1
2
3
expose:
- "3000"
- "8000"

external_links

链接到在该 docker-compose 之外启动的容器。特别是对于提供共享或公共服务的容器。

  • 主要作用是容器间通信

  • 与 links 作用类似,作用范围不同。

    • links 是同一个 docker-compose 文件中的 services 之间链接;
    • external_links 是链接外部容器;
1
2
3
4
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
  • 如果使用 network,所有主机加入相同的 network,则可以不使用 links 方式了。

extra_hosts

在启动容器的 /etc/hosts 文件中添加域名解析映射。

1
2
3
4
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"

networks

使容器加入指定的网络,使用的 value 为顶级 key networks 中定义的网络。

  • 可以添加多个网络;
1
2
3
4
5
services:
web:
networks:
- some-network
- other-network

ipv4_address,ipv6_address

允许当容器加入到指定 network 时,给容器设定静态 IP 地址。

同时,需要在顶级key networks 章节添加 ipam 块,保证设置的子网包含指定的静态 IP 地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: "3.9"

services:
app:
image: nginx:alpine
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10

networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
- subnet: "2001:3984:3989::/64"

ports

对外暴露端口

注意,端口映射不支持 network_mode: host

运行 docker-compose run 命令时,需要指定 --service-ports, 否则会忽略 ports 参数设置。

有两种书写形式,short 语法 和 long 语法

short syntax:

  • 指定端口(HOST:CONTAINER);
  • 仅指定容器的端口(此时主机端口是非固定端口);
  • 指定主机IP地址:端口IPADDR:HOSTPORT:CONTAINERPORT 。如果HOSTPORT 为空,例如(127.0.0.1::80),此时主机端口也是非固定的。

注意,因为 YAML 解析器的xx:yy 的形式是基于 60 的,端口绑定时 < 60 会出现异常,所以建议所有端口绑定时,使用字符串形式。

样例:

1
2
3
4
5
6
7
8
9
10
11
12
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"
- "127.0.0.1::5000"
- "6060:6060/udp"
- "12400-12500:1240"

Docker compose 使用默认的 bridge 网络

结论:compose 中的 service 无法使用默认的 bridge 网络进行通信,必须使用用户自定义的网络,外部定义或者 compose 中定义均可。

报错:compose 中使用 docker 默认的 bridge 网络,会出现如下报错:

Network-scoped alias is supported only for containers in user defined networks

原因

  1. compose 依赖网络范围的别名,如果使用外部的 bridge 网络,compose 仍然会尝试设置别名,但是网络别名只能设置在用户定义的网络上,默认的网络是不能设置别名的,所以会报错。
  2. 如果打算设置 network_mode 来关闭 compose 内置的别名功能,也是不行的,因为默认的 bridge 中无法设置别名,同时也不存在默认的别名,service 间的网络通信依赖于别名,所以依然行不通。

常用 docker-compose 命令

1
2
3
4
5
6
7
8
root@www:/home/spoon/devops/docker-traefik# docker-compose stop
Stopping docker-traefik_whoami_1 ... done
root@www:/home/spoon/devops/docker-traefik# docker-compose rm
Going to remove docker-traefik_reverse-proxy_1, docker-traefik_whoami_1
Are you sure? [yN] y
Removing docker-traefik_reverse-proxy_1 ... done
Removing docker-traefik_whoami_1 ... done

1
2
3
4
5
6
root@www:/home/spoon/devops/docker-outline-main# docker network ls
NETWORK ID NAME DRIVER SCOPE
6d5a02e468d1 bridge bridge local
8d594ba232c7 host host local
224c32b61f84 none null local
cc728494b8a4 traefik_ipv6 bridge local
1
2
3
root@www:/home/spoon/devops/docker-outline-main# docker network rm traefik_ipv6
traefik_ipv6

1
2
3
root@www:/home/spoon/devops/docker-outline-main# docker network create -d bridge --ipv6 --subnet "fd00:db8:ddee::/80" outline
1acbe0461302b6856c5c1ed79c54fc0f452d4eae16f695c0fc9a3228b2266067

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
root@www:/home/spoon/devops/docker-outline-main# docker network inspect outline
[
{
"Name": "outline",
"Id": "1acbe0461302b6856c5c1ed79c54fc0f452d4eae16f695c0fc9a3228b2266067",
"Created": "2022-05-05T16:48:48.584158563+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.21.0.0/16",
"Gateway": "172.21.0.1"
},
{
"Subnet": "fd00:db8:ddee::/80"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信