Docker - прокси nginx - доступ к хостам между контейнерами

У меня есть веб-приложение.

  1. Общедоступное веб-приложение (app1)
  2. веб-приложение api (app2)

Я делаю конфигурацию докеров для этих приложений. Каждое приложение в своем контейнере. Чтобы получить доступ к этим приложениям из Интернета, сконфигурированный контейнер с nginx, где nginx проксирует все запросы.
Итак, я могу запустить - http://app1.dev/ и http://app2.dev/

Но мне нужен доступ из app1 к http://app2.dev/ (доступ к хостам app2.dev из контейнера app1) .

Пинг (из контейнера app1):

PING app2.dev (127.0.53.53) 56(84) bytes of data.
64 bytes from 127.0.53.53: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 127.0.53.53: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 127.0.53.53: icmp_seq=3 ttl=64 time=0.038 ms

Что мне еще нужно настроить, чтобы иметь доступ к хосту http://app2.dev/ из контейнера app1?

Конфигурация прокси Nginx

upstream app1_upstream {
    server app1;
}
upstream app1_upstream {
    server app2;
}
server {
    listen 80;

    server_name app1.dev
                app2.dev;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;

        if ($host = "app1.dev") {
            proxy_pass http://app1;
        }

        if ($host = "app2.dev") {
            proxy_pass http://app2;
        }
    }

    error_log  /var/log/nginx/proxy_error.log;
    access_log /var/log/nginx/proxy_access.log;
}

Докер сочиняет

version: '2'
services:
    proxy:
        build: ./proxy/
        ports:
            - "80:80"
            - "443:443"
        links:
            - app1
            - app2
            - app1:app1
            - app2:app2
        hostname: proxy

    app1:
        build: ./app1/
        volumes:
            - ../app1/:/var/www/app1
        hostname: app1

    app2:
        build: ./app2/
        volumes:
            - ../app2/:/var/www/app2
        hostname: app2

docker-compose ps

app1      /sbin/my_init  Up      80/tcp                                   
app2     /sbin/my_init  Up      80/tcp                                   
proxy_1   /sbin/my_init  Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

person Dmytro    schedule 17.03.2016    source источник


Ответы (2)


Не уверен, какую версию докера вы используете, но если вы (или можете) запустить 1.10, вам следует использовать сеть докеров вместо использования «ссылки».

Если вы запустите все три контейнера в одной сети докеров, они будут иметь доступ друг к другу через свое имя контейнера.

Это позволит вам сделать вызов из app1 в app2, не возвращаясь через ваш прокси (хотя я бы назвал это анти-шаблоном, как если бы вы изменили интерфейс на app2, вам нужно было бы обновить app1 и прокси, я бы пусть app1 вызывает app2 через ваш прокси, чтобы поддерживать один интерфейс).

Для получения дополнительной информации о сетях Docker: https://docs.docker.com/engine/userguide/networking/dockernetworks/

TL; DR:

# create bridge network (for single host)
docker networks create my-network

затем измените и свой состав:

version: '2'
services:
    proxy:
        build: ./proxy/
        ports:
            - "80:80"
            - "443:443"
        networks:
            - my-network
        hostname: proxy

    app1:
        build: ./app1/
        volumes:
            - ../app1/:/var/www/app1
        networks:
            - my-network
        hostname: app1

    app2:
        build: ./app2/
        volumes:
            - ../app2/:/var/www/app2
        networks:
            - my-network
        hostname: app2

networks:
   my-network:
    external: true
person Collin Estes    schedule 17.03.2016
comment
Всем привет! Я попробовал то же самое, но у меня ничего не вышло. Nginx по-прежнему не может разрешить имена. Я упускаю что-то мудрое разрешение? - person MSIS; 25.03.2016
comment
Я думаю, вы имели в виду docker network create my-network (без s) - person Steven Rosato; 14.10.2016

ports:
    - "80:80"
    - "443:443"

предоставляет порты хост-машине. Когда ты делаешь

docker ps -a

вы увидите эти порты в списке

Однако, чтобы открыть порты между контейнерами, вам необходимо использовать команду EXPOSE в вашем файле dockerfile.

https://docs.docker.com/engine/reference/builder/#expose

What i should configure else, to have access to http://app2.dev/ host from app1 container?

Вы должны открыть порты в dockerfile!

также если вы сделаете ...

docker exec -it containerName bash

вы сможете исследовать.

Просмотрите файл hosts внутри контейнера.

cat /etc/hosts

вы увидите запись для другого контейнера в файле hosts, если вы правильно указали --link контейнеров.

вы можете пинговать, используя доменное имя в файле hosts.

person danday74    schedule 17.03.2016
comment
я обновил вопрос. С портами проблем нет. Я могу получить доступ к приложениям из Интернета. - person Dmytro; 17.03.2016
comment
каждый файл хостов контейнера содержит запись только для этого контейнера 172.19.0.8 proxy (это для прокси, для app1 и app2 свой IP-адрес). Но вы можете увидеть файл docker-compose - есть ли некорректное связывание? Dockerfile каждого приложения содержит - EXPOSE 80 - person Dmytro; 17.03.2016