Configuração do proxy reverso Nginx do Docker

1

Contexto:

Sou relativamente novo no nginx e descubro como fazer isso funcionar de forma incremental. Eu tenho trabalhado em torno deste problema por um tempo até agora, onde na verdade está dificultando o desenvolvimento em um dos meus aplicativos como resultado de um comportamento inadequado (cabeçalhos não sendo passados entre cada host, corpos de solicitação sendo vazios, etc).

Eu tenho três aplicativos em contêineres php-fpm e um servidor nginx em seu próprio contêiner. O contêiner nginx atua como um único ponto de acesso para atender solicitações aos contêineres php-fpm com base no nome do host solicitado (configuração vhost básica). Tudo funciona bem ao usar try_files , mas ao alternar para proxy_pass , o problema se apresenta.

As configurações do nginx são quase idênticas para cada um dos hosts php-fpm, com a exceção do server_name sendo alterado para corresponder ao recipiente pelo qual a solicitação deve ser processada.

Meus recursos de pesquisa estão vinculados na parte inferior da página.

Problema:

É aqui que estou confuso. Dependendo do que eu definir proxy_pass para alterar o erro que vejo nos logs nginx. Sob nenhuma circunstância, quando usar proxy_pass , as solicitações serão realmente concluídas com êxito. Aqui estão as várias configurações com o erro associado:

Configuração:

proxy_pass http://appX/; # upstream name

Erro:

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" "-"

Configuração:

proxy_pass https://appX/; # upstream name

Erro:

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"

Configuração:

proxy_pass http://appX.local/; # hostname

Erro (Faz um loop várias vezes (logicamente, com base no redirecionamento para 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"

Configuração:

proxy_pass https://appX.local/; # hostname

Erro (faz um loop várias vezes e não sei por que) :

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" "-"

Configuração:

proxy_pass https://appX:9000/;

Erro:

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" "-"

Configuração:

proxy_pass https://appX.local:9000/;

Erro:

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" "-"

Tentativa de remédios:

  • Eu tentei alterar as portas nas diretivas do servidor para portas não padrão como bem como acrescentar um número de porta (tanto o especificado na escuta directiva, bem como a especificada na directiva a montante).
  • Tentei não usar SSL e fazer isso funcionar em uma conexão HTTP padrão.
  • removi todas as outras configurações de proxy e tentei apenas com proxy_pass
  • Isso funciona com try_files $uri $uri/ /index.php?$args , mas isso ignora o proxying.
  • Eu tentei combinar as várias configurações em meus recursos de pesquisa e sou experimentando os erros, independentemente das alterações que eu faço.

Configurações:

O nome do host está no arquivo /etc/hostname do meu host e todos respondem como esperado.

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

Qualquer ajuda seria muito apreciada. Eu passei algumas horas sobre isso hoje e estou muito bem preso ao que eu perdi em toda a leitura e tentativa e erro.

Recursos de pesquisa:

link

link

link

link

link

link

link

link

link

Use o Nginx como proxy reverso para vários servidores

EDITAR: Com base na opinião de algumas pessoas legais aqui, concluí que essa rota desviou-se muito do meu problema original para garantir uma busca adicional. Isso pode ser atribuído à confusão e a muitas horas encarando o mesmo problema. Se um moderador quiser encerrar esta questão, sinta-se à vontade para fazê-lo.

    
por TomJ 09.05.2018 / 00:58

1 resposta

1

Os nomes de host para o docker não estão especificados em / etc / hostname ou / etc / hosts. O Docker tem sua própria comunicação entre contêineres. Portanto, quando você se referir a um contêiner, poderá usar o nome do serviço especificado em seu docker-compose.yml para se referir ao contêiner. Então, no momento, você tem os seguintes contêineres:

  1. nginx: você pode se referir a ele como nginx como o nome do host. Você deve conseguir executar ping no contêiner usando o nome do host nginx.
  2. php-app-one: nome do host: php-app-one
  3. php-app-dois
  4. php-app-three
  5. db

Btw se você quiser especificar um nome de host diferente para o contêiner, então você pode usar isso no seu docker-compose.yml

container_name: 'some-container-name-different-to-the-name-of-service'

Conseguir que o nginx + php-fpm trabalhe em conjunto, mas cada um em seu próprio contêiner é bastante difícil. Aqui está um repositório do github onde eu configuro tudo manualmente sem o docker-compose.yml. Nginx e php-fpm estão em seu próprio contêiner: link Essa é a configuração do nginx. Você verá o contêiner nginx se conectando ao contêiner php-fpm usando um nome de host e porta.

fastcgi_pass php-fpm-container:9000;

Veja o README, é bastante descritivo: link

Sugiro dividir o problema em pequenas partes como você tem feito. Primeiro, pegue nginx e php-fpm em seu próprio contêiner e depois sirva uma página aleatória que contém:

<?php
phpinfo();
php>

Depois de conseguir esse trabalho, vá a partir daí.

Aqui estão alguns links para ajudá-lo: link link link

    
por 09.05.2018 / 12:23