Назад | Перейти на главную страницу

Конфигурация обратного прокси Docker Nginx

Контекст:

Я новичок в 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" "-"

Попытки правовой защиты:

Конфигурации:

Имя хоста находится в моем хосте /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://stackoverflow.com/questions/43500469/nginx-proxy-jwilder-nginx-proxy-connection-reset-by-peer-502-bad-gateway

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

https://umbrella.cisco.com/blog/2015/11/03/lets-talk-about-proxies-pt-2-nginx-as-a-forward-http-proxy/

Используйте Nginx в качестве обратного прокси для нескольких серверов

РЕДАКТИРОВАТЬ: Основываясь на мнениях пары добрых людей, я пришел к выводу, что этот маршрут слишком далеко отклонился от моей первоначальной проблемы, чтобы гарантировать дальнейшее преследование. Это можно списать на путаницу и слишком много часов изучения одной и той же проблемы. Если модератор хочет закрыть этот вопрос, пожалуйста, сделайте это.

Имена хостов для докера не указаны в / etc / hostname или / etc / hosts. Docker имеет собственное межконтейнерное взаимодействие. Поэтому, когда вы ссылаетесь на контейнер, вы можете использовать имя службы, указанное в вашем docker-compose.yml, для ссылки на контейнер. Итак, на данный момент у вас есть следующие контейнеры:

  1. nginx: вы можете называть его nginx в качестве имени хоста. Вы должны иметь возможность пинговать контейнер, используя имя хоста nginx.
  2. php-app-one: имя хоста: php-app-one
  3. php-приложение-два
  4. php-приложение-три
  5. db

Кстати, если вы хотите указать другое имя хоста для контейнера, вы можете использовать это в своем 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