Контекст:
Я новичок в nginx и выясняю, как постепенно заставить эту работу. Я работал над этой проблемой некоторое время до сих пор, когда она фактически препятствует разработке одного из моих приложений из-за неправильного поведения (заголовки не передаются между каждым хостом, тела запросов пусты и т. Д.).
У меня есть три приложения в контейнерах php-fpm и сервер nginx в собственном контейнере. Контейнер nginx действует как единая точка доступа для обслуживания запросов к контейнерам php-fpm на основе запрошенного имени хоста (базовая конфигурация vhost). Все отлично работает при использовании try_files
, но при переходе на proxy_pass
проблема возникает сама собой.
Конфигурации nginx почти идентичны для каждого из хостов php-fpm, за исключением server_name
изменяется для соответствия тому контейнеру, который должен обрабатывать запрос.
Ссылки на мои исследовательские ресурсы находятся внизу страницы.
Проблема:
Вот где я запутался. В зависимости от того, что я установил proxy_pass
to изменит ошибку, которую я вижу в журналах nginx. Ни при каких обстоятельствах при использовании proxy_pass
запросы будут действительно успешно завершены. Вот различные настройки и связанные с ними ошибки:
Настройка:
proxy_pass http://appX/; # upstream name
Ошибка:
nginx | 2018/05/08 22:19:48 [error] 10224#10224: *8442 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.18.0.1, server: appX.local, request: "GET / HTTP/1.1", upstream: "http://172.18.0.3:9000/", host: "appX.local"
nginx | 172.18.0.1 - - [08/May/2018:22:19:48 +0000] "GET / HTTP/1.1" 502 568 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
Настройка:
proxy_pass https://appX/; # upstream name
Ошибка:
nginx | 172.18.0.1 - - [08/May/2018:22:20:50 +0000] "GET / HTTP/1.1" 502 568 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
nginx | 2018/05/08 22:20:50 [error] 13589#13589: *8446 peer closed connection in SSL handshake (104: Connection reset by peer) while SSL handshaking to upstream, client: 172.18.0.1, server: appX.local, request: "GET / HTTP/1.1", upstream: "https://172.18.0.3:9000/", host: "appX.local"
Настройка:
proxy_pass http://appX.local/; # hostname
ошибка (Зацикливается несколько раз (логично, на основе перенаправления на https):
nginx | 172.18.0.6 - - [08/May/2018:22:21:49 +0000] "GET / HTTP/1.0" 301 185 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "172.18.0.1"
Настройка:
proxy_pass https://appX.local/; # hostname
ошибка (Зацикливается много раз, и я не знаю почему):
nginx | 172.18.0.1 - - [08/May/2018:22:23:35 +0000] "GET / HTTP/1.1" 500 588 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
Настройка:
proxy_pass https://appX:9000/;
Ошибка:
nginx | 2018/05/08 22:29:26 [error] 14426#14426: *9563 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: appX.local, request: "GET / HTTP/1.1", upstream: "https://172.18.0.6:9000/", host: "appX.local"
nginx | 172.18.0.1 - - [08/May/2018:22:29:26 +0000] "GET / HTTP/1.1" 502 568 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
Настройка:
proxy_pass https://appX.local:9000/;
Ошибка:
nginx | 2018/05/08 22:27:39 [error] 14426#14426: *9559 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: appX.local, request: "GET / HTTP/1.1", upstream: "https://172.18.0.6:9000/", host: "appX.local"
nginx | 172.18.0.1 - - [08/May/2018:22:27:39 +0000] "GET / HTTP/1.1" 502 568 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
Попытки правовой защиты:
proxy_pass
try_files $uri $uri/ /index.php?$args
, но это обходит проксирование.Конфигурации:
Имя хоста находится в моем хосте /etc/hostname
файл и все отвечают, как и ожидалось.
nginx.conf
worker_processes 1;
daemon off;
events {
worker_connections 1024;
}
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
http {
default_type application/octet-stream;
include /etc/nginx/conf/mime.types;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/appX.conf:
upstream appX {
server appX:9000;
}
server {
listen 80;
listen [::]:80;
server_name appX.local appX;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_tokens off;
ssl on;
ssl_certificate /etc/nginx/certs/appX.crt;
ssl_certificate_key /etc/nginx/certs/appX.key;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
server_name appX.local appX;
root /var/www/appX;
index index.php index.html;
location / {
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_next_upstream error timeout invalid_header;
proxy_hide_header X-Powered-By;
proxy_hide_header X-Pingback;
proxy_hide_header Link;
proxy_cache_bypass $http_pragma $http_authorization;
proxy_ssl_session_reuse off;
proxy_ssl_server_name on;
proxy_pass https://appX;
}
}
docker-compose.yml
version: '3.3'
services:
nginx:
image: evild/alpine-nginx:1.9.15-openssl
container_name: apps_nginx
volumes:
- ./app-one:/var/www/app-one/:ro
- ./app-two:/var/www/app-two/:ro
- ./app-three:/var/www/app-three/:ro
- ./nginx/conf/nginx.conf:/etc/nginx/conf/default.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./certs:/etc/nginx/certs
ports:
- 80:80
- 443:443
expose:
- "80"
- "443"
depends_on:
- php-app-one
- php-app-two
environment:
TZ: "America/Los_Angeles"
networks:
default:
aliases:
- app-one.local
- app-two.local
php-app-one:
environment:
TZ: "America/Los_Angeles"
image: joebubna/php
container_name: apps_php_app-one
restart: always
volumes:
- ./app-one:/var/www/app-one
ports:
- 9001:9000
networks:
- default
php-app-two:
environment:
TZ: "America/Los_Angeles"
image: joebubna/php
container_name: apps_php_app-two
restart: always
volumes:
- ./app-two:/var/www/app-two
ports:
- 9000:9000
networks:
- default
php-app-three:
image: joebubna/php
container_name: apps_php_app-three
restart: always
volumes:
- ./app-three:/var/www/app-three
- ./fastcgi_params:/var/www/fastcgi_params
ports:
- 9002:9000
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
WORDPRESS_DB_NAME: app_three
TZ: "America/Los_Angeles"
networks:
- default
db:
image: mysql:5.6
container_name: apps_mysql
volumes:
- db-data:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/conf.d/ZZ-apps.cnf:ro
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_DATABASE: cora
TZ: "America/Los_Angeles"
ports:
- 3306:3306
expose:
- "3306"
networks:
- default
volumes:
db-data:
networks:
default:
driver: bridge
Любая помощь будет принята с благодарностью. Сегодня я потратил на это немало часов, и я довольно хорошо зациклился на том, что я пропустил во время всего чтения, проб и ошибок.
Ресурсы для исследований:
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
https://www.liaohuqiu.net/posts/nginx-proxy-pass/
https://gist.github.com/soheilhy/8b94347ff8336d971ad0
https://groups.google.com/forum/#!topic/xnat_discussion/-S6eYsnwrXg
https://stackoverflow.com/questions/37346560/nginx-server-closes-ssl-connection-for-some-clients
https://stackoverflow.com/questions/38375588/nginx-reverse-proxy-to-heroku-fails-ssl-handshake
https://stackoverflow.com/questions/40580617/nginx-reverse-proxy-upstream-not-working
Используйте Nginx в качестве обратного прокси для нескольких серверов
РЕДАКТИРОВАТЬ: Основываясь на мнениях пары добрых людей, я пришел к выводу, что этот маршрут слишком далеко отклонился от моей первоначальной проблемы, чтобы гарантировать дальнейшее преследование. Это можно списать на путаницу и слишком много часов изучения одной и той же проблемы. Если модератор хочет закрыть этот вопрос, пожалуйста, сделайте это.
Имена хостов для докера не указаны в / etc / hostname или / etc / hosts. Docker имеет собственное межконтейнерное взаимодействие. Поэтому, когда вы ссылаетесь на контейнер, вы можете использовать имя службы, указанное в вашем docker-compose.yml, для ссылки на контейнер. Итак, на данный момент у вас есть следующие контейнеры:
Кстати, если вы хотите указать другое имя хоста для контейнера, вы можете использовать это в своем docker-compose.yml
container_name: 'some-container-name-different-to-the-name-of-service'
Довольно сложно заставить nginx + php-fpm работать вместе, но каждый в своем собственном контейнере. Вот репозиторий на github, где я настраиваю все вручную без docker-compose.yml. Nginx и php-fpm находятся каждый в своем собственном контейнере: https://github.com/timogoosen/mediawiki-dockerized/blob/master/nginx/sites-enabled/site.conf Это конфигурация nginx. Вы увидите, что контейнер nginx подключается к контейнеру php-fpm, используя имя хоста и порт.
fastcgi_pass php-fpm-container:9000;
Смотрите README, он довольно информативен: https://github.com/timogoosen/mediawiki-dockerized/tree/master/nginx
Я предлагаю разбить проблему на мелкие части, как вы это делали. Сначала загрузите nginx и php-fpm каждый в своем собственном контейнере, а затем обслужите случайную страницу, которая просто содержит:
<?php
phpinfo();
php>
Как только вы получите эту работу, продолжайте.
Вот несколько ссылок, которые могут вам помочь: https://stackoverflow.com/questions/39901311/docker-ubuntu-bash-ping-command-not-found https://stackoverflow.com/questions/30172605/how-to-get-into-a-docker-container https://stackoverflow.com/questions/30151436/how-to-run-nginx-docker-container-with-custom-config