问题描述
在使用 Dokploy 部署应用时,你可能会遇到项目中的服务之间无法互相访问的问题。
例如,在一个 Dokploy 项目中:
- 使用 Dokploy 的预置数据库功能创建了一个 MySQL 数据库
- 使用 Docker Compose 部署了一个 Ghost 博客程序
此时,Ghost 应用的日志中会报告无法解析 MySQL 的主机名,导致数据库连接失败。
Error: getaddrinfo ENOTFOUND xxx-mysql-7eegrt
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)
问题原因
这个故障的根本原因是 容器网络隔离。
在 Dokploy 中:
- 通过预置数据库部署的 MySQL 容器会自动接入
dokploy-network网络 - 使用 Docker Compose 部署的应用默认会创建一个独立的专用网络,网络名称通常为
<项目名>_default
由于两个容器分别位于不同的 Docker 网络中,它们之间无法直接通过容器名或服务名进行通信。这就像两个人在不同的局域网中,无法直接访问对方一样。
解决方案
解决这个问题的关键是 让 Docker Compose 部署的应用加入到 dokploy-network 网络。
配置步骤
在你的 Docker Compose 配置文件中,需要做两个修改:
- 在服务定义中添加网络配置:在
services部分的应用配置中,添加networks字段,指定使用dokploy-network - 声明外部网络:在配置文件的顶层添加
networks部分,声明dokploy-network为外部网络
完整配置示例
以 Ghost 博客为例,完整的 Docker Compose 配置如下:
services:
ghost:
image: ghost:5.129.0-alpine
ports:
- 2368
environment:
NODE_ENV: production
url: https://xxx.com
database__client: mysql
database__connection__host: xxx-mysql-7eegrt
database__connection__user: ghost
database__connection__password: xxx
database__connection__database: ghost
volumes:
- /root/xxx/data:/var/lib/ghost/content
networks:
- dokploy-network
networks:
dokploy-network:
external: true
配置说明
服务网络配置
services:
ghost:
# ... 其他配置
networks:
- dokploy-network
在服务定义中添加 networks 字段,指定容器要加入的网络。这里指定为 dokploy-network,这样 Ghost 容器启动后就会连接到这个网络。
外部网络声明
networks:
dokploy-network:
external: true
在顶层的 networks 部分声明网络配置:
external: true表示这是一个外部网络,即该网络不是由当前 Docker Compose 创建的,而是已经存在的网络- Docker Compose 在启动时会检查
dokploy-network是否存在,如果不存在则会报错
验证网络连接
配置完成后,你可以通过以下方式验证容器是否成功加入网络:
1. 查看容器网络
docker inspect <容器名或ID> | grep -A 10 Networks
输出应该包含 dokploy-network:
"Networks": {
"dokploy-network": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"ghost",
"xxx"
],
...
}
}
2. 测试网络连通性
进入 Ghost 容器测试是否能够解析 MySQL 主机名:
# 进入容器
docker exec -it <ghost容器名> sh
# 测试 DNS 解析
ping xxx-mysql-7eegrt
# 测试 MySQL 端口连通性
nc -zv xxx-mysql-7eegrt 3306
如果能够正常解析和连接,说明网络配置成功。
其他注意事项
1. 数据库主机名
在 Dokploy 中创建的数据库,其主机名通常是 <项目名>-<服务名>-<随机字符> 的格式。你可以在 Dokploy 控制面板中查看具体的主机名。
2. 端口配置
当容器在同一个 Docker 网络中时:
- 内部通信使用容器的内部端口(如 MySQL 的 3306)
- 外部访问需要通过映射的主机端口
在上面的配置中,ports: - 2368 表示将容器的 2368 端口映射到主机的随机端口,Dokploy 会自动处理外部访问的路由。
3. 多网络配置
如果你的应用需要连接多个网络,可以这样配置:
services:
myapp:
networks:
- dokploy-network
- custom-network
networks:
dokploy-network:
external: true
custom-network:
driver: bridge
4. 网络隔离最佳实践
虽然将所有服务放在同一个网络中可以解决互访问题,但从安全角度考虑:
- 生产环境建议根据服务职责划分不同的网络
- 只有需要通信的服务才放在同一个网络中
- 敏感服务(如数据库)应该尽量限制网络访问范围
总结
Dokploy 中容器无法互访的问题本质上是 Docker 网络隔离机制导致的。通过在 Docker Compose 配置中:
- 在服务定义中添加
networks: - dokploy-network - 声明
dokploy-network为外部网络
就可以让不同方式部署的容器加入同一个网络,实现相互访问。这是在 Dokploy 中进行容器编排时需要特别注意的配置细节。
作者: TorchTree
原文地址: https://torchtree.com/post/dokploy-container-network-issue/
发布时间: 2025-11-17
版权声明: CC BY-NC-SA 4.0