Reputation: 807
I've EC2 Ubuntu 18.04 Server with Python Flask framework running on Gunicorn
application server with Nginx
reverse proxy listening on port 80 & 443. I've added LetsEncrypt
for the domain using certbot.
The website works fine without ssl. With LetsEncrypt
ssl configuration on Nginx
the server fails to load the page.
My previous supervisor
and Nginx
configuration without ssl support is as follows and Nginx
works with gunicorn
with no issues.
server {
listen 80;
server_name example.com www.example.com;
location /static {
alias /home/ubuntu/myapp-backend/myapp/static;
}
location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
}
[program:myapp]
directory=/home/ubuntu/myapp-backend
command=/home/ubuntu/myapp-backend/venv/bin/gunicorn -w 5 run:app
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/myapp/myapp.err.log
stdout_logfile=/var/log/myapp/myapp.out.log
When I change the Nginx
configuration to include LetsEncrypt
support while listening on port 80 & 443, the website doesn't show up.. It shows indefinite 301 redirects requests.
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /static {
alias /home/ubuntu/myapp-backend/myapp/static;
}
location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
}
When I load the site example.com
, it redirects to https:\\www.example.com
. However the website homepage doesn't load or show any response from server/Nginx. When I login to the server and run curl -v localhost:8000
, the the gunicorn works fine.
curl -v localhost:8000
* Rebuilt URL to: localhost:8000/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 500 INTERNAL SERVER ERROR
< Server: gunicorn/19.9.0
< Date: Sat, 28 Sep 2019 14:14:47 GMT
< Connection: close
< Content-Type: text/html; charset=utf-8
< Content-Length: 27911
<
<!doctype html>
...
There was earlier Stackoverflow question on gunicorn
over ssl with ssl parameters which can be added to supervisor
config.
I believe the error must be with on Nginx
configuration on port 443 or Gunicorn
supervisor
config info. If you could have a look, I would appreciate it.
Upvotes: 0
Views: 1211
Reputation: 7621
You have too many server
blocks
The second block in your configration with SSL, catches connections to 443
and redirects them to the https://
URL. Thus causing the infinite loop:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 301 https://www.example.com$request_uri;
}
This 301
should only be returned when the user hits the server on port 80
. That's what the first server
block in this config file actually does.
Remove this whole block and it should probably work. You already have the third server block configured to (correctly) catch traffic to 443
and proxy it to gunicorn.
There was earlier Stackoverflow question on gunicorn over ssl with ssl parameters which can be added to supervisor config. I believe the error must be with on Nginx configuration.
You are terminating SSL at nginx, then proxying to gunicorn in plain HTTP (which is the correct way to operate with nginx involved). The question you linked there is about adding native SSL support to gunicorn, so that gunicorn terminates SSL. This would only be required if your internet based users connect directly to the gunicorn server.
Upvotes: 1