2016-11-05 602 views
2

TL; DR:如何修改我的docker-compose.yml以允许一个容器使用另一个服务通过自定义(非标准)港口?docker-compose:容器之间的连接被拒绝,但服务可以从主机访问

我有一个很常见的设置: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的redis:9002。值得注意的是,如果我用6379(标准Redis的端口)工作而不是9002

docker ps相同的设置也看起来很好,据我所知:

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的来自主机的容器通过redis-cli -h localhost -p 9002 -n 0,但Web应用程序和Sidekiq容器无法建立连接。

我使用在MacOS此泊坞窗版本: Docker version 1.12.3, build 6b644ec, experimental

任何想法我做错了吗?我很感激任何提示如何让我的设置运行。

回答

4

当你像这样绑定端口'9002:6379'时,你告诉Docker转发来自localhost:9002 - >redis:6379的流量。这就是为什么这从您的主机的工作原理:

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

然而,当容器相互交谈,他们都在默认情况下(在泊坞桥docker0)连接到同一个网络。默认情况下,容器可以在此网络上互相通信免费,而不需要打开任何端口。在这个网络中,您的redis容器正在监听通常的端口上的流量(6379),主机根本不参与。这就是为什么你的集装箱到集装箱通信的原因是6379

+0

你钉了它!非常感谢你指点我的部分(端口映射,它将端口转发给主机,但不是内部容器)我直到现在才被误解。现在它工作了! :) – crn

+0

当您可能有多个容器在内部侦听同一端口并且需要在本地主机上重新映射时,映射非常有用。由于每个容器是分开的,所以在容器到容器中不存在问题。还有一些设置可以关闭容器之间的通信,还可以创建其他网络而不是默认连接容器。请记住接受答案,如果它的工作:) – johnharris85

相关问题