Docker Compose 的编写
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的强大工具。在现代软件开发中,应用程序往往由多个互相关联的服务组成,例如数据库、Web 服务器和后端服务等。Docker Compose 通过一个简单的 YAML 文件来描述这些服务,并提供了一键式启动、停止和管理整个应用的能力,使得开发、测试和部署变得更加简便和高效。
让我们开始这段 Docker Compose 的探索之旅,了解如何利用这一工具简化多容器应用的管理,提升效率和协作能力。🚀
常用内容
name: syncthing # 堆栈的名称
services: # 要使用的软件。固定格式。
Syncthing: # 服务的名称。没什么用,可以随便填。
image: lscr.io/linuxserver/syncthing # 镜像。指定了作者与软件
container_name: syncthing # 容器的名称
network_mode: host # 网络模式。
environment: # 环境变量。一种设定配置的方式。
- PUID=3000
- PGID=950
- TZ=Asia/Shanghai
volumes: # 卷的映射。将宿主机的文件或目录映射到容器中。
# 格式:外部卷:容器内路径
- /app/syncthing/config:/config
- mynfs:/mnt/nfs
ports: # 端口映射
# 格式 宿主机端口:容器端口/协议
- 8384:8384
restart: always # 重启策略
volumes: # 卷的另一种定义方式。可以实现更多功能。
mynfs:
external: true多容器堆栈
示例
name: brother
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:软件
services:
my-service:
image: lscr.io/linuxserver/syncthing:latest # 镜像image 用于确定要使用的软件和来源。
格式:仓库/作者/软件:版本。其中,软件是必要的,其它都是可选项目。要指定镜像仓库,则需要指定作者。
image: redis # 镜像名
image: ubuntu:14.04 # 镜像名:版本
image: estrellaxd/auto_bangumi # 作者/镜像名
image: my-registry.com:4000/postgresql # 仓库/作者/镜像名
image: a4bc65fd # 镜像id支持的格式。
环境变量
它是一种存储配置的方式。
services:
my-service:
environment: # 环境变量
- PUID=3000 # 用户ID
- PGID=950 # 组ID
- TZ=Asia/Shanghai # 时区另一种写法
services:
my-service:
environment:
PUID: 3000 # 用户ID
PGID: 950 # 组ID
TZ: Asia/Shanghai # 时区存储
Docker 的卷(Volume)是用于在容器之间共享和持久化数据的一种机制。它们提供了一种独立于容器生命周期的数据管理方式,使得数据在容器停止或删除后仍然能够保留。
背景
默认情况下,容器的数据不会被保存。这使得,在这些情况下,数据丢失:容器停止、重启系统、软件升级
为什么使用卷?
- 持久化数据:卷允许你持久化数据,即使容器被删除,数据也不会丢失。
- 共享数据:不同的容器可以共享同一个卷,方便实现数据共享和协作。
- 数据隔离:卷可以隔离数据,使得不同的应用和环境可以使用独立的数据存储。
services:
my-service:
volumes: # 卷的映射。将宿主机的文件或目录映射到容器中。
- /path/to/host:/config # 宿主机路径:容器内路径
- mynfs:/mnt/nfs # 卷的名称:容器内路径
- web_data:/usr/share/nginx/html
- db_data:/var/lib/mysql
- /path2:/config:ro # 只允许容器读取数据,不能写入
- /path3:/config:rw # 允许容器读取、写入数据
volumes: # 卷的另一种定义方式。可以实现更多功能。
web_data: # 简单定义
# 更多可选项
db_data:
name: custom_db_data # 卷的名称
volumes_3:
driver: local
driver_opts:
o: bind
device: /path/on/host
# 网络卷
mynfs:
driver_opts:
type: "nfs"
o: "addr=192.168.5.25,vers=4,nolock,soft,rw"
device: ":/mnt/pool_1/Main/"
my_smb:
driver_opts:
type: "cifs"
o: "addr=192.168.5.25,username=用户,password=密码,vers=3.0"
device: "//192.168.5.25/pool_1"
wai_bu: # 外部卷
external: true端口映射
功能:映射容器内的端口,到宿主机的端口
在网络模式模式为bridge时,外部不能主动访问容器内。这个功能可以解决此问题。通过此功能,还能使用自定义的端口,而不是软件默认监听的的端口。
services:
my-service:
network_mode: bridge # 网络模式
ports: # 端口映射
# 格式 宿主机端口:容器端口/协议
- 8384:8384
- 22000:22000/tcp
- 22000:22000/udp网络模式
services:
my-service:
network_mode: host # 网络模式区别
bridge: Docker 的默认网络模式,每个容器在启动时都会连接到一个桥接网络。容器之间可以通过容器名相互通信,但默认情况下,外部不能直接访问容器。它的本质是NAT,就像小区内的快递柜。host: 容器与宿主机共享网络栈。网络方面,效果和直接在宿主机运行相同。适用于需要高性能网络的场景,但会减少网络隔离。none: 容器不配置任何网络。容器内没有网络接口,只适用于不需要网络通信的场景。
网络相关
services:
my-service:
hostname: my-service # 主机名。没什么用。重启策略
services:
my-service:
restart: alwaysno:默认值,表示不会自动重启容器。如果容器停止或退出,它将保持停止状态。always:无论容器如何停止,都会自动重启。这意味着即使容器崩溃或手动停止,Compose 也会尝试重新启动它。on-failure:仅在容器以非零退出码退出时重启。你可以指定最大重启次数,例如on-failure:5表示容器最多重启五次。unless-stopped:除非容器被手动停止,否则会自动重启。这意味着如果容器崩溃,Compose 会尝试重新启动它,但如果你手动停止了容器,它将保持停止状态。
参数与入口点
services:
Watchtower:
command: --schedule "0 5 * * *" aria2 AriaNg yacd-meta Peer-Ban-Helper Home_Assistant AutoBangumi DDNS-Gocommand 的功能是传递参数
services:
web:
entrypoint: ["sh", "-c", 'apk add openssh && exec /app/ddns-go && "$@"']entrypoint 指容器开启时,启动软件的命令。它被指定时,效果是覆盖原有的entrypoint,而不是追加。
services:
jellyfin:
image: jellyfin/jellyfin
entrypoint: ["sh", "-c", 'apt update && apt install -y fonts-noto-cjk-extra && exec /jellyfin/jellyfin && "$@"']覆盖entrypoint,可以在启动软件前,安装其他的依赖,或做一些定制。
在这个示例中,先安装代号为fonts-noto-cjk-extra的字体,再启动软件。解决了问题:Jellyfin没有中文字体,导致中文显示为方框
交互式的终端环境
services:
web:
stdin_open: true # 开启标准输入
tty: true # 分配为伪终端docker exec -it 容器名称 sh # 连接容器的 shell这两个选项通常一起使用,以确保容器能够提供一个交互式的终端环境,适合调试或运行需要用户输入的应用程序。通常使用场景:需要在容器启动后,立刻在其中执行命令。
资源限制
Docker 允许用户对容器,限制、预留CPU、内存。因此,可以更容易地管理资源。
services:
web:
deploy:
resources:
limits: # 资源限制
cpus: "0.50" # 多可以使用 0.5 个CPU核心
memory: "512M" # 最多可以使用 512MB 的内存。
reservations: # 资源保留
cpus: "0.25" # 保留 0.25 个CPU核心
memory: "256M" # 保留 256MB 的内存。cpus:单位:1 CPU核心。例子:宿主的 CPU 有 6 核,要使用全部资源的50%,则值应为3;它的最大值为6。
拉取策略
此策略告诉Compose如何处理镜像拉取:
services:
my-service:
pull_policy: alwayspull_policy的选项:
- always: 每次启动服务时都会拉取镜像。
- missing: 如果服务启动时本地没有该镜像,则会拉取镜像。
- never: 强制使用本地存在的镜像,不会进行任何拉取操作。
- if_not_present: 如果镜像本地不存在则会拉取,但如果本地已经有这个镜像,即使不是最新的也不会进行更新。
注意事项
- 使用
--pull always或pull_policy: always可能会导致更新时由于镜像变化过大而产生兼容性问题或服务中断,所以生产环境中要慎用,确保更新的镜像与现有应用兼容。 - 使用
pull_policy是一种更细粒度的控制,可以为每个服务独立设置更新策略。 - 确保你的环境变量以及其它依赖的配置是与新的镜像更新兼容的。
扩展功能
secrets
定义可以被服务使用的全局机密(仅适用于Compose v3.1+):
secrets:
my-secret:
file: ./my_secret.txtconfigs
定义可以在服务之间共享的配置(仅适用于Compose v3.1+):
configs:
my-config:
file: ./my_config.txt扩展标签
docker-compose.yml可以包含一些全局设置,允许你为整个文件应用某些配置:
- x-default-env-file: 指定一个环境文件,所有的服务都将默认读取这个文件中的环境变量
x-default-env-file:
- .envx-default-pull_policy: 拉取策略
x-default-pull_policy: always- x-default-logging: 设置一个全局的日志记录配置,这是被所有服务继承,除非单个服务有自己的特殊设置:
x-default-logging: &global-logging
driver: syslog
options:
syslog-address: "udp://127.0.0.1:123"
tag: 'something'
services:
web:
image: myimage
logging: *global-logging- x-default-ports: 在某些版本中,你可以定义一个默认的端口映射策略,它将自动应用于所有适用的服务:
x-default-ports:
- 'target: 80, published: 8080'- x-default-networks: 为所有服务添加默认网络:
x-default-networks:
- default- x-default-volumes: 定义可以在服务中使用的全局卷:
x-default-volumes:
- data:/data
volumes:
data:
...WARNING
需要注意的是,像x-*这样的用户定义的扩展字段都是非标准的,所以它们在不同的Docker Compose版本中可能有不同的支持方式或被忽略。在使用这些扩展功能时,请检查你的Docker Compose版本和官方支持的功能,确保你使用的标签是有效的。