关于 dokploy-docker-compose
Dokploy Docker Compose Deployment Skill 提供在 Dokploy 上部署 Docker Compose 和 Docker Stack 服务的指导,面向配置部署、持久化文件、网络、域名、环境变量及健康检查的运维人员。
主要功能
- 01选择 Compose、Stack 或 Git 部署
- 02选择持久化卷和文件挂载方式
- 03配置环境变量加载
- 04设置域名和 Traefik 路由
- 05排查服务网络与健康检查问题
- 06参考部署及 init container 模式
适用场景
- 01将多服务 Compose 配置适配到 Dokploy
- 02在重新部署后保留应用数据
- 03通过域名路由已部署服务
- 04诊断 DNS、配置或健康检查故障
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trfi/ skills --skill dokploy-docker-compose安装后在 Claude Code 中输入/dokploy-docker-compose确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/healthchecks.mdinit-container-patterns.mdlibrechat-example.mdsignoz-example.mdsop-compose-deployment.mdsop-git-deployment.md详细介绍
Dokploy Docker Compose 部署技能
概述
Dokploy 是一个可自托管的部署平台,可在 VPS 上管理 Docker 容器。它支持两种 Compose 模式(Docker Compose 和 Docker Stack),并且需要遵循特定模式才能可靠运行。
快速决策树:
- 单仓库应用,带有
Dockerfile?→ 使用 Application (Git) 部署 - 预构建镜像或多服务栈?→ 使用 Compose 部署
- 需要公共 HTTPS 域名?→ 使用 Domains tab(Dokploy 会自动注入 Traefik 标签)
- 需要为每个应用隔离网络?→ 在 UI 中启用 Isolated Deployments
- 无需 SSH 即可提供配置文件?→ 在 Advanced → Mounts 中使用 File Mounts
- 需要生成配置文件并下载二进制文件的复杂服务栈?→ 使用 Init Containers 模式
第 1 部分:服务类型
Compose(Docker Compose 模式)
适用于:使用预构建镜像的多服务栈。行为与标准的 docker compose up 相同。
与本地运行相比的主要限制:
- 每次通过 AutoDeploy 部署都会执行
git clone,这会清空仓库目录——首次推送后,任何相对路径(如./config.yaml)都将为空或缺失 - 服务中绝不要使用
container_name:——它会破坏 Dokploy 的日志、指标和监控功能 - 相对绑定挂载(
./data)仅在首次部署时有效;请改用../files/或命名卷
Stack(Docker Swarm 模式)
用于编排部署的 Docker Stack 模式。与 Compose 模式的主要区别:
- 不支持
build:指令——必须使用来自镜像仓库的预构建镜像 - Traefik 标签必须放在
deploy.labels下,而不能直接放在labels下 - 使用副本和私有镜像仓库时,在 Advanced → Command 中添加
--with-registry-auth标志
Application(Git)部署
适用于:通过 Dockerfile 构建的源代码。
步骤:创建 Service → Application → Source: Git → Build Type: Dockerfile → 在 Advanced 中配置 Volumes 和 Ports。
第 2 部分:卷策略
⚠️ Dokploy 关键规则:绝对主机路径(例如 /opt/myapp/)会在部署期间被清理。绝不要使用它们。请改用 ../files/ 文件夹或命名卷。
命名卷(最适合数据库和大型数据)
services:
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
这些卷由 Docker 管理。支持通过 Dokploy 的 Volume Backups 功能进行自动备份。最适合数据库和大型数据集。
../files/ 绑定挂载(最适合配置文件和小型数据)
Dokploy 提供一个持久化的 ../files/ 文件夹,部署后仍会保留:
volumes:
- ../files/my-config:/etc/myapp/config ✅ persists across deploys
- ../files/my-database:/var/lib/mysql ✅ persists across deploys
- ./config.yaml:/app/config.yaml ❌ wiped on each AutoDeploy (git clone)
- /opt/myapp/data:/app/data ❌ absolute paths are cleaned up by Dokploy
无需直接访问主机文件。最适合配置文件和小型数据集。不支持备份。
VPS 上的主机路径:../files/ 会映射到主机上 Dokploy 项目目录内的 files/ 文件夹。首次部署后,要查找确切路径,请通过 SSH 登录并运行:
# Step 1: find your container name (Dokploy names them <stack>-<service>-1)
docker ps --format "table {{.Names}}\t{{.Image}}" | grep <service-keyword>
# Step 2: inspect that container to see where ../files/ maps on the host
docker inspect <container-name> | grep -A2 '"Source"'
或者查看 Dokploy UI 中的 Docker tab——其中会直接列出容器名称。
File Mounts(Dokploy UI — 用于直接粘贴配置内容)
在 Advanced → Mounts → Add Mount → File Mount 中:
- Content:粘贴文件文本
- File Path:仅填写文件名(例如
config.yaml) - Mount Path:完整的容器路径(例如
/app/config/config.yaml)
✅ 最适合:完全通过 Dokploy UI 管理的配置文件 ❌ 不适用于:二进制文件、需要在运行时生成的文件、大小超过几 KB 的文件
Init Container 模式(适用于需要生成配置文件的复杂服务栈)
如果服务栈需要在运行时写入多个配置文件,或下载二进制文件,请使用 alpine 初始化容器,在主服务启动前将文件写入共享命名卷:
services:
my-conf:
image: alpine:3.20
command:
- /bin/sh
- -lc
- |
cat > /config/app.yaml <<'YAML'
key: value
YAML
apk add --no-cache wget && wget -O /scripts/tool "https://..."
volumes:
- app-config:/config
- app-scripts:/scripts
restart: "no" # MUST exit after running
app:
depends_on:
my-conf:
condition: service_completed_successfully
volumes:
- app-config:/etc/app/
- app-scripts:/usr/local/scripts/
**Shell 转义:**在 Compose heredoc 中使用 $$——写作 $$(uname -s),而不是 $(uname -s)。
完整示例请参阅 references/init-container-patterns.md。
选择合适的卷方式
| 需求 | 方法 |
|---|---|
| 数据库数据 | 命名卷 |
| 自动备份到 S3 | 命名卷(唯一选项) |
| 配置文件 — 在 UI 中管理 | 文件挂载 |
| 配置文件 — 较大或较复杂 | ../files/ 绑定挂载 |
| 生成的配置 + 二进制文件 | Init 容器 → 命名卷 |
| ❌ 不要使用 | 绝对主机路径、./ 相对路径 |
第 3 部分:环境变量
Dokploy 如何处理环境变量
在 Environment 选项卡中设置的变量会写入与
docker-compose.yml 相同目录下的 .env 文件。它们不会自动注入容器。你必须在 Compose YAML 中使用以下两种方式之一显式加载这些变量:
选项 A — 加载所有变量(适用于变量较多的情况):
services:
app:
env_file:
- .env # loads every variable from Dokploy's Environment tab
选项 B — 选择特定变量:
services:
app:
environment:
- JWT_SECRET=${JWT_SECRET}
- DATABASE_URL=${DATABASE_URL}
- PORT=3000 # hardcoded values also work
⚠️ 如果使用 environment: 并显式指定变量,则只会传递列出的变量。
任何在 UI 中设置但未在此处列出的变量都会被静默忽略。
建议: 对于包含许多机密信息的堆栈(LibreChat 等),在每个需要这些变量的服务中使用 env_file: - .env。对于各服务需要不同变量子集的堆栈,则使用显式的 ${VAR} 引用。
生成安全值
openssl rand -hex 32 # 64-char hex string (for keys like CREDS_KEY)
openssl rand -hex 16 # 32-char hex string (for IVs like CREDS_IV)
第 4 部分:域名与 Traefik 路由
Dokploy 使用 Traefik 作为反向代理。通过域名公开服务有两种方式。
方法 1:Dokploy 域名 UI(推荐 — 自 v0.7.0 起)
进入你的服务 → Domains 选项卡 → Add Domain。Dokploy 会在部署时自动注入正确的 Traefik 标签到你的 compose 文件中。你无需手动处理这些标签。
⚠️ 先部署,再添加域名。 Domains 选项卡需要服务处于运行状态 — 首次部署前无法添加域名。
- 通过域名路由时,在 compose YAML 中使用
expose:(而不是ports:) - 使用 Preview Compose 按钮查看自动注入标签后的最终 compose 文件
- HTTPS:直接使用 DNS(A 记录 → VPS)时启用;使用 Cloudflare 代理时禁用(将 Cloudflare SSL/TLS 设为 Full)
services:
app:
image: myapp:latest
expose:
- 3000 # container-only; Traefik routes via domain, no host port needed
方法 2:手动添加 Traefik 标签(高级)
如需精细控制,可直接在 compose 文件中添加标签。需要连接到
dokploy-network(共享的 Traefik 网络):
services:
frontend:
image: myapp:latest
expose:
- 3000
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.my-unique-name.rule=Host(`app.yourdomain.com`)
- traefik.http.routers.my-unique-name.entrypoints=websecure
- traefik.http.routers.my-unique-name.tls.certResolver=letsencrypt
- traefik.http.services.my-unique-name.loadbalancer.server.port=3000
networks:
dokploy-network:
external: true
对于 Docker Stack — 标签需放在 deploy.labels 下:
services:
frontend:
image: myapp:latest
deploy:
labels:
- traefik.enable=true
- traefik.http.routers.my-app.rule=Host(`app.yourdomain.com`)
- traefik.http.services.my-app.loadbalancer.server.port=3000
networks:
- dokploy-network
隔离部署
在 Dokploy UI 中启用此功能(在 Compose 服务页面上切换开关),即可为堆栈创建自己的专用网络,而非共享 dokploy-network。此功能:
- 运行同一应用的多个实例时必需(例如,两个 WordPress 站点)
- 更安全 — 其他堆栈中的服务无法访问这些服务
- 自动完成 — Dokploy 会处理所有网络创建和 Traefik 配置
启用隔离部署后,无需手动添加 dokploy-network。
Dokploy 附带的所有开源模板默认都启用了此功能。
⚠️ 如果未启用隔离部署,则只有指定域名的服务会自动添加 dokploy-network。
除非手动添加,否则堆栈中的其他服务不会加入该网络。
第 5 部分:网络与 DNS(EAI_AGAIN 修复)
最常见的多服务错误:
getaddrinfo EAI_AGAIN mongodb
容器无法解析另一个服务的主机名。原因:竞争条件或 DNS 混淆。
修复方法 1 — 健康检查 + 正确的 depends_on(防止竞争条件):
services:
api:
depends_on:
mongodb:
condition: service_healthy # waits until healthy, not just started
mongodb:
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
retries: 5
start_period: 10s
修复方法 2 — 显式自定义网络(确保服务之间的 DNS 解析正常):
networks:
app-net:
driver: bridge
services:
api:
networks: [app-net]
mongodb:
networks: [app-net]
⚠️ 避免将 container_name: 用作 DNS 变通方案 — 这会破坏 Dokploy 的监控功能。
容器间通信请改用服务名称。
第 6 部分:健康检查
为每个依赖服务(数据库、缓存、队列)添加 healthcheck。对于需要这些依赖的服务,配合使用 depends_on: condition: service_healthy — 这可以防止服务在依赖项就绪前启动所导致的竞争条件。
示例:
services:
postgres:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
app:
depends_on:
postgres:
condition: service_healthy
第 7 部分:更新已部署的服务
手动更新(你不拥有的公共仓库)
- 前往 Deployments 选项卡 → 点击 Deploy
- 如果 Docker 缓存已过期:查找“Redeploy without Cache”,或在 System Settings 中清除 Build Cache
通过 Webhook 自动更新
- 从 Deployments 选项卡复制 Webhook URL
- 将其添加到 GitHub/GitLab/Gitea 仓库的 Settings → Webhooks
- 每次向该分支推送都会触发自动部署
第 8 部分:常见错误与修复方法
| 错误 | 原因 | 修复方法 |
|---|---|---|
getaddrinfo EAI_AGAIN <hostname> | 竞态条件 / DNS | 添加 healthcheck + condition: service_healthy;使用自定义网络 |
| 重新部署后配置文件为空 | ./ 相对路径被 git clone 清除 | 使用 ../files/ 绑定挂载或 UI 中的 File Mount |
JwtStrategy requires a secret or key | 未注入 JWT 环境变量 | 添加 env_file: - .env 或显式设置 - JWT_SECRET=${JWT_SECRET};Redeploy(不要用 Restart) |
ENOENT: no such file or directory | 配置文件未挂载 | 在 Advanced → Mounts 中使用 File Mount,或使用 ../files/ 绑定挂载 |
卷上的 permission denied | 旧卷属于其他用户 | 重命名卷(例如 data-v2),以强制重新创建 |
容器 is unhealthy | 镜像的 healthcheck 配置错误 | 根据镜像类型调整 healthcheck 命令;参见第 6 部分 |
| Dokploy 中缺少日志/指标 | 服务设置了 container_name: | 移除 container_name: —— 它会导致 Dokploy 监控失效 |
| 添加域名后服务无法互相发现 | 不在同一网络上 | 使用 Isolated Deployments,或手动将 dokploy-network 添加到所有服务 |
第 9 部分:参考文件
references/sop-compose-deployment.md— 适用于任何多服务 Compose 堆栈的分步 SOPreferences/sop-git-deployment.md— 使用 Dockerfile 从 Git 部署references/librechat-example.md— LibreChat:JWT 密钥、MongoDB DNS、librechat.yaml 挂载references/signoz-example.md— SigNoz:初始化容器、ClickHouse、Zookeeper 迁移references/init-container-patterns.md— 使用 heredocs 和二进制文件下载的初始化容器模式references/healthchecks.md— 常见服务的 healthcheck 片段
快速检查清单:调整任意 docker-compose.yml 以适配 Dokploy
- 移除所有
container_name:—— 会导致 Dokploy 日志和指标失效 - 将
./相对绑定挂载替换为../files/或命名卷 - 不要使用绝对主机路径(
/opt/...)—— 部署时会被清理 - 移除
user: "${UID}:${GID}"—— 会在 Dokploy 中导致权限错误 - 移除
env_file: - ./.env—— 文件将不存在;使用env_file: - .env(不带./)或${VAR}语法 - 添加
env_file: - .env,或为每个密钥显式引用${VAR}—— 环境变量不会自动注入 - 为所有数据库/依赖服务添加 healthcheck
- 更新
depends_on,使用condition: service_healthy,而不只是服务名称 - 对于域名:除非需要自定义 Traefik 配置,否则使用 Dokploy 的 Domains 选项卡(方法 1)
- 对通过 Traefik 域名路由的服务使用
expose:(而不是ports:) - 在文件底部声明所有命名卷