es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Contenedor de Nginx como proxy para el contenedor de la aplicación Flask: problema con el dominio y el método Flask.redirect().

Tengo una aplicación Flask en el primer contenedor y NGINX en el segundo, ambos alojados en el mismo servidor. En NGINX quiero tener un proxy al primer contenedor, el cual no tiene puertos expuestos porque quiero que NGINX sirva la aplicación con HTTPS. Mi nginx.conf se ve así:

http {
    server {
        server_name hostname.dominio;
        listen 443 ssl;
        ssl_certificate /hostname_dominio.cer;
        ssl_certificate_key /hostname_dominio.key;
        location / {
            proxy_pass http://172.17.0.5:80;  # IP del contenedor de la aplicación Flask
        }
    }
}

La aplicación funciona bien cuando ingreso a https://hostname.dominio, pero cuando activo el método de redireccionamiento de Flask, como este:

return redirect(url_for("view.whatever"))

me redirecciona a http://172.17.0.5/whatever en lugar de https://hostname.dominio/whatever. ¿Cómo puedo solucionarlo y qué está causando este comportamiento? ¡Gracias por cualquier respuesta!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es con la generación de URL de Flask. Flask genera URLs basadas en la URL de la solicitud, y en este caso, dado que la solicitud proviene del servidor NGINX, Flask genera una URL con la dirección IP del servidor NGINX (172.17.0.5) en lugar del nombre de host de dominio que queremos.

    Para solucionar esto, debemos indicarle a Flask que genere URLs basadas en los encabezados X-Forwarded-Proto y X-Forwarded-Host que establece NGINX al reenviar las solicitudes al contenedor de la aplicación Flask. Para hacer esto, debemos agregar las siguientes líneas a nuestro archivo nginx.conf:

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    

    Esto configura NGINX para establecer los encabezados X-Forwarded-Proto y X-Forwarded-Host con los valores apropiados para la solicitud, y reenviar esos encabezados al contenedor de la aplicación Flask.

    Luego, debemos indicarle a Flask que utilice estos encabezados al generar URLs. Podemos hacer esto configurando los valores de configuración SERVER_NAME y PREFERRED_URL_SCHEME en nuestra aplicación Flask:

    from flask import Flask, redirect, url_for
    
    app = Flask(__name__)
    app.config['SERVER_NAME'] = 'nombredehost.dominio'
    app.config['PREFERRED_URL_SCHEME'] = 'https'
    
    @app.route('/')
    def index():
        return "Hola, mundo!"
    
    @app.route('/redireccionar')
    def vista_redireccionar():
        return redirect(url_for('index'))
    

    Al configurar SERVER_NAME con nuestro valor de nombre de host de dominio y PREFERRED_URL_SCHEME con ‘https’, Flask generará URLs con el nombre de host y el protocolo correctos cuando usemos url_for y redirect.

    Con estos cambios, nuestra configuración de NGINX se vería así:

    http {
        server {
            server_name nombredehost.dominio;
            listen 443 ssl;
            ssl_certificate /ruta/certificado_de_nombredehost.dominio;
            ssl_certificate_key /ruta/clave_de_nombredehost.dominio;
            location / {
                proxy_pass http://flask:5000;  # Nombre de host del contenedor de la aplicación Flask
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Host $host;
            }
        }
    }
    

    Ten en cuenta que hemos cambiado el valor de proxy_pass para utilizar el nombre de host del contenedor de la aplicación Flask en lugar de su dirección IP. También hemos agregado las directivas proxy_set_header para reenviar los encabezados necesarios a la aplicación Flask.

    Con estos cambios, la redirección de Flask debería funcionar según lo esperado y redirigir a https://nombredehost.dominio/loquesea.

Comments are closed.