Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Gunicorn - HTTP and HTTPS in the same instance?

988 views
Skip to first unread message

Skip Montanaro

unread,
Jan 7, 2022, 1:52:59 PM1/7/22
to
Hopefully some Pythonistas are also Gunicornistas. I've had little success
finding help with a small dilemma in the docs or in other more specific
sources.

I'm testing out a new, small website. It is just Gunicorn+Flask. I'd like
to both listen for HTTP and HTTPS connections. Accordingly, in my config, I
have the Gunicorn process bind to both ports 80 and 443 if running as root:

if IAM_ROOT:
bind = [
'0.0.0.0:443',
'0.0.0.0:80',
]
else:
bind = [
'0.0.0.0:8080',
]

Gunicorn listens on both ports, but insists on SSL/TLS chit chat over port
80, not just port 443 (which seems to work okay). Is there some magic
incantation to get it to just talk HTTP on port 80, or will I need to spin
up two instances? (The non-root config works fine - plain old HTTP over
port 8080.)

Thx,

Skip

Kushal Kumaran

unread,
Jan 7, 2022, 8:54:55 PM1/7/22
to
It is not possible to do this. The ssl-ness is a global configuration,
and will apply to all of the listening sockets gunicorn creates. To get
what you want, you need to run multiple instances, as you say, if you
can run those safely.

The recommended way to deploy gunicorn, though, is to front it with a
reverse proxy such as nginx. You'd configure nginx (or whatever proxy
you choose) to listen on the interfaces/ports you want, and
enable/disable TLS as required. Example for configuring nginx is at
https://docs.gunicorn.org/en/latest/deploy.html, although that
particular example does not talk about TLS.

--
regards,
kushal

Albert-Jan Roskam

unread,
Jan 8, 2022, 8:00:36 AM1/8/22
to
I always use NGINX for this. Run Flask/Gunicorn on localhost:5000 and have
NGINX rewrite https requests to localhost requests. In nginx.conf I
automatically redirect every http request to https. Static files are
served by NGINX, not by Gunicorn, which is faster. NGINX also allows you
to easily set the transfer encoding to gzip
Albert-Jan

Skip Montanaro

unread,
Jan 8, 2022, 11:26:07 AM1/8/22
to
Thanks all. I was hoping to get away without something more
sophisticated like NGINX. This is just a piddly little archive of an
old mailing list running on a single-core Ubuntu VM somewhere on the
East Coast. Speed is not a real requirement. Load balancing seemed
like overkill to me. Still, I guess if it has to be, then it has to
be.

Skip

Kirill Ratkin

unread,
Jan 8, 2022, 1:49:41 PM1/8/22
to

Hi.
You probably can solve issue on Gunicorn side. But afaik better solution is to use http proxy before Gunicorn. This proxy accepts https connection and proxy requests to Gunicorn instances as plain http.

This approach gives you:
a) Monitoring on network layer (tcpdump/wireshark shows you req/res on Gunicorn instance)
b) Scalability (proxy can spread traffic on several Gunicorn instances)
c) Maintenance (you can gracefully shutdown/restart Gunicorn instances one by one)
d) Security (For example SSL certificate is configured in proxy only. There are another useful features which such proxy can do: simple authentication, ddos/fail2ban and so on)

Quite often NGINX is better choice for such proxy. But apache is good as well.

Best regards.
Kirill

От: Skip Montanaro
Отправлено: 7 января 2022 г. в 21:54
Кому: Python
Тема: Gunicorn - HTTP and HTTPS in the same instance?

Hopefully some Pythonistas are also Gunicornistas. I've had little success
finding help with a small dilemma in the docs or in other more specific
sources.

I'm testing out a new, small website. It is just Gunicorn+Flask. I'd like
to both listen for HTTP and HTTPS connections. Accordingly, in my config, I
have the Gunicorn process bind to both ports 80 and 443 if running as root:

if IAM_ROOT:
bind = [
'0.0.0.0:443',
'0.0.0.0:80',
]
else:
bind = [
'0.0.0.0:8080',
]

Gunicorn listens on both ports, but insists on SSL/TLS chit chat over port
80, not just port 443 (which seems to work okay). Is there some magic
incantation to get it to just talk HTTP on port 80, or will I need to spin
up two instances? (The non-root config works fine - plain old HTTP over
port 8080.)

Thx,

Skip
--
https://mail.python.org/mailman/listinfo/python-list

Lars Liedtke

unread,
Jan 10, 2022, 5:31:41 AM1/10/22
to
I think this is more a thing of apporach. Nginx is quite simple to
install and a config doing nothing else than redirecting https to https
and proxying requests to a service (whichever tat is, in your case
gunicorn) can become a nobrainer. That is what it became for me.
Additionally the config for only this functionality are less than 10. So
it's may seem complicated at first, but is way less oncxe you got used
to it.

Cheers

Lars

Am 08.01.22 um 17:25 schrieb Skip Montanaro:
--
punkt.de GmbH
Lars Liedtke
.infrastructure

Kaiserallee 13a
76133 Karlsruhe

Tel. +49 721 9109 500
https://infrastructure.punkt.de
in...@punkt.de

AG Mannheim 108285
Geschäftsführer: Jürgen Egeling, Daniel Lienert, Fabian Stein

Lars Liedtke

unread,
Jan 10, 2022, 1:06:02 PM1/10/22
to
server {
   listen [::]:80;
   listen 80;


   server_name api.familie-liedtke.net;

   location / {
       return 301 https://$host$request_uri;
   }

   include /usr/local/etc/nginx/include/letsencrypt.conf;
}

server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;

   server_name api.familie-liedtke.net;

   ssl_certificate
/usr/local/etc/ssl/certs/api.familie-liedtke.net/fullchain.pem;
   ssl_certificate_key
/usr/local/etc/ssl/certs/api.familie-liedtke.net/privkey.pem;

   root /var/www/api;

   location /weather/{
       access_log /var/log/nginx/weather-access.log;
       include uwsgi_params;
       rewrite ^/weather(/.*)$ $1 break;
       uwsgi_pass unix:///tmp/uwsgi.sock;
   }

   include /usr/local/etc/nginx/include/ssl.conf;
}

This is my config for a flask app on uwsgi. granted it is a bit more
than the 10 lines I said. But there is not much sophistication to it.
0 new messages