bad gateway NGINX при настройке reverse-proxy в docker
есть некий сайт который находится в контейнере и откликается на 80 порт. Мне нужно сделать реверс прокси в другом контейнере. Я создал Dockerfile:
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/
RUN ["nginx". "-t"]
EXPOSE 80
и сам файл default.conf
upstream site{
server 172.17.0.2:5555;
}
server{
listen 80;
server_name site.com;
access и errorr log по стандарту
location / {
proxy_pass http://site;
}
}
контейнер с сайтом запускаю так - docker run --name site --rm -d -p 5555:80 repository контейнер с reverse-proxy - docker run -d --name reverse --rm -p 80:80 reverse
docker ps -a:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab1b69a58df7 reverse "/docker-entrypoint.…" 14 minutes ago Up 14 minutes 0.0.0.0:80->80/tcp proxy
e07d7fc9eaf2 repository "/docker-entrypoint.…" 14 minutes ago Up 14 minutes 0.0.0.0:5555->80/tcp site
при попытке подключение к реверс-прокси получаю 502 ошибку:
root@debian:/home/user/docker# curl localhost
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>
- Почему у контейнеров указывается адрес 0.0.0.0, а не 172.17.0.2 и 172.17.0.3 ?
- что указывать в upstream nginx 0.0.0.0:5555 или 172.17.0.2:5555 ?
- Как исправить 502 ошибку и настроить работу reverse-proxy ?
Ответы (1 шт):
- Потому что в команде
docker ps -aуказывается не адрес контейнера, а настройки публикации (роутинга) портов.0.0.0.0:5555->80/tcpозначает, что перенаправляться трафик будет с любого адреса на хост системе (т.е. 0.0.0.0) и порта 5555 на порт 80 внутри контейнера. Чтобы посмотреть IP контейнера можно воспользоваться командойdocker inspect <container name/id>. - Указывать IP контейнера, полученного из пункта 1 (не самый лучший/удобный вариант).
- Лучше всего это исправить объединив два контейнера в одну сеть. Проще всего это сделать через
docker compose, но можно и руками (через команды в терминале), когда вы это сделаете появится возможность указывать не конкретные IP контейнеров в конфигурацииnginx, а имена контейнеров (это работает из-за того, что в сетях созданных пользователем работает DNS, т.е. по имене контейнера будет резолвится реальный IP). Это хорошо тем, что по умолчанию у контейнера IP не статический (хотя статические IP и можно настроить) и после удаление контейнера (или запуска не другой машине)Dockerможет выдать другой IP иnginxне сможет найти его. Лучше на конкретные IP адреса не завязываться.
Выглядеть это будет примерно так:
docker-compose.yml
version: '3.4'
services:
nginx:
image: nginx
build:
context: ./nginx
ports:
- 80:80
site:
image: site
build:
context: ./node
environment:
NODE_ENV: production
При запуске через docker compose up -d, автоматически создается сеть между двумя контейнерами. Для примера я использовал небольшое node приложение. У вас в качестве site может быть что-то другое. Указывать ports у site не обязательно, т.к. у вас два контейнера будут находиться в одной сети и ports нужно только чтобы вы могли получить доступ из внешней сети (например, с хоста).
default.conf:
server {
listen 80;
location / {
proxy_pass http://site;
}
}
Можно просто указать имя контейнера и порт на котором запушено приложение (в данном случае это 80) и upstream не нужен.