2

I have a flask app running in docker, and setup nginx with Let’s Encrypt. I've added proxy_set_header X-Forwarded-Proto $scheme; to my nginx config, but url_for still returns http url instead https url. But the issue only occurs when running in docker.

This is my nginx config:

server {
    listen 443 ssl default_server;
    ssl_certificate /etc/letsencrypt/live/markote.app/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/markote.app/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        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 $scheme;
    }
}

and my docker file:

FROM python:3.6-slim

WORKDIR /app

ADD . /app

RUN apt update
RUN apt install -y curl sudo gnupg libcairo2-dev
RUN pip install gunicorn
RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
RUN sudo apt-get install -y nodejs

RUN python setup.py install
RUN npm install
RUN npm run build

EXPOSE 5000

CMD [ "gunicorn", "-c", "gunicorn.py", "wsgi:app" ]

If I run gunicorn -c gunicorn.py wsgi:app & instead of sudo docker run -d -p 5000:5000 my/repo, url_for can generate https successfully. Do I miss something?

Xiaodan Mao
  • 1,648
  • 2
  • 17
  • 30

1 Answers1

1

I know it's been a while but you could try url_for('endpoint', _schema='https')

heyon
  • 26
  • 3
  • I'll give it a try. Thanks! – Xiaodan Mao May 31 '19 at 00:01
  • 1
    I just found another solution for this. The `_schema` attribute will work for the individual link alone however, if you don't want to do this for every single url, you can create a wsgi middleware that sets the `wsgi.url_scheme` attribute. Take a look at this snippet for how to do it: http://flask.pocoo.org/snippets/35/ Just make sure you put something like `environ['wsgi.url_scheme'] = 'https'` in the `__call__` function for your middleware. – heyon May 31 '19 at 15:28