Hola a todos,
Llevo horas atascado con esto, así que solicito ayuda ya que no he podido encontrar una solución que funcione.
Debido a que tengo varios contenedores que alojan servicios web, necesito alojar mi propio Nginx para enrutar el tráfico a los contenedores correctos. (Podría simplemente mover Discourse a su propio servidor, pero eso sería un último recurso si no logro que esto funcione).
Actualmente estoy utilizando la siguiente configuración:
- Nginx-Proxy - jwilder/nginx-proxy - Docker Image
- Nginx-Proxy/Acme-companion - GitHub - nginx-proxy/acme-companion: Automated ACME SSL certificate generation for nginx-proxy · GitHub
Un buen diagrama de cómo encaja todo se puede encontrar en la siguiente página:
He utilizado los siguientes tutoriales que han sido útiles, pero aún no he tenido éxito.
- How to Install Multiple Discourse Forums on the Same Server
- Use Nginx-Proxy and LetsEncrypt Companion to Host Multiple Websites - Singular Aspect
Anteriores hilos de Discourse que he encontrado (de hace más de 2 años) incluyen:
Mi archivo app.yml de Discourse contiene lo siguiente (dominio y correo electrónico ocultos):
docker_args:
- "--net nginx-proxy"
VIRTUAL_HOST: {dominio}
VIRTUAL_PORT: 80
LETSENCRYPT_HOST: {dominio}
LETSENCRYPT_EMAIL: {dirección de correo electrónico}
He comentado el puerto expuesto en el ejemplo de abajo. He probado múltiples variaciones y he visto muchas presentaciones diferentes. Por ejemplo, los comentarios en esta publicación: Discourse with jwilder/nginx-proxy howtos?, o en otros donde lo he visto comentado y especificado como VIRTUAL_PORT en las variables de Docker. Estoy un poco confundido con esta parte.
#expose:
# - "80"
Todos mis contenedores están en la misma red, por ejemplo:
docker network inspect nginx-proxy
[
{
"Name": "nginx-proxy",
"Id": "d2715f513771f002711521838340b879bb9106ef50118fb29be6b0cf2d5f25e7",
"Created": "2022-02-01T20:32:10.021632263Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"0b6296ccf7e31b67caf0d31ccc5485e30bd6f1746ceee7e6ce29617b892178cd": {
"Name": "app",
"EndpointID": "1cea3782ef9dea3cf0066add142121f569682c74ff8faa6b19813035eff8998c",
"MacAddress": "02:72:f8:ee:03:32",
"IPv4Address": "172.18.0.4/16",
"IPv6Address": ""
},
"975ea34d56a65b722aa5e83b99f71039fd687b1aee4e8d4df3cb192b1d35c043": {
"Name": "nginx-proxy",
"EndpointID": "bc7a0b4602614be516ee0ceb1c4edf923b91bf7a6528c013157180a98d435807",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"e299a734584a765dbc10102a5bc9b0d0c98ac6096b6ae75dd1169105893e40af": {
"Name": "letsencrypt-proxy",
"EndpointID": "6b3588359ac4eec02618d3a7438d2750cb6e1c3d1cb6e1a8ce6378c568358a50",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Mi certificado se generó correctamente, como pueden ver aquí, pero actualmente estoy recibiendo un error 502.
Al intentar depurar revisando los registros de nginx en el contenedor de Discourse, los archivos de registro se generan, pero no se rellenan con ningún contenido:
root@ubuntu-vm-dev-app:/var/log/nginx# ls -lt
total 692
-rw-r--r-- 1 www-data www-data 0 Feb 4 07:23 access.letsencrypt.log
-rw-r--r-- 1 www-data www-data 0 Feb 4 07:23 error.letsencrypt.log
-rw-r--r-- 1 www-data www-data 0 Feb 4 07:23 error.log
-rw-r--r-- 1 www-data www-data 0 Feb 1 23:04 access.log
-rw-r--r-- 1 www-data www-data 700917 Jan 31 23:48 error.log.1
-rw-r--r-- 1 www-data www-data 0 Jan 31 22:55 access.letsencrypt.log.1
-rw-r--r-- 1 www-data www-data 0 Jan 31 22:55 error.letsencrypt.log.1
Mis registros de Docker muestran lo siguiente, que parece ser la información más útil hasta ahora (he eliminado la IP pública y mi nombre de dominio):
nginx-proxy | nginx.1 | 2022/02/04 08:35:04 [error] 206#206: *93 connect() failed (111: Connection refused) while connecting to upstream, client: {REDACTED_PUBLIC_IP}, server: {MY_FORUM_DOMAIN}.com, request: "GET / HTTP/2.0", upstream: "http://172.18.0.4:80/", host: "{MY_FORUM_DOMAIN}.com"
nginx-proxy | nginx.1 | {MY_FORUM_DOMAIN}.com {REDACTED_PUBLIC_IP} - - [04/Feb/2022:08:35:04 +0000] "GET / HTTP/2.0" 502 559 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36" "172.18.0.4:80"
nginx-proxy | nginx.1 | 2022/02/04 08:35:06 [error] 206#206: *93 connect() failed (111: Connection refused) while connecting to upstream, client:{REDACTED_PUBLIC_IP}, server: {MY_FORUM_DOMAIN}.com, request: "GET /service-worker.js HTTP/2.0", upstream: "http://172.18.0.4:80/service-worker.js", host: "{MY_FORUM_DOMAIN}.com", referrer: "https://{MY_FORUM_DOMAIN}.com/service-worker.js"
nginx-proxy | nginx.1 | {MY_FORUM_DOMAIN}.com {REDACTED_PUBLIC_IP} - - [04/Feb/2022:08:35:06 +0000] "GET /service-worker.js HTTP/2.0" 502 559 "https://{MY_FORUM_DOMAIN}.com/service-worker.js" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36" "172.18.0.4:80"
nginx-proxy | nginx.1 | 2022/02/04 08:35:19 [error] 206#206: *93 connect() failed (111: Connection refused) while connecting to upstream, client:{REDACTED_PUBLIC_IP}, server: {MY_FORUM_DOMAIN}.com, request: "GET /service-worker.js HTTP/2.0", upstream: "http://172.18.0.4:80/service-worker.js", host: "{MY_FORUM_DOMAIN}.com", referrer: "https://{MY_FORUM_DOMAIN}.com/service-worker.js"
nginx-proxy | nginx.1 | {MY_FORUM_DOMAIN}.com{REDACTED_PUBLIC_IP} - - [04/Feb/2022:08:35:19 +0000] "GET /service-worker.js HTTP/2.0" 502 559 "https://{MY_FORUM_DOMAIN}.com/service-worker.js" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36" "172.18.0.4:80"
He confirmado que la comunicación hacia el contenedor de Discourse a través del puerto especificado en el archivo containers/app.yml es correcta. Por ejemplo, inicié sesión en el contenedor de Discourse y ejecuté netcat en el puerto 80 antes de realizar una solicitud desde mi navegador.
root@ubuntu-vm-dev-app:/var/log/nginx# netcat -lnvp 80
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::80
Ncat: Listening on 0.0.0.0:80
Ncat: Connection from 172.18.0.2.
Ncat: Connection from 172.18.0.2:48776.
GET / HTTP/1.1
Host: {REDACTED_HOST}.com
Connection: close
X-Real-IP: {REDACTED_PUBLIC-IP}
X-Forwarded-For: {REDACTED_PUBLIC-IP}
X-Forwarded-Proto: https
X-Forwarded-Ssl: on
X-Forwarded-Port: 443
cache-control: max-age=0
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cookie: _t=azl2WkpyN1hgbENOd3pyZ1d6V3ZXUT....
root@ubuntu-vm-dev-app:/var/log/nginx#
Una muestra de mi configuración de Nginx generada desde el contenedor nginx-proxy es la siguiente:
root@975ea34d56a6:/etc/nginx/conf.d# cat default.conf
# nginx-proxy version : 0.10.0-11-g42c8b0c
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header based on $proxy_x_forwarded_proto
map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl {
default off;
https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$upstream_addr"';
access_log off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
resolver 127.0.0.11;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen 80;
access_log /var/log/nginx/access.log vhost;
return 503;
}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen 443 ssl http2;
access_log /var/log/nginx/access.log vhost;
return 503;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
# {REDACTED_DOMAIN}.com
upstream {REDACTED_DOMAIN}.com {
## Can be connected with "nginx-proxy" network
# app
server 172.18.0.4:80;
}
server {
server_name {REDACTED_DOMAIN}.com;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
# Do not HTTPS redirect Let'sEncrypt ACME challenge
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
auth_request off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name {REDACTED_DOMAIN}.com;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/{REDACTED_DOMAIN}.com.crt;
ssl_certificate_key /etc/nginx/certs/{REDACTED_DOMAIN}.com.key;
ssl_dhparam /etc/nginx/certs/{REDACTED_DOMAIN}.com.dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/certs/{REDACTED_DOMAIN}.com.chain.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
include /etc/nginx/vhost.d/default;
location / {
proxy_pass http://{REDACTED_DOMAIN}.com;
}
}
Me pregunto si alguien ha logrado que esto funcione o si tiene alguna idea sobre métodos para depurar el error 502 que estoy recibiendo. Sé que el error puede deberse a varias variables, pero si han encontrado esto al configurar Discourse o configuraciones similares a la mía, su solución podría ser de ayuda.
Gracias.



