Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,您可以从您的配置中创建并启动所有服务。
一个简单的docker-compose.yml文件如下:
version: "3.9" # 从 v1.27.0 之后可选
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Compose 使用项目名称将环境彼此隔离。您可以在几个不同的上下文中使用此项目名称:
默认项目名称是项目目录的基本名称。您可以使用 -p
命令行选项或 COMPOSE_PROJECT_NAME
环境变量设置自定义项目名称。
默认项目目录是 Compose 文件的基本目录。可以使用--project-directory
命令行选项定义它的自定义值。
Compose 会保留您的服务使用的所有卷。运行时docker-compose up
,如果它找到以前运行的任何容器,它会将卷从旧容器复制到新容器。此过程可确保您在卷中创建的任何数据都不会丢失。
Compose 缓存用于创建容器的配置。当您重新启动未更改的服务时,Compose 会重新使用现有容器。重复使用容器意味着您可以非常快速地更改您的环境。
Compose 支持 Compose 文件中的变量。您可以使用这些变量为不同的环境或不同的用户定制您的组合。
可以在 shell 中使用环境变量来填充 Compose 文件中的值:
web:
image: "webapp:${TAG}"
如果您有多个环境变量,您可以通过将它们添加到名为的默认环境变量文件.env
或使用--env-file
命令行选项提供环境变量文件的路径来替换它们。
${VARIABLE:-default} # VARIABLE 未设值或者未空,则使用默认值:default
+v1.28 以上可以使用 .env 环境变量配置文件
$ cat .env
TAG=v1.5
$ cat docker-compose.yml
version: '3'
services:
web:
image: "webapp:${TAG}"
当运行时docker-compose up
,web
上面定义的服务使用该图像webapp:v1.5
。
shell 中的值优先于.env
文件中指定的值。
$ export TAG=v2.0
$ docker-compose config
version: '3'
services:
web:
image: "webapp:v2.0"
通过将文件作为参数传递,您可以将其存储在任何地方并适当命名,例如.env.ci
。使用以下选项传递文件路径:.env.dev
.env.prod
--env-file
$ docker-compose --env-file ./config/.env.dev up
使用’environment’ key在服务的容器中设置环境变量 ,就像使用 docker run -e VARIABLE=VALUE ...
:
web:
environment:
- DEBUG=1
您可以使用’env_file’ 选项将多个环境变量从外部文件传递到服务的容器,就像使用docker run --env-file=FILE ...
:
web:
env_file:
- web-variables.env
在下面的示例中,我们在 Environment 文件和 Compose 文件上设置了相同的环境变量:
cat ./Docker/api/api.env
NODE_ENV=test
cat docker-compose.yml
version: '3'
services:
api:
image: 'node:6-alpine'
env_file:
- ./Docker/api/api.env
enviroment:
- NODE_ENV: production
运行容器时,Compose 文件中定义的环境变量优先。
docker-compose exec api node
# process.env.NODE_ENV -> 'production'
profile允许通过选择性地启用服务来针对各种用途和环境调整 Compose 应用程序模型。这是通过将每个服务分配给零个或多个配置文件来实现的。如果未分配,则始终启动服务,但如果已分配,则仅在激活配置文件时才启动。
version: "3.9"
services:
frontend:
image: frontend
profiles: ["frontend"]
phpmyadmin:
image: phpmyadmin
depends_on:
- db
profiles:
- debug
backend:
image: backend
db:
image: mysql
在这里,服务frontend
和phpmyadmin
被分配给配置文件 frontend
和 debug
仅在启用它们各自的配置文件时才启动。
$ docker-compose --profile debug up
$ COMPOSE_PROFILES=debug docker-compose up
上述命令都将在debug
启用配置文件的情况下启动您的应用程序。
$ docker-compose --profile frontend --profile debug up
$ COMPOSE_PROFILES=frontend,debug docker-compose up
都将会启动 frontend 和 phpmyadmin
当一个已分配的服务profiles
在命令行上明确定位时,它的配置文件将自动启用,因此您无需手动启用它们。这可用于一次性服务和调试工具。例如,考虑以下配置:
version: "3.9"
services:
backend:
image: backend
db:
image: mysql
db-migrations:
image: backend
command: myapp migrate
depends_on:
- db
profiles:
- tools
# will only start backend and db
$ docker-compose up -d
# this will run db-migrations (and - if necessary - start db)
# by implicitly enabling profile `tools`
$ docker-compose run db-migrations
默认情况下,Compose 会为您的应用程序设置一个 网络。服务的每个容器都加入默认网络,并且可以被该网络上的其他容器访问,并且可以通过与容器名称相同的主机名被它们**发现。
例如,假设您的应用位于名为 的目录中myapp
,并且您的docker-compose.yml
外观如下所示:
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
ports:
- "8001:5432"
运行docker-compose up
时,会发生以下情况:
myapp_default
。web
的配置创建容器。myapp_default
它以 名义加入网络 web
。db
的配置创建容器。myapp_default
它以 名义加入网络 db
。每个容器现在都可以查找主机名web
或db
取回相应容器的 IP 地址。例如,web
的应用程序代码可以连接到 URLpostgres://db:5432
并开始使用 Postgres 数据库。
在web
容器内,您的连接字符串db
看起来像 postgres://db:5432
,而在主机上,连接字符串看起来像postgres://{DOCKER_IP}:8001
。
如果您对服务进行配置更改并运行docker-compose up
以更新它,旧容器将被删除,新容器以不同的 IP 地址但同名加入网络。正在运行的容器可以查找该名称并连接到新地址,但旧地址停止工作。
如果任何容器与旧容器的连接打开,它们将被关闭。检测这种情况、再次查找名称并重新连接是容器的责任。
链接允许您定义额外的别名,通过这些别名可以从另一个服务访问服务。它们不需要启用服务进行通信 - 默认情况下,任何服务都可以使用该服务的名称访问任何其他服务。在以下示例中,db
可从web
主机名db
和访问database
:
version: "3.9"
services:
web:
build: .
links:
- "db:database"
db:
image: postgres
除了(或同时)指定您自己的网络,您还可以通过在networks
named下定义一个条目来更改应用程序范围的默认网络的设置default
:
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
参考:https://docs.docker.com/compose/extends/
version: "3.9"
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
depends_on:
- db