问题描述
在尝试通过容器连接到CouchDB时遇到问题,他的应用无法看到CouchDB。然而,如果使用外部地址 123.456.789.123:12345
(server_ip:external_port
),它可以工作,但他需要通过内部端口 5986
在网络上进行连接。
以下是他的Docker-Compose配置文件:
version: '3'
services:
couchdb:
image: couchdb:latest
restart: always
volumes:
- couchdb-data-volume:/usr/local/var/lib/couchdb
env_file: .env.docker
ports:
- "12345:5986"
networks:
app-net:
aliases:
- couchdb
app:
build: .
image: app
restart: always
depends_on:
- couchdb
env_file: .env.docker
networks:
app-net:
driver: bridge
volumes:
couchdb-data-volume:
他还提供了一个环境变量文件 .env.docker
,内容如下:
NODE_ENV=production
COUCHDB_SERVER=http://user:pass@couchdb:5986
COUCHDB_USER=user
COUCHDB_PASSWORD=pass
他尝试使用 links
替代网络,但问题依然存在:
links:
- couchdb
他寻求解决方法。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
最佳解决方案
问题出在您没有将 app 服务注册到 app-net 网络上。要让容器能够相互连接,它们必须共享一个网络,并使用镜像名称作为域名。Docker 提供了网络内部的 DNS 服务。
您需要做以下更改来修复这个问题:
在 app
服务中,添加 container_name: app
来设置容器名称。
同时,将 app
服务注册到 app-net
网络中,将 networks:
部分调整如下:
version: '3'
services:
couchdb:
# ... 其他配置 ...
networks:
app-net:
aliases:
- couchdb
app:
build: .
image: app
container_name: app
restart: always
depends_on:
- couchdb
env_file: .env.docker
networks:
- app-net
volumes:
couchdb-data-volume:
networks:
app-net:
在 app
服务中,现在可以使用 http://couchdb:5986
来访问 couchdb
服务。您可以使用以下命令在 app
服务内部测试这一点:docker exec -it app bash
,这取决于 container_name
的设置。
备选解决方案
另一种方法是使用脚本或工具来控制容器的启动顺序。您可以使用 docker run
命令手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。以下是一个简单的 Bash 脚本示例,可以在容器 A 启动后启动容器 B:
#!/bin/bash
# 启动容器 A
docker run -d --name container_a your_image_a
# 等待容器 A 完全启动
while ! docker exec container_a echo "Container A is ready"; do
sleep 1
done
# 启动容器 B
docker run -d --name container_b your_image_b
在这个示例中,我们首先使用 docker run
命令启动容器 A,并将其命名为 container_a
。然后,使用一个循环来等待容器 A 完全启动(这里是通过在容器内运行 echo
命令来测试)。一旦容器 A 就绪,我们再使用 docker run
命令启动容器 B,并将其命名为 container_b
。
以上是两种解决方案,您可以根据您的需求选择其中之一来解决您的问题。