SSL de configuração de proxy reverso Ngnix para localhost no Docker

SSL de configuração de proxy reverso Ngnix para localhost no Docker

Usando o docker compose.yml abaixo, estou criando 2 contêineres e um contêiner de proxy reverso.

version: '3'

services:
  # SSGTM Tag Server Container
  tagging_server_container:
    image: gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable
    ports:
      - '8080:8080'
    restart: always
    environment:
      PREVIEW_SERVER_URL: https://preview.ssgtm.dev
      CONTAINER_CONFIG: aWQ9...
    networks:
      - ssgtm
  # SSGTM Preview Server Container
  preview_server_container:
    image: gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable
    ports:
      - '8081:8080'
    restart: always
    environment:
      RUN_AS_PREVIEW_SERVER: true
      CONTAINER_CONFIG: aWQ9...
    networks:
      - ssgtm
  proxy:
    image: nginx:1.19.10-alpine
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./conf/nginx.conf:/etc/nginx/nginx.conf
      - ./certs:/etc/nginx/certs
    depends_on:
      - preview_server_container
      - tagging_server_container
    networks:
      - ssgtm
networks:
  ssgtm:
    driver: bridge

E também interno conf/nginx.confe usado mkcert -cert-file ssgtm.dev.crt -key-file ssgtm.dev.key ssgtm.dev "*.ssgtm.dev" localhost 127.0.0.1 ::1para criar certificado e chave SSL.

events {
  worker_connections 1024;
}

http {
  
  upstream docker-tagging-server {
    server tagging_server_container:8080;
  }

  upstream docker-preview-server {
    server preview_server_container:8080;
  }
  
  server {
    listen 443 ssl;
    server_name 127.0.0.1;

    ssl_certificate /etc/nginx/certs/cert.crt;
    ssl_certificate_key /etc/nginx/certs/cert.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
      proxy_buffering off;
      proxy_redirect  off;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;

      proxy_pass http://docker-preview-server;
    }
  }
  
  server {
    listen 443 ssl;
    server_name ssgtm.dev;

    ssl_certificate /etc/nginx/certs/cert.crt;
    ssl_certificate_key /etc/nginx/certs/cert.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
      proxy_buffering off;
      proxy_redirect  off;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;

      proxy_pass http://docker-tagging-server;
    }
  }

  server {
    listen 443 ssl;
    server_name preview.ssgtm.dev;

    ssl_certificate /etc/nginx/certs/cert.crt;
    ssl_certificate_key /etc/nginx/certs/cert.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
      proxy_buffering off;
      proxy_redirect  off;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;

      proxy_pass http://docker-preview-server;
    }
  }
}

Onde estou fazendo proxy de minhas solicitações do VirtualHost para o contêiner de destino.

Também no hostsarquivo que adicionei abaixo para resolver localmente. O que funciona muito bem... Ele está resolvendo para 127.0.0.1 e indo para o Nginx e indo para o contêiner de destino.

127.0.0.1 preview.ssgtm.dev
::1 preview.ssgtm.dev

127.0.0.1 ssgtm.dev
::1 ssgtm.dev

O problema que estou enfrentando é... dentro de ambos o aplicativo contêiner solicita um TCP para IP de domínio com porta 443... então, quando solicita ssgtm.dev:443, torna-se 127.0.0.1:443 e retorna erro Message: connect ECONNREFUSED 127.0.0.1:443E não consigo entender esse erro. Pelo que entendi, não é possível conectar-se a 127.0.0.1 com a porta 443, mas adicionei isso! O que estou fazendo errado?

Responder1

Os contêineres não conseguem acessar o Nginx porque estão tentando se conectar ao host local de seu próprio namespace de rede. Poderíamos tentar o DNS especial name host.docker.internalque resolve o endereço IP interno usado pelo host.

Modifique seu nginx.confarquivo para que, em vez de fazer solicitações para ssgtm.dev:443ou 127.0.0.1:443, ele faça solicitações para host.docker.internal:443.

server {
    listen 443 ssl;
    server_name host.docker.internal;

    ssl_certificate /etc/nginx/certs/cert.crt;
    ssl_certificate_key /etc/nginx/certs/cert.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
      proxy_buffering off;
      proxy_redirect  off;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;

      proxy_pass http://docker-preview-server;
    }
  }

informação relacionada