Контейнер для док-станции nginx: 502 плохой ответ шлюза
У меня есть сервис, слушая порт 8080. Это не контейнер.
Затем я создал контейнер nginx, используя официальное изображение:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d -p 443:443 -p 80:80 nginx
В конце концов:
# netstat -tupln | grep 443
tcp6 0 0 :::443 :::* LISTEN 3482/docker-proxy
# netstat -tupln | grep 80
tcp6 0 0 :::80 :::* LISTEN 3489/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 1009/java
Конфигурация Nginx:
upstream eighty {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name eighty.domain.com;
location / {
proxy_pass http://eighty;
}
}
Я проверил, что я могу подключиться к этому серверу с помощью # curl http://127.0.0.1:8080
<html><head><meta http-equiv='refresh'
content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body
style='background-color:white; color:white;'>
...
Кажется, что работает хорошо, однако, когда я пытаюсь получить доступ к моему браузеру, nginx сообщает bt ответ на плохой шлюз 502.
Я выясню, что это может быть проблема, связанная с видимостью между открытием неконтейнерным процессом и контейнером. Могу ли я контейнерное соединение с портом, открытым другим неконтейнерным процессом?
ИЗМЕНИТЬ
Журналы, где upstream { server 127.0.0.1:8080; }
:
2016/07/13 09:06:53 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:06:53 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
Журналы, где upstream { server 0.0.0.0:8080; }
:
62.57.217.25 - - [13/Jul/2016:09:00:30 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" 2016/07/13 09:00:30 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client:
62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com" 2016/07/13 09:00:32 [error] 5#5: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:00:32 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
Любые идеи?
Ответы
Ответ 1
Эта проблема
Localhost немного сложнее, когда дело доходит до контейнеров. Внутри док-контейнера localhost указывает на сам контейнер. Это означает, что с восходящим потоком, как это:
upstream foo{
server 127.0.0.1:8080;
}
или же
upstream foo{
server 0.0.0.0:8080;
}
вы говорите nginx передать ваш запрос локальному хосту. Но в контексте docker-контейнера localhost (и соответствующие IP-адреса) указывают на сам контейнер:
![enter image description here]()
Обращаясь к 127.0.0.1, вы никогда не достигнете своего хост-компьютера, если ваш контейнер не находится в сети хоста.
Решения
Хост сеть
Вы можете запустить nginx в той же сети, что и ваш хост:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d --net=host nginx
Обратите внимание, что вам не нужно выставлять какие-либо порты в этом случае.
Это работает, хотя вы теряете преимущество работы с сетью докеров. Если у вас есть несколько контейнеров, которые должны взаимодействовать через сеть докеров, такой подход может стать проблемой. Если вы просто хотите развернуть nginx с помощью Docker и не хотите использовать какие-либо расширенные функции сети Docker, этот подход подойдет.
Доступ к удаленному IP-адресу хостов
Другим подходом является перенастройка вашей исходной директивы nginx для прямого подключения к вашему хост-компьютеру путем добавления его удаленного IP-адреса:
upstream foo{
//insert your hosts ip here
server 192.168.99.100:8080;
}
Теперь контейнер пройдет через сетевой стек и правильно определит ваш хост:
![enter image description here]()
Вы также можете использовать свое DNS-имя, если оно у вас есть. Убедитесь, что докер знает о вашем DNS-сервере.
Ответ 2
Мне помогла эта строка кода proxy_set_header Host $http_host;
server {
listen 80;
server_name localhost;
location / {
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_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://myserver;
}
Ответ 3
nginx.sh
ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)
docker run --name nginx --add-host="host:${ip}" -p 80:80 -d nginx
nginx.conf
location / {
...
proxy_pass http://host:8080/;
}
Это работает для меня
Ответ 4
Что вы можете сделать, это настроить proxy_pass
чтобы с точки зрения container
адрес указывал на ваш реальный хост.
Чтобы получить адрес host
с точки зрения контейнера, вы можете сделать следующее в Windows с докером 18.03
(или более поздней):
Запустите bash для контейнера с хоста, где имя образа - nginx
(работает в Alpine Linux distribution
):
docker run -it nginx /bin/ash
Затем запустите внутри контейнера
/ # nslookup host.docker.internal
Name: host.docker.internal
Address 1: 192.168.65.2
192.168.65.2
- это IP-адрес хоста, а не IP-адрес моста, как в ответе spinus
.
Я использую здесь host.docker.internal:
Хост имеет изменяющийся IP-адрес (или не имеет, если у вас нет доступа к сети). Начиная с 18.03, мы рекомендуем подключаться к специальному DNS-имени host.docker.internal, который разрешает внутренний IP-адрес, используемый хостом. Это для целей разработки и не будет работать в производственной среде за пределами Docker для Windows.
Затем вы можете изменить конфигурацию nginx
на: proxy_pass http://192.168.65.2:{your_app_port};
: proxy_pass http://192.168.65.2:{your_app_port};
и это должно работать нормально.
Не забудьте указать тот же port
с которым работает ваше локальное приложение.
Ответ 5
У меня была эта проблема, и оказалось, что проблема с контейнером Docker не запускается из-за проблемы с разрешениями.
В моем случае работает
docker-compose ps
показал, что контейнер не был запущен и вышел со статусом 1. Оказывается, что при переносе на новую машину были потеряны разрешения. Настройка разрешений для известного сотрудника пользователя в родительском каталоге устранила проблему для меня, и я смог запустить службу Docker, где, как и раньше, я получал
nginx_1_c18a7f6f7d6d | chown: /var/www/html: Operation not permitted