docker-compose:连接在容器之间拒绝,但服务可以从主机访问 [英] docker-compose: connection refused between containers, but service accessible from host
问题描述
TL; DR:如何更改我的下面 docker-compose.yml
,以便允许一个容器使用另一个容器通过自定义(非我有一个很常见的设置:一个web应用程序的容器(Padrino [Ruby]),Postgres,Redis和一个排队框架(Sidekiq) 。网络应用程序附带自定义的Docker文件,其余的服务来自标准图像(Postgres,Redis),或从Web应用程序(Sidekiq)安装数据。他们通过以下 docker-compose.yml
绑定在一起:
版本:'2'
服务:
web:
build:。
命令:'bundle exec puma -C config / puma.rb'
卷:
- 。/ / myapp
ports:
- 9000:3000
depends_on:
- postgres
- redis
sidekiq:
build:。
命令:'bundle exec sidekiq -C config / sidekiq.yml -r ./config/boot.rb'
volumes:
- 。:/ myapp
depends_on:
- postgres
- redis
postgres:
image:postgres:9.5
环境:
POSTGRES_USER:my-postgres-user
POSTGRES_PASSWORD:my-postgres-pass
ports:
- '9001:5432'
volumes:
- 'postgres:/ var / lib / postgresql / data'
redis:
image:redis
ports:
- '9002:6379'
volumes:
- 'redis:/ var / lib / redis /数据'
卷:
redis:
postgres:
这里要注意的一个关键点是我正在使用非标准端口(9000-9002)的容器服务。
如果我使用 docker-compise up
开始安装,Redis和Postgres容器会很好,但是web应用程序和Sidekiq的容器因为无法连接到Redis在 redis:9002
而失败。值得注意的是,如果我使用6379(标准的Redis端口)而不是9002,则相同的设置工作。
docker ps
也看起来很好afaik:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9148566c2509 redisdocker-entrypoint.sh不到一秒钟上传大约一分钟0.0.0.0:9002->6379/tcp rubydockerpadrino_redis_1
e6d47321c939 postgres:9.5/docker-entrypoint.s不到一秒钟前大约一分钟0.0.0.0:9001->5432/tcp rubydockerpadrino_postgres_1
更令人困惑的是:我可以通过 redis-cli -h localhost -p 9002 -n 0
从主机访问Redis容器,但Web应用程序和Sidekiq容器无法建立连接。
我正在使用这个MacOS上的docker版本:
Docker版本1.12.3,构建6b644ec,实验
任何想法我做错了吗我很感激任何提示如何让我的设置运行。
当您绑定这样的端口 '9002:6379'
你正在告诉Docker从 localhost:9002
- > redis:6379
。这就是为什么这可以从您的主机运行:
redis-cli -h localhost -p 9002 -n 0
但是,当容器相互通信时,它们都默认连接到同一个网络(Docker bridge 或 docker0
)。默认情况下,容器可以在该网络上自由地互相通信,而不需要打开任何端口。在这个网络中,您的 redis
容器正在监听通常的端口( 6379
)上的流量,主机不涉及在所有这就是为什么你的容器到集装箱通讯工作在 6379
。
TL;DR: How do I have to change my below docker-compose.yml
in order to allow one container to use a service of another over a custom (non-standard) port?
I have a pretty common setup: containers for a web app (Padrino [Ruby]), Postgres, Redis, and a queueing framework (Sidekiq). The web app comes with its custom Dockerfile, the remaining services come either from standard images (Postgres, Redis), or mount the data from the web app (Sidekiq). They are ties together via the following docker-compose.yml
:
version: '2'
services:
web:
build: .
command: 'bundle exec puma -C config/puma.rb'
volumes:
- .:/myapp
ports:
- "9000:3000"
depends_on:
- postgres
- redis
sidekiq:
build: .
command: 'bundle exec sidekiq -C config/sidekiq.yml -r ./config/boot.rb'
volumes:
- .:/myapp
depends_on:
- postgres
- redis
postgres:
image: postgres:9.5
environment:
POSTGRES_USER: my-postgres-user
POSTGRES_PASSWORD: my-postgres-pass
ports:
- '9001:5432'
volumes:
- 'postgres:/var/lib/postgresql/data'
redis:
image: redis
ports:
- '9002:6379'
volumes:
- 'redis:/var/lib/redis/data'
volumes:
redis:
postgres:
One key point to notice here is that I am exposing the containers services on non-standard ports (9000-9002).
If I start the setup with docker-compose up
, the Redis and Postgres containers come up fine, but the containers for the web app and Sidekiq fail since they can't connect to Redis at redis:9002
. Remarkably enough, the same setup works if I use 6379 (the standard Redis port) instead of 9002.
docker ps
also looks fine afaik:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9148566c2509 redis "docker-entrypoint.sh" Less than a second ago Up About a minute 0.0.0.0:9002->6379/tcp rubydockerpadrino_redis_1
e6d47321c939 postgres:9.5 "/docker-entrypoint.s" Less than a second ago Up About a minute 0.0.0.0:9001->5432/tcp rubydockerpadrino_postgres_1
What's even more confusing: I can access the Redis container from the host via redis-cli -h localhost -p 9002 -n 0
, but the web app and Sidekiq containers fail to establish a connection.
I am using this docker version on MacOS:
Docker version 1.12.3, build 6b644ec, experimental
Any ideas what I am doing wrong? I'd appreciate any hint how to get my setup running.
When you bind ports like this '9002:6379'
you're telling Docker to forward traffic from localhost:9002
-> redis:6379
. That's why this works from your host machine:
redis-cli -h localhost -p 9002 -n 0
However, when containers talk to each other, they are all connected to the same network by default (the Docker bridge or docker0
). By default, containers can communicate with each other freely on this network, without needing any ports opened. Within this network, your redis
container is listening for traffic on it's usual port (6379
), host isn't involved at all. That's why your container to container communication works on 6379
.
这篇关于docker-compose:连接在容器之间拒绝,但服务可以从主机访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!