Docker组成端口映射

z.a*_*.a. 42 docker docker-compose

我有一个docker-compose yml文件,如下所示

version: '2'
services:
  nodejs:
    build:
      context: .
      dockerfile: DockerFile
    ports:
      - "4000:4000"
    links:
      - redis
    expose:
      - "6379"
  redis:
    build:
      context: .
      dockerfile: Dockerfile-redis
Run Code Online (Sandbox Code Playgroud)

我的目标是将nodejs-127.0.0.1端口6379转发到redis主机.我已经可以从nodejs机器ping redis,但是没有映射端口.尝试暴露选项,但也没有机会.

Jes*_*oco 55

如果要从nodejs容器绑定到redis端口,则必须在redis容器中公开该端口:

version: '2'
services:
  nodejs:
    build:
      context: .
      dockerfile: DockerFile
    ports:
      - "4000:4000"
    links:
      - redis

  redis:
    build:
      context: .
      dockerfile: Dockerfile-redis
    expose:
      - "6379"
Run Code Online (Sandbox Code Playgroud)

expose标签会让你暴露的端口没有它们发布到主机,但他们将被暴露在容器网络.

https://docs.docker.com/compose/compose-file/#expose

ports标签将映射与容器端口的主机端口HOST:集装箱

https://docs.docker.com/compose/compose-file/#ports

  • 好吧,这是因为它们在不同的主机/容器上运行。您能否检查是否使用问题解决的`redis:6379`而不是`127.0.0.1:6379`? (3认同)

Bre*_*dly 36

重要的是要指出所有上述解决方案都将端口映射到计算机上的每个接口.如果您拥有公共IP地址,或者您的计算机在大型网络上具有IP,则这不太理想.您的应用程序可能会暴露给比您希望的更广泛的受众.

redis:
  build:
    context:
    dockerfile: Dockerfile-redis
    ports:
    - "127.0.0.1:3901:3901"
Run Code Online (Sandbox Code Playgroud)

127.0.0.1是映射到计算机上主机名的IP地址localhost.因此,现在您的应用程序仅通过该界面公开,因为127.0.0.1只能通过您的计算机访问,所以您不会将容器暴露给整个世界.

文档进一步解释了这一点,可以在这里找到:https://docs.docker.com/compose/compose-file/#ports

  • Kudo 为安全预防。 (9认同)
  • 知道 HOST:PORT 映射在群模式下不起作用非常重要。比打开端口更好的是“公开”端口,然后通过地址 redis:3901 连接到它(这仅可用于同一网络中的其他容器) (3认同)

Isa*_*esh 11

看来这里的其他答案都误解了您的问题。如果我理解正确的话,您希望向 localhost:6379 (redis 的默认值)发出请求,并将它们自动转发到 redis 容器上的同一端口。

https://unix.stackexchange.com/a/101906/38639帮助我找到了正确的答案。

首先,您需要nc在映像上安装该命令。在 CentOS 上,此软件包称为 nmap-ncat,因此在下面的示例中,如果您使用不同的操作系统作为基础映像,只需将其替换为适当的软件包即可。

接下来,您需要告诉它在每次容器启动时运行某个命令。您可以使用 CMD 来完成此操作。

# Add this to your Dockerfile
RUN yum install -y --setopt=skip_missing_names_on_install=False nmap-ncat
COPY cmd.sh /usr/local/bin/cmd.sh
RUN chmod +x /usr/local/bin/cmd.sh
CMD ["/usr/local/bin/cmd.sh"]
Run Code Online (Sandbox Code Playgroud)

最后,我们需要在 cmd.sh 中设置端口转发。我发现nc,即使使用-l-k选项,偶尔也会在请求完成时终止,因此我使用 while 循环来确保它始终运行。

# cmd.sh
#! /usr/bin/env bash

while nc -l -p 6379 -k -c "nc redis 6379" || true; do true; done &

tail -f /dev/null # Or any other command that never exits
Run Code Online (Sandbox Code Playgroud)


Ant*_*hon 6

如果redis要从主机(127.0.0.1)访问,必须使用该ports命令。

redis:
  build:
    context: .
    dockerfile: Dockerfile-redis
    ports:
    - "6379:6379"
Run Code Online (Sandbox Code Playgroud)

  • 嗯,恐怕这也行不通。这对于将端口暴露给 Nodejs 容器来说不是必需的。ports:向实际主机公开端口。我想将 rdis 6379 端口映射到 nodejs 6379 端口。 (2认同)