2016-09-06 2 views
1

Я пытаюсь настроить Nginx (внутри контейнера Docker) с помощью Node.js (снаружи, на главной машине). Конфигурация Nginx использует upstream и proxy-pass директивы:Docker Nginx + Node: адрес уже используется

upstream helloworld { 
    server localhost:8080; 
} 

server { 
    listen 443; 
    ssl on; 
    ssl_certificate /some/cert.crt; 
    ssl_certificate_key /some/cert.key; 
    location/{ 
     proxy_pass http://helloworld; 
     proxy_http_version 1.1; 
     proxy_set_header Upgrade $http_upgrade; 
     proxy_set_header Connection 'upgrade'; 
     proxy_set_header Host $host; 
     proxy_cache_bypass $http_upgrade; 
     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 https; 
    } 
} 

Node приложение прослушивает порт 8080 хоста. Теперь я начинаю Nginx контейнер

docker run \ 
     -d \ 
     -p 80:80 \ 
     -p 443:443 \ 
     -p 8080:8080 \ 
     -v /some/mounts:/to/some/mounts \ 
     --name nginx \ 
     nginx:alpine 

Что я ожидаю, что Nginx принимает подключения к портам 80 и 443, и направляет их на порт 8080 внутри контейнера, который затем будет перенаправляются на порт 8080 хоста машины приложение Node (-p 8080:8080), однако он дает ошибку: Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.

Я попытался изменить localhost к 127.0.0.1 и даже в IP-адрес хост-машине (172.17.0.1 производства $ /sbin/ip route внутри контейнера Nginx), но ничто из этого не работает. Если я не использую -p 8080:8080 при запуске контейнера, он тоже не работает.

Даже если 172.17.0.1 является хост-машины IP-адрес, я не могу подключиться к нему изнутри контейнера Nginx:

$ wget 172.17.0.1:8080 
Connecting to 172.17.0.1:8080... failed: Connection refused. 

Теперь я знаю, что могу Dockerize мой Node приложение и использовать --link аргумент когда начиная с контейнера Nginx, но это не решение на данный момент, так как для этого требуется много повторной записи приложения Node.

Любая помощь очень ценится.

ответ

3

Я бы предположил, что вы перемещаете приложение nodejs в контейнер в той же сети (сеть моста) как nginx. Это упрощает/повышает безопасность (изолируйте узел за публичным прокси-сервером nginx).

В противном случае запустите свой nginx в сети хоста, чтобы его localhost был таким же, как и у хоста.

docker run \ 
    -d \ 
    -p 80:80 \ 
    -p 443:443 \ 
    -p 8080:8080 \ 
    -v /some/mounts:/to/some/mounts \ 
    --name nginx \ 
    --network host \ 
    nginx:alpine 

Если вы все еще получаете bind: address already in use, это потому, что более чем одна услуга прослушивания по этому адресу. Используйте netstat или lsof (linux | osx), чтобы выяснить, какой процесс прослушивает 8080.

Дополнительная информация о настройках сети. https://docs.docker.com/engine/reference/run/#/network-settings

+0

Хорошо, я пробовал использовать '--network host' (с и без' -p 80: 80' и т. Д., Так как я предполагаю, что с этим вариантом объявления порта избыточны). Если я выполняю '$ curl https: // 127.0.0.1', он работает, я получаю ответ от приложения Node *, но * Nginx перестает отвечать на запросы извне (т. Е. Если я перейду к' https://xxx.xxx .xxx.xxx' из браузера). Еще одна интересная проблема заключается в том, что если do '$ curl https: // localhost' (вместо' 127.0.0.1'), я получаю стандартную страницу «Добро пожаловать в Nginx» oO –

+0

Ваш nginx.conf только слушает 443, а не 80. – Alkaline

+0

Кроме того, ваш nginx находится в сети хоста (localhost, loopback и т. д.), поэтому он недоступен извне вашего компьютера. Если вы не пытаетесь сделать что-то эзотерическое, я действительно предлагаю вам следовать лучшим практикам. Запускайте свои контейнеры в частной сети мостов и только выставляйте свой nginx во внешний мир. – Alkaline

Смежные вопросы