Sample Nginx configuration
I am attempting to install my own mygpo backend on my home server. It is ~95% working. I think some of the issues I'm continuing to bump in to may be related to my Nginx configuration. Here is what I have so far.
server {
listen 80;
server_name podcast.myservice.com;
location / {
proxy_pass http://192.168.1.23:8080/;
}
location /static {
alias /home/gpodder/mygpo/staticfiles/;
}
location /favicon.png {
alias /home/gpodder/mygpo/static/favicon.png;
}
}
The service is started with systemd using the following ExecStart command.
/home/gpodder/mygpo/venv/bin/envdir /home/gpodder/mygpo/envs/prod /home/gpodder/mygpo/venv/bin/daphne --bind 192.168.1.23 --port 8080 mygpo.asgi:application
Any help would be appreciated.
Could you describe, what the Issues are? Error messages? Logfiles? What do you expect to happen and what happens instead?
So at first I assumed the problem was my Nginx config. After doing a lot of reading I don't think that is the case any more.
Here is a good example of the kinds of problems that I am seeing. If I try to add a new podcast at https://podcast.baucum.me/missing/ by putting in the URL http://feeds.wnyc.org/science-friday, clicking check, and then "Add Podcast", it hangs and eventually gives me "502 Bad Gateway" error. The curl for the request looks like this, with the tokens removed.
curl 'https://podcast.baucum.me/add-podcast/' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: null' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Cookie: csrftoken=removed; sessionid=removed' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-GPC: 1' -H 'TE: Trailers' --data-raw 'csrfmiddlewaretoken=removed&url=http%3A%2F%2Ffeeds.wnyc.org%2Fscience-friday'
This is what I have after using certbot to install certificates, hope it may help:
server {
server_name xxx;
# Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)
add_header Strict-Transport-Security "max-age=172800; includeSubdomains";
# This checks if the certificate has been invalidated by the certificate authority
# You can remove this section if you use self-singed certificates...
# Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox)
ssl_stapling on;
ssl_stapling_verify on;
# - - - - - - - - -
# Reverse Proxy
# - - - - - - - - -
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr; # clients real IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # a proxy did forward this request
proxy_set_header Host $http_host; # Set Proxy host info
proxy_http_version 1.1; # Required for WebSocket connection
proxy_set_header Upgrade $http_upgrade; # Allow protocol switch to websocket
proxy_set_header Connection "upgrade"; # Do protocol switch
proxy_set_header X-Forwarded-Proto $scheme; # this connection used HTTP or HTTPS
client_max_body_size 500M; # Bump the max body size
proxy_buffering off; # Do not hold back the request while the client sends data, give the stream directly
location / {
proxy_pass http://localhost:8000;
}
location /favicon.png {
alias /var/www/mygpo/static/favicon.png;
}
location /media {
alias /var/www/mygpo/media; # your Django project's media files - amend as required
}
location /static {
alias /var/www/mygpo/static; # your Django project's static files - amend as required
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/xxx/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
}
server {
if ($host = xxx) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name xxx;
listen 80;
return 404; # managed by Certbot
}
Adapted it from other projects, so there are stuffs that are probably not needed.
I updated my Nginx config to be similar to what you provided here is my new config
server {
listen 80;
server_name podcast.xx.x;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 500M;
proxy_buffering off;
location / {
proxy_pass http://127.0.0.1:8080;
}
location /static {
alias /home/gpodder/mygpo/staticfiles/;
}
location /favicon.png {
alias /home/gpodder/mygpo/static/favicon.png;
}
location /media {
alias /home/gpodder/mygpo/media;
}
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
}
It's worth noting that the machine this is running on is not facing the Internet. I have it locked down with UFW such that it only accepts requests on port 80 from the Internet facing proxy machine.
On the proxying machine nginx looks like this.
server {
listen 80;
server_name podcast.xx.x;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/xx.x/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xx.x/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/xx.x/chain.pem;
server_name podcast.xx.x;
proxy_set_header X-Forwarded-For $remote_addr;
location / {
proxy_pass http://192.168.1.23/;
proxy_set_header Host podcast.xx.x;
}
access_log /var/log/nginx/gpodder_access.log;
error_log /var/log/nginx/gpodder_error.log warn;
}
And finally here is my latest systemd configuration.
[Unit]
Description=gpodder podcast server
[Service]
Restart=on-failure
WorkingDirectory=/home/gpodder/mygpo
ExecStart=/home/gpodder/mygpo/venv/bin/envdir /home/gpodder/mygpo/envs/prod /home/gpodder/mygpo/venv/bin/gunicorn mygpo.wsgi -b 127.0.0.1:8080 --workers=2
User=gpodder
StandardOutput=append:/var/log/gpodder/gpodder.log
StandardError=append:/var/log/gpodder/error.log
[Install]
WantedBy=multi-user.target
Here is what I get in the gpodder error log.
[2021-02-17 04:21:01 +0000] [1751870] [CRITICAL] WORKER TIMEOUT (pid:1751926)
[2021-02-17 04:21:01 +0000] [1751926] [INFO] Worker exiting (pid: 1751926)
[2021-02-17 04:21:02 +0000] [1752831] [INFO] Booting worker with pid: 1752831
2021-02-17 04:21:02,401 django.request WARNING Not Found: /favicon.ico
All help is greatly appreciated.