Доступ к родственной службе из службы контейнера докеров

Я запускаю контейнер Docker на основе образа Node (терминал быстрого запуска Docker из Windows)

FROM node:7.8.0
ENV NPM_CONFIG_LOGLEVEL warn

VOLUME /tmp
#copy server source /piu contains node server and /piu/client contains react+redux client
ADD piu /piu
ADD server_start.sh /

#clean windows \r char to make the .sh file real executable
RUN sed -i -e 's/\r$//' server_start.sh

CMD ./server_start.sh

EXPOSE 3000 3009

Я запускаю клиент Node (на порту 3000) и сервер Node (на основе Express) (на порту 3009). Клиент обращается к серверу REST через вызов AJAX.

componentDidMount() {
    const that = this;
    console.log('SERVER_URL=' + SERVER_URL); //the output is localhost:3009
    axios
        .get(SERVER_URL + '/posts')
        .then(res => {
            that.setState({pageInfo: res.data});
        })
        .catch(err => {
            console.log(err)
        })
}

Он отлично работает с хоста (клиент обращается к localhost: 3009 и возвращает результаты). И я могу позвонить по номеру: 3009 и снова получить правильные результаты.

Но когда я создаю и запускаю образ докера, он терпит неудачу.

docker run -p 3000-3009:3000-3009 --add-host="mongodb:192.168.12.151" MyDockerImage

--add-host используется для доступа к базе данных mongo, работающей на хосте.

Порт сервера 3009 открыт, поэтому у меня есть рабочий трюк для вызова

192.168.99.100:3009 //the docker IP and exposed port

вместо localhost:3009, но было бы неплохо разрешить клиенту доступ к серверу непосредственно внутри контейнера.

Как правильно указать localhost внутри контейнера докеров для доступа к родственному сервису?

ОБНОВИТЬ

#!/bin/bash

# Start the first process (server)
npm run start_docker --prefix piu &
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_first_process: $status"
  exit $status
fi

# Start the second process (client)
npm run start --prefix piu/client
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_second_process: $status"
  exit $status
fi

person StanislavL    schedule 06.09.2017    source источник


Ответы (1)


Есть несколько вещей, которые вы можете сделать здесь

Разрешить запуск другого контейнера в сети другого контейнера

docker run --net container:<id> MyDockerImage

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

Создайте сеть самостоятельно и используйте ее

docker network create myapps

docker run --name mongodb_service --net myapps mongodb
docker run -p 3000-3009:3000-3009 --net myapps MyDockerImage

Теперь внутри вашего MyDockerImage доступ к mongodb можно получить по адресу mongodb_service.

Использовать docker compose

Вы можете использовать docker-compose для запуска их обоих как композиции.

version: '3'
services:
  mongo: 
    image: mongodb
  app:
    build:
      context: .
    ports:
      - "3000-3009:3000-3009"

И теперь в приложении mongodb будет доступен с именем mongo

person Tarun Lalwani    schedule 06.09.2017
comment
Проблема вовсе не в mongodb. Я успешно получаю доступ к монго. Проблема заключается в доступе к одному сервису из другого. Оба работают в одном контейнере. Я пробовал docker-compose иметь отдельную ссылку imkage для монго, но это не имеет значения. Предположим, у меня вообще нет монго. Все, что мне нужно, это вызвать localhost:3009 из localhost:3000 (оба в одном контейнере) - person StanislavL; 06.09.2017
comment
каково содержание /server_start.sh - person Tarun Lalwani; 06.09.2017
comment
Файл добавлен - person StanislavL; 06.09.2017
comment
@StanislavL, теперь я хорошо понимаю твой вопрос. Проблема в том, что вы выполняете вызов ajax на локальном хосте на другом компьютере, и это не должно работать. Вам нужен nginx и для этого, а затем вам нужно использовать обратный прокси для nginx для обработки входящих подключений и прокси на 3000 или 3009 для вас. Тогда люди смогут обращаться к основному хосту nginx по его IP-адресу, и проблемы с локальным хостом не возникнет. Другая возможность - создать URL-адрес на основе текущего URL-адреса браузера. Если URL-адрес браузера — localhost:3000, подключитесь к localhost:3009, если это 192.168.X.X:3000, подключитесь к API в 192.168.X.X:3009. - person Tarun Lalwani; 06.09.2017
comment
На самом деле процесс2 (клиент) пытается вызвать процесс1 (сервер) внутри себя. server не должен быть доступен вне контейнера. Я получаю доступ к той же машине (внутри контейнера). Без докера работает нормально. Я запускаю процессы process1 и process2 на хосте и успешно вызываю сервер с клиента. - person StanislavL; 06.09.2017
comment
Предположим, на одном сервере вы запускаете 2 веб-приложения на разных портах. App1 вызывает App2, вызывая GET localhost:3009. Без докера нормально. Теперь я помещаю их в контейнер докеров. Мне не нужно app2 (сервер). App2 должен вызываться app1 внутри, и я вижу результат, вызывая app1 извне. - person StanislavL; 06.09.2017
comment
Да, это правильно. В этом есть две вещи: если App1 вызывает app2 на стороне сервера, тогда может быть раскрыто только app1. Но если приложение1 вызывает его через ajax в пользовательском браузере, тогда приложение2 должно быть открыто с использованием обратного прокси-сервера nginx либо на поддомене, либо на другом URL-адресе. - person Tarun Lalwani; 06.09.2017
comment
Спасибо за идею. Проверим, как создать обратный прокси. - person StanislavL; 06.09.2017