Docker Compose
如果您使用基于 Docker Compose 的部署,您需要了解 Docker Compose 如何与 Coolify 配合工作。
在所有情况下,Docker Compose(docker-compose.y[a]ml)文件都是唯一的事实来源。 这意味着您通常在 Coolify UI 中配置的各种设置(如环境变量、存储等)都需要直接在 compose 文件中定义。
使服务对外可见
当 Coolify 部署 Docker Compose 时,它会为部署中的服务创建一个网络。此外,它还会添加代理服务,以便能够从新网络中访问这些服务。
这意味着您可以通过以下几种方式使您的服务对外可用:
域名
Coolify 加载您的 compose 文件后,会列出所有服务并允许您分配域名。如果您的服务监听 80 端口,分配域名就足以让代理找到它们并将流量路由过去。如果它们监听其他端口,请将端口号添加到域名中。
例如,如果您的应用监听(容器)端口 80,并且希望运行在 example.com 上,请在域名字段输入 http://example.com(或 https://)。
然而,如果您的应用监听(容器)端口 3000,则需要在相关服务中填写 http://example.com:3000。此处的端口仅告诉 Coolify 将流量发送到容器内的哪个位置;代理仍会将此服务通过标准端口对外提供(在此例中为 http://example.com 的 80 端口)。
如果您想进一步自定义基于域名的路由,请参阅下方的 Coolify 的魔法环境变量。
服务端口映射
如果您希望通过主机端口直接访问您的服务,请在 compose 文件中添加 ports 属性。例如,将容器端口 3000 直接映射到宿主机:
services:
backend:
image: your-backend:latest
ports:
- "3000:3000"请注意,如果这样做,您的服务将在服务器的 3000 端口上直接暴露,不受任何代理配置的控制。这可能不是您想要的!如果您在开发和部署中使用同一个 Docker Compose 文件,这可能会意外暴露您本不想公开的私有服务端口。
可选地,您可以传入 IP 地址,将端口绑定到宿主机的特定网络接口:
services:
backend:
image: your-backend:latest
ports:
- "127.0.0.1:3000:3000"这将使您的服务仅在服务器的 localhost:3000 上可用。
私有或内部服务
如果您不映射服务端口或分配域名,Coolify 将不会在私有网络之外暴露您的服务。此时,您可以按照 Docker Compose 的常规方式进行引用。
例如,如果您有两个服务,名称如下:
services:
backend:
image: your-backend:latest
auth:
image: your-auth:latest然后,您可以从 backend 通过 http://auth:1234(或相应端口)连接到 auth。同样,auth 也可以通过 http://backend:3000(或相应端口)连接到 backend。
更多详细信息,请参阅 Docker Compose 网络文档。
定义环境变量
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} # 会在 Coolify 的 UI 中创建一个值为 "hello" 的可编辑环境变量
必填环境变量
Coolify 支持使用 Docker Compose 的内置语法将环境变量标记为必填。此功能通过在启动服务前验证关键配置来改善部署体验。
您可以使用 :? 语法将环境变量标记为必填。必填变量必须在部署前设置,如果为空,将在 Coolify 的 UI 中以红色边框高亮显示。
services:
myapp:
environment:
# 必填变量 - 如果未设置,部署将失败
- DATABASE_URL=${DATABASE_URL:?}
- API_KEY=${API_KEY:?}
# 带默认值的必填变量 - 在 UI 中预填,但可以更改
- PORT=${PORT:?3000}
- LOG_LEVEL=${LOG_LEVEL:?info}
# 可选变量 - 标准行为
- DEBUG=${DEBUG:-false}
- CACHE_TTL=${CACHE_TTL:-3600}关键行为:
- 必填变量 (
{VAR:?}) 会出现在环境变量列表的顶部,若为空则显示红色边框 - 带默认值的必填变量 (
{VAR:?default}) 会预填默认值,但仍可编辑 - 可选变量 (
{VAR:-default}) 遵循标准的 Docker Compose 行为
如果在部署期间未设置必填变量:
- Coolify 将在 UI 中高亮显示缺失的变量
- 部署将被阻止,直到提供所有必填变量
- 清晰的错误提示将引导用户修复配置
此验证发生在容器创建之前,可防止部分部署和运行时故障。
共享环境变量
Coolify 不会直接检测 compose 文件中的共享环境变量,但可以通过额外步骤进行引用。
-
按照 共享变量文档 创建您的共享变量。
-
在您的 Docker Compose 文件中定义变量,例如:
services:
myservice:
environment:
- HARD_CODED=dev # 会传递给容器,但不会显示在 Coolify 的 UI 中。
- SOME_OPTIONAL_VARIABLE=${SOME_VARIABLE_IN_COOLIFY_UI} # 会在 UI 中创建一个可编辑的未初始化变量。
volumes:
- data-persist:/var/data
volumes:
data-persist:
device: /mnt/serverstorage/${SOME_VARIABLE_IN_COOLIFY_UI} # 复用该变量- 在应用程序的“环境变量”中显式定义该变量,引用您在第 1 步中创建的共享变量;
如果您在开发者视图中,可以这样输入:
SOME_VARIABLE_IN_COOLIFY_UI={{environment.SOME_SHARED_VARIABLE}}或者在普通视图中,“名称”对应 Docker Compose 文件中引用的 SOME_VARIABLE_IN_COOLIFY_UI,而“值”则是引用的环境变量 {{environment.SOME_SHARED_VARIABLE}},如下图所示。保存正确后,您会看到第三个文本框,展开它即可看到实际值,在此例中为 SOME_VALUE。
Coolify 的魔法环境变量
Coolify 可以使用以下语法为您生成动态环境变量:SERVICE_<TYPE>_<IDENTIFIER>。类型可以是以下之一:
| 类型 | 生成的值 |
|---|---|
URL | 基于您的通配符域名生成的 URL。下方示例展示了如何添加路径和端口。 |
FQDN | 基于生成的 URL 生成的完全限定域名 (FQDN)。下方示例展示了如何添加路径和端口。 |
USER | 随机字符串,16 个字符。 |
PASSWORD | 不含特殊符号的随机密码。 |
PASSWORD_64 | 不含特殊符号的随机密码,64 个字符。 |
PASSWORDWITHSYMBOLS | 含特殊符号的随机密码。 |
PASSWORDWITHSYMBOLS_64 | 含特殊符号的随机密码,64 个字符。 |
BASE64 或 BASE64_32 | 随机字符串,非 Base64 编码,32 个字符。 |
BASE64_64 | 随机字符串,非 Base64 编码,64 个字符。 |
BASE64_128 | 随机字符串,非 Base64 编码,128 个字符。 |
REALBASE64 或 REALBASE64_32 | Base64 编码的随机字符串,32 个字符。 |
REALBASE64_64 | Base64 编码的随机字符串,64 个字符。 |
REALBASE64_128 | Base64 编码的随机字符串,128 个字符。 |
HEX_32 | 十六进制随机字符串,32 个字符。 |
HEX_64 | 十六进制随机字符串,64 个字符。 |
HEX_128 | 十六进制随机字符串,128 个字符。 |
标识符命名
标识符使用下划线 (_) 时,不能在环境变量中使用端口。请改用连字符 (-) 以避免此限制。
SERVICE_URL_APPWRITE_SERVICE_3000 ❌
SERVICE_URL_APPWRITE-SERVICE_3000 ✅每个生成的变量都可以重复使用,并且对所有服务始终保持相同的值。 所有生成的变量都会显示在 Coolify 的环境变量 UI 中,并可以在那里进行编辑(FQDN 和 URL 除外)。
例如,假设有一个 UUID 为 vgsco4o 的应用程序(由 Coolify 在创建时生成)。
它使用一个 compose 文件,在 通配符 域名 http://example.com 上部署 Appwrite 。
这将执行以下操作:
services:
appwrite:
environment:
# http://appwrite-vgsco4o.example.com
- SERVICE_URL_APPWRITE
# http://appwrite-vgsco4o.example.com/v1/realtime
- SERVICE_URL_APPWRITE=/v1/realtime
# _APP_URL 将包含 FQDN,因为 SERVICE_URL_APPWRITE 只是一个普通的环境变量
- _APP_URL=$SERVICE_URL_APPWRITE
# http://appwrite-vgsco4o.example.com/ 将被代理到 3000 端口
- SERVICE_URL_APPWRITE_3000
# DOMAIN_NAME 将包含 FQDN (appwrite-vgsco4o.example.com),因为 SERVICE_FQDN_APPWRITE 会生成完整的 FQDN。无需在变量末尾添加 3000
- DOMAIN_NAME=${SERVICE_FQDN_APPWRITE}
# http://api-vgsco4o.example.com/api 将被代理到 2000 端口
- SERVICE_URL_API_2000=/api
# Coolify 生成密码并将其作为 SERVICE_SPECIFIC_PASSWORD 注入到容器中
- SERVICE_SPECIFIC_PASSWORD=${SERVICE_PASSWORD_APPWRITE}
# Coolify 生成一个 64 字符的不含特殊符号的密码
- LONG_PASSWORD=${SERVICE_PASSWORD_64_APPWRITE}
# Coolify 生成一个 64 字符的含特殊符号的密码
- SYMBOL_PASSWORD=${SERVICE_PASSWORDWITHSYMBOLS_64_APPWRITE}
# Coolify 生成一个 64 字符的 Base64 编码随机字符串
- ENCRYPTION_KEY=${SERVICE_REALBASE64_64_APPWRITE}
# Coolify 生成一个 64 字符的十六进制随机字符串
- HEX_SECRET=${SERVICE_HEX_64_APPWRITE}
not-appwrite:
environment:
# 复用 Appwrite 服务的密码。
- APPWRITE_PASSWORD=${SERVICE_PASSWORD_APPWRITE}
# 由于 SERVICE_URL_API 与 SERVICE_URL_APPWRITE 不同
# Coolify 将生成一个新的 URL
# http://not-appwrite-vgsco4o.example.com/api
- SERVICE_URL_API=/api基于 Git 源的 Compose 文件中的魔法环境变量支持需要 Coolify v4.0.0-beta.411 或更高版本。
存储
您可以在 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/firebrowser:latest
environment:
- POSTGRES_PASSWORD=password
volumes:
- type: bind
source: ./srv/99-roles.sql
target: /docker-entrypoint-initdb.d/init-scripts/99-roles.sql
content: | # 这将告诉 Coolify 创建文件(普通 docker-compose 中不可用)
-- 注意:在生产环境中请更改为您自己的密码
\set pgpass `echo "$POSTGRES_PASSWORD"`
ALTER USER authenticator WITH PASSWORD :'pgpass';
ALTER USER pgbouncer WITH PASSWORD :'pgpass';或者,您可以使用 Docker Compose 中的顶级元素 configs 来创建配置文件。
services:
filebrowser:
image: filebrowser/filebrowser:latest
environment:
- POSTGRES_PASSWORD=password
configs:
- source: roles
target: /docker-entrypoint-initdb.d/init-scripts/99-roles.sql
configs:
roles:
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。这将允许堆栈中的各个服务相互通信。
但在某些情况下,您可能希望与账户中的其他资源进行通信。例如,您希望将应用程序连接到部署在另一个堆栈中的数据库。
为此,您需要在 Service Stack(服务堆栈)页面上启用 Connect to Predefined Network(连接到预定义网络)选项,但这会导致内部 Docker DNS 无法按预期工作。
以下是一个示例。您有一个包含 postgres 数据库和 laravel 应用程序的堆栈。Coolify 会将您的 postgres 堆栈重命名为 postgres-<uuid>,将 laravel 堆栈重命名为 laravel-<uuid>,以防止名称冲突。
如果您在 laravel 堆栈上设置了 Connect to Predefined Network 选项,您的 laravel 应用程序将能够连接到 postgres 数据库,但您需要使用 postgres-<uuid> 作为数据库主机。
原始 Docker Compose 部署
您可以将项目配置为使用 docker compose build pack,以便直接部署您的 compose 文件,而无需使用 Coolify 的大部分自动化功能。这被称为 Raw Compose Deployment(原始 Compose 部署)。
注意
此功能面向高级用户。如果您不熟悉 Docker Compose,我们不推荐使用此方法。
标签 (Labels)
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