docker-compose:容器之间的连接被拒绝,但是可以从主机访问服务

TL; DR:为了让一个容器在一个自定义(非标准)端口上使用另一个容器的服务,我该如何改变下面docker-compose.yml

我有一个非常普通的设置:Web应用程序(Padrino [Ruby]),Postgres,Redis和排队框架(Sidekiq)的容器。 Web应用程序随附自定义Dockerfile,其余服务来自标准图像(Postgres,Redis),或者从Web应用程序(Sidekiq)装载数据。 他们通过以下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: 

这里要注意的一点是,我公开了非标准端口上的容器服务(9000-9002)。

如果我用docker-compose up进行设置,Redis和Postgres容器就可以正常工作,但是Web应用程序和Sidekiq的容器却无法通过redis:9002连接到Redis。 值得注意的是,如果我使用6379(标准Redis端口)而不是9002,相同的设置工作

docker ps也看起来很好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 

更令人困惑的是:我可以通过redis-cli -h localhost -p 9002 -n 0 从主机访问Redis容器,但是Web应用程序和Sidekiq容器无法build立连接。

我在MacOS上使用这个docker版本: Docker version 1.12.3, build 6b644ec, experimental

任何想法我做错了什么? 我将不胜感激任何提示如何让我的设置运行。

当你像这样绑定端口'9002:6379'你告诉Docker从localhost:9002 – > redis:6379转发stream量。 这就是为什么这可以在你的主机上运行:

 redis-cli -h localhost -p 9002 -n 0 

但是,当容器互相通信时,默认情况下它们都连接到同一个networking(Docker网桥 docker0 )。 默认情况下,容器可以在这个networking上自由地相互通信,而不需要打开任何端口。 在这个networking中,你的redis容器正在监听通常的端口( 6379 )的stream量,根本不涉及主机。 这就是为什么你的容器通信到6379