Прокси-сервер докеров-докеров Nginx переходит в другой порт
Я хочу запустить Nginx в контейнере докера, он прослушивает порт 80, и я хочу, чтобы он прокси_pass до порта 8080, когда URL-адрес начинается со слова api
, и у меня есть порт прослушивания веб-приложений 8080. Это было работая для меня без докеров, но с докером я не мог заставить его работать.
Мой nginx.conf похож:
location /{
# serve static page
}
location /api {
proxy_pass http://0.0.0.0:8080;
}
Я запускаю свой контейнер nginx с docker run -d -p 80:80 -p 8080: 8080 nginx
Моя проблема в том, что я больше не могу запускать свое веб-приложение, потому что он не может слушать порт 8080, поскольку этот контейнер уже прослушивает его.
docker run -d --net host nginx
Попробуйте!
Контейнер Nginx будет совместно использовать хост-сеть с IP-адресом и всеми портами
Сначала вам нужно создать сеть для размещения обоих контейнеров:
docker network create nginx_network
Затем вы должны указать DNS-сервер Docker в конфигурации nginx:
location /api {
#Docker DNS
resolver 127.0.0.11;
#my_api - name of container with your API, see below
proxy_pass http://my_api:8080;
}
Наконец, запустите контейнеры:
docker run --network="nginx_network" -d --name my_api your_api_container
docker run --network="nginx_network" -d -p 80:80 nginx
Примечание:
- - значение параметра имени для контейнера API должно соответствовать доменному имени в конфигурации Nginx
достаточно указать только 80 портов для вашего контейнера nginx.
сначала запустите контейнер API, а затем контейнер Nginx (см. ниже).
оба контейнера должны находиться в одной сети.
Это должно работать.
В случае, если вы сначала запустите контейнер nginx, nginx попытается разрешить имя домена my_api
при запуске и сбой, поскольку контейнер с этим именем еще не существует. В этом случае существует следующее обходное решение (не уверен, что это хорошее решение). Изменить конфигурацию nginx:
location /api {
#Docker DNS
resolver 127.0.0.11;
#hack to prevent nginx to resolve domain on start up
set $docker_host "my_api";
#my_api - name of container with your API, see below
proxy_pass http://$docker_host:8080;
}
Вы можете (или, скорее, должны) иметь только один процесс на контейнер докеров, что означает, что nginx будет работать в одном контейнере, а ваше приложение - на другом. Старый способ заключается в создании связей между контейнерами следующим образом:
$ docker run --name my-app -d myself/myapp
$ docker run --name proxy --link my-app:my-app -d nginx
Это добавит строку в /etc/hosts
в контейнере nginx, чтобы она могла вызвать другой контейнер по его имени.
И затем в файле nginx.conf:
location /api {
proxy_pass http://my-app:8080;
}
Однако согласно официальным документам Docker этот метод устарел, и вы должны использовать его "абсолютно необходимо". Вместо этого вы должны использовать docker networking. Теоретически, если оба контейнера находятся в одной сети, а локальный DNS-сервер работает (встроен в докер), они должны иметь возможность видеть друг друга без параметра -link. К сожалению, для меня это почему-то не сработало. У Nginx не было правильного DNS, настроенного в /etc/resolv.conf, но прочитайте статью и поиграйте вокруг нее, я уверен, что она будет работать.