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启动设置,Redis和Postgres容器就可以正常运行,但Web应用程序和Sidekiq的容器会因为无法连接Redis而无法连接到redis:9002.值得注意的是,如果我使用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容器无法建立连接.
我在MacOS上使用这个docker版本:
Docker版本1.12.3,构建6b644ec,实验性的
我有什么想法我做错了吗?我很感激任何暗示如何让我的设置运行.
最佳答案
当您绑定像’9002:6379’这样的端口时,您告诉Docker转发来自localhost的流量:9002 – > Redis的:6379.这就是为什么这适用于您的主机:
redis-cli -h localhost -p 9002 -n 0
但是,当容器相互通信时,默认情况下它们都连接到同一网络(Docker桥或docker0).默认情况下,容器可以在此网络上自由地相互通信,而无需打开任何端口.在此网络中,您的redis容器正在侦听通常端口上的流量(6379),主机根本不参与.这就是为什么容器到容器的通信工作在6379上的原因.