Docker Compose
如果您正在使用基于 Docker Compose 的部署方式,您需要了解 Docker Compose 如何与 Coolify 配合工作。
在所有情况下,Docker Compose (docker-compose.y[a]ml) 文件是唯一的真实来源。
定义环境变量
Coolify 会识别您在 compose 文件中提到的环境变量,并在其 UI 中显示它们。
services:
myservice:
environment:
- SOME_HARDCODED_VALUE=hello # 会传递给容器,但在 Coolify 的 UI 中不可见
- SOME_VARIABLE=${SOME_VARIABLE_IN_COOLIFY_UI} # 创建一个未初始化的环境变量,可在 Coolify 的 UI 中编辑
- SOME_DEFAULT_VARIABLE=${OTHER_NAME_IN_COOLIFY:-hello} # 创建一个值为 "hello" 的环境变量,可在 Coolify 的 UI 中编辑
必需的环境变量
Coolify 支持使用 Docker Compose 的内置语法将环境变量标记为必需。此功能通过在启动服务前验证关键配置来改善部署体验。
语法
使用 :? 语法将变量标记为必需:
services:
webapp:
environment:
# 必需变量 - 必须设置,无默认值
- DATABASE_URL=${DATABASE_URL:?}
# 必需变量带默认值 - 预填充但可编辑
- PORT=${PORT:?3000}
# 可选变量带默认值 - 标准 Docker Compose 行为
- DEBUG=${DEBUG:-false}主要行为:
- 必需变量 (
${VAR:?}) 在环境变量列表中首先出现,为空时显示红色边框 - 必需变量带默认值 (
${VAR:?default}) 预填充默认值但仍然可编辑 - 可选变量 (
${VAR:-default}) 使用标准 Docker Compose 行为
如果在部署期间未设置必需变量:
- Coolify 会在 UI 中突出显示缺失的变量
- 部署将被阻止,直到提供所有必需变量
- 清晰的错误消息指导用户修复配置
此验证在容器创建之前进行,防止部分部署和运行时失败。
Coolify 的魔法环境变量
此外,Coolify 还可以为您生成一些动态环境变量。 语法为 SERVICE_<TYPE>_<IDENTIFIER>。 类型可以是以下之一:
- FQDN:这将生成服务的 FQDN(完全限定域名)。下面的示例展示了如何添加路径和端口。
- URL:根据您定义的 FQDN 生成 URL。
- USER:使用
Str::random(16)生成随机字符串。您可能希望将其用作服务中的用户名。 - PASSWORD:使用
Str::password(symbols: false)生成密码。使用PASSWORD_64可生成 64 位长的密码,使用Str::password(length: 64, symbols: false)。 - BASE64:使用
Str::random(32)生成随机字符串。对于更长的字符串,请使用BASE64_64或BASE64_128。 - REALBASE64:使用
base64_encode(Str::random(32))对随机生成的字符串进行编码。对于更长的字符串,请使用REALBASE64_64或REALBASE64_128。
每个生成的变量都可以重用,并且对于每个服务始终具有相同的值。 所有生成的变量都会显示在 Coolify 的环境变量 UI 中,并且可以在那里编辑(FQDN 和 URL 除外)。
例如,假设有一个 UUID 为 vgsco4o 的应用程序(由 Coolify 在创建时生成)。 它使用一个 compose 文件在通配符域名 http://example.com 上部署 Appwrite。
services:
appwrite:
environment:
# http://appwrite-vgsco4o.example.com/v1/realtime
- SERVICE_FQDN_APPWRITE=/v1/realtime
# _APP_URL 将拥有 FQDN,因为 SERVICE_FQDN_APPWRITE 只是一个简单的环境变量
- _APP_URL=$SERVICE_FQDN_APPWRITE
# http://appwrite-vgsco4o.example.com/ 将被代理到端口 3000
- SERVICE_FQDN_APPWRITE_3000
# http://api-vgsco4o.example.com/api 将被代理到端口 2000
- SERVICE_FQDN_API_2000=/api
# Coolify 生成密码并将其作为 SERVICE_SPECIFIC_PASSWORD 注入到容器中
- SERVICE_SPECIFIC_PASSWORD=${SERVICE_PASSWORD_APPWRITE}
not-appwrite:
environment:
# 与 Appwrite 服务中的值相同
- APPWRITE_PASSWORD=${SERVICE_PASSWORD_APPWRITE}
# 由于 SERVICE_FQDN_API 与 SERVICE_FQDN_APPWRITE 不同
# Coolify 将生成一个新的 FQDN
# http://not-appwrite-vgsco4o.example.com/api
- SERVICE_FQDN_API=/api存储
您可以在 compose 文件中正常预定义存储,但有一些额外的选项可以设置,以告诉 Coolify 如何处理存储。
创建空目录
# 预定义带有主机绑定的目录
services:
filebrowser:
image: filebrowser/filebrowser:latest
volumes:
- type: bind
source: ./srv
target: /srv
is_directory: true # 这将告诉 Coolify 创建目录(这在普通 docker-compose 中不可用)创建包含内容的文件
在这里,您可以看到如何添加一个包含内容和来自环境变量的动态值的文件。
services:
filebrowser:
image: filebrowser/filebrowser:latest
environment:
- POSTGRES_PASSWORD=password
volumes:
- type: bind
source: ./srv/99-roles.sql
target: /docker-entrypoint-initdb.d/init-scripts/99-roles.sql
content: |
-- 注意:在生产环境中更改为您自己的密码
\set pgpass `echo "$POSTGRES_PASSWORD"`
ALTER USER authenticator WITH PASSWORD :'pgpass';
ALTER USER pgbouncer WITH PASSWORD :'pgpass';从健康检查中排除
如果您有一个服务不想包含在整体健康检查中,可以通过将 exclude_from_hc 选项设置为 true 来将其从健康检查中排除。
提示
例如,如果您有一个迁移服务,它只运行一次然后容器停止,这很有用。
services:
some-service:
exclude_from_hc: true
...连接到预定义网络
默认情况下,每个 compose 堆栈都部署到一个单独的网络中,网络名称为您的资源 UUID。这将允许您堆栈中的每个服务相互通信。
但在某些情况下,您可能希望与账户中的其他资源通信。例如,您可能希望将应用程序连接到部署在另一个堆栈中的数据库。
要做到这一点,您需要在 服务堆栈 页面上启用 连接到预定义网络 选项,但这会使内部 Docker DNS 无法正常工作。
举个例子:假设您有一个包含 postgres 数据库和 laravel 应用程序的堆栈。Coolify 会将您的 postgres 堆栈重命名为 postgres-<uuid>,将您的 laravel 堆栈重命名为 laravel-<uuid>,以防止名称冲突。
如果您在 laravel 堆栈上设置 连接到预定义网络 选项,您的 laravel 应用程序将能够连接到您的 postgres 数据库,但您需要使用 postgres-<uuid> 作为数据库主机。
原始 Docker Compose 部署
您可以设置项目使用 docker compose 构建包直接部署您的 compose 文件,而无需 Coolify 的大部分魔法功能。这称为 原始 Compose 部署。
注意
这适用于高级用户。如果您不熟悉 Docker Compose,我们不建议使用此方法。
标签
Coolify 仍会向您的应用程序添加以下标签(如果它们未设置):
labels:
- coolify.managed=true
- coolify.applicationId=5
- coolify.type=application要使用 Coolify 的代理(Traefik),您需要为应用程序设置以下标签:
labels:
- traefik.enable=true
- "traefik.http.routers.<unique_router_name>.rule=Host(`coolify.io`) && PathPrefix(`/`)"
- traefik.http.routers.<unique_router_name>.entryPoints=http