Docker создает сопоставление портов

У меня есть файл yml для docker-compose, как показано ниже

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

Моя цель состоит в том, чтобы переместить nodejs-127.0.0.1 порт 6379 на узел redis. Я уже могу выполнить ping redis с машины nodejs, но порты не отображаются. Пробовал варианты раскрытия, но никаких шансов тоже.

Ответы

Ответ 1

Если вы хотите привязать порт redis к контейнеру nodejs, вам нужно будет открыть этот порт в контейнере redis:

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

  redis:
    build:
      context: .
      dockerfile: Dockerfile-redis
    expose:
      - "6379"

Тег expose позволит вам открывать порты, не публикуя их на главной машине, но они будут отображаться в сетях контейнеров.

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

Тег ports будет отображать хост-порт с портом контейнера HOST: CONTAINER

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

Ответ 2

Важно отметить, что все вышеперечисленные решения сопоставляют порт с каждым интерфейсом на вашей машине. Это нежелательно, если у вас есть общедоступный IP-адрес или ваш компьютер имеет IP-адрес в большой сети. Ваше приложение может быть представлено гораздо более широкой аудитории, чем вы ожидали.

redis:
  build:
    context:
    dockerfile: Dockerfile-redis
    ports:
    - "127.0.0.1:3901:3901"

127.0.0.1 - это IP-адрес, который сопоставляется с именем хоста localhost на вашем компьютере. Так что теперь ваше приложение доступно только через этот интерфейс, и поскольку 127.0.0.1 доступен только через вашу машину, вы не открываете свои контейнеры всему миру.

Документация объясняет это далее и может быть найдена здесь: https://docs.docker.com/compose/compose-file/#ports


Примечание. Если вы используете Docker для Mac, контейнер будет слушать 127.0.0.1 на Docker для Mac VM и не будет доступен с вашего локального хоста. Если я правильно помню.

Ответ 3

Кажется, что другие ответы здесь все неправильно поняли ваш вопрос. Если я правильно понимаю, вы хотите отправлять запросы на 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"]

Наконец, нам нужно настроить переадресацию портов в cmd.sh. Я обнаружил, что nc, даже с -l и -k, иногда прерывается, когда запрос завершается, поэтому я использую опцию while -l, чтобы гарантировать, что он всегда работает.

# 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

Ответ 4

Если вы хотите получить доступ к redis с хоста (127.0.0.1), вы должны использовать команду ports.

redis:
  build:
    context: .
    dockerfile: Dockerfile-redis
    ports:
    - "6379:6379"