I am trying to setup a django project on my server and cannot get it to run. I am using virtualenv, gunicorn and nginx for static files. I am not sure were I am going wrong. My current setup is as follows:
myenv
- project(my django project)
- bin(and all it contains)
- lib(and all it contains)
- include(and all it contains)
- gunicorn_config.py
gunicorn_config.py:
command = '/home/me/django/myenv/bin/gunicorn'
pythonpath = '/home/me/django/myenv/project'
bind = '127.0.0.1:80'
workers = 2
nginx project.conf:
upstream project_server {
server unix:/tmp/gunicorn_project.sock fail_timeout=0;
}
server {
listen 80;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name project.com www.project.com;
keepalive_timeout 5;
# path for static files
root /home/me/django/myenv/assets;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://project_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/me/django/myenv/project/project/templates;
}
}
And I run the following to try start it all up:
/home/me/django/myenv/bin/gunicorn -c /home/me/django/myenv/gunicorn_config.py project/project/wsgi.py
But it just says "Can't connect to ('127.0.0.1', 80)"
You've configured gunicorn to bind on a TCP port, but gunicorn is binding on a unix socket. You should use the same thing; preferably the socket, so it doesn't conflict with the port nginx is actually listening on.
In gunicorn_config.py:
bind = 'unix:/tmp/gunicorn_project.sock'
Basically, I would guess nginx spins up before gunicorn. It takes port 80 (from your listen). gunicorn comes next, also wants port 80 (from your bind), and finds it occupied so it errors out. Run gunicorn on a different port and use proxy_pass to tell nginx about it.
Gunicorn
bind = '127.0.0.1:8000'
Nginx
proxy_pass http://127.0.0.1:8000/;
Related
I have a setup with Nginx as web server and Gunicorn as application server serving a Django REST API.
Nginx is listening at port 80 and gunicorn at port 8000 (I launch gunicorn using this command):
gunicorn --bind 0.0.0.0:8000 cdm_api.wsgi -t 200 --workers=3
and when I launch the petition to port 8000, I am able to access to the API running for instance:
curl -d "username=<user>&password=<pass>" -X POST http://127.0.0.1:8000/api/concept
However, when I try to make the petition though Nginx acting as reverse proxy, I get 404 Not Found Error:
curl -d "username=<user>&password=<pass>" -X POST http://127.0.0.1:80/api/concept
Here is my nginx conf file:
server {
listen 80;
listen [::]:80;
server_name 127.0.0.1;
location /api/ {
proxy_pass http://127.0.0.1:8000/api/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
Let me know if more information is needed. Thanks in advance!
So
gunicorn will create a sock file and you will have to map your proxy_pass with the sock file created, for now you are mapping to your localhost:8000 for this you will have to run the django runserver command so that nginx can find a server running on port 8000.
something like -
location / {
include proxy_params;
#proxy_pass http://unix:/home/abc/backend/social.sock;
proxy_pass http://unix:/home/abc/backend/backend.sock;
}
gunicorn make it possible to serve django at production, you don't have to command runserver everytime. Make sure gunicorn restarts everytime when server reboots.
I'm trying to set up a simple blogging site that I wrote using the django framework. The website works except that it isn't serving static files. I imagine that's because nginx isn't running. However, when I configure it to run on any port other than 80 I get the following error:
nginx: [emerg] bind() to 172.17.0.1:9000 failed (99: Cannot assign requested address)
When I run it on a port that is already being used by gunicorn I get the following error:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
My nginx configuration file is as follows:
upstream django {
server 127.0.0.1:8080;
}
server {
listen 172.17.0.1:9000;
server_name my.broken.blog;
index index.html;
location = /assets/favicon.ico { access_log off; log_not_found off; }
location /assets {
autoindex on;
alias /var/www/html/mysite/assets;
}
location / {
autoindex on;
uwsgi_pass unix:///run/uwsgi/django/socket;
include /var/www/html/mysite/mysite/uwsgi_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
But if I run nginx without starting guincorn it runs properly but I get a 403 forbidden error.
Going with the suggested answer I don't get any errors, but the site is returning 403 forbidden and doesn't present the part of the website gunicorn is supposed to deliver.
Configure Nginx and Gunicorn in following way to make it work,
Use unix socket to comminicate between nginx and gunicron rather than running gunicorn in some port
Create a unit file for gunicorn in the following location
sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=nginx
WorkingDirectory=/path-to-project-folder
ExecStart=/<path-to-env>/bin/gunicorn --workers 9 --bind unix:/path-to-sockfile/<blog>.sock app.wsgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then start and enable gunicorn service
It will generate a sock file in the specified path.
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
Note: Choose the suitable number of workers for gunicorn, can sepecify log files as follows
ExecStart=//bin/gunicorn --workers 9 --bind unix:/path-to-sockfile/.sock app.wsgi:application --access-logfile /var/log/gunicorn/access.log --error-logfile /var/log/error.log
create a new configuration file specific to the project in /etct/nginx rather than edit the default nginx.conf
nano /etc/nginx/blog.conf
and add the following lines ( can also add the file in /etc/nginx/default.d/)
server {
listen 80;
server_name 172.17.0.1; # your Ip
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /path-to-static-folder;
}
location /media/ {
root /path-to-media-folder;
}
location / {
proxy_set_header Host $http_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;
proxy_pass http://unix:/path-to-sock-file/<blog-sock-file>.sock;
}
}
include the /etc/nginx/blog.conf to nignx.conf
---------
----------
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/blog.conf; # the new conf file added
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
------
-------
run sudo nginx -t // to check for errors in nginx configuration.
run sudo systemctl nginx restart
refer: https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
I know many others have asked the same question, but I haven't found any answers that are relevant or work for me. If you do know of a duplication, feel free to direct me to it.. I'm getting lost in the maze of nginx threads!
I am new to this and used the following tutorials to set up my django site with gunicorn and nginx:
https://vahiwe.medium.com/deploy-django-and-flask-applications-in-the-cloud-using-nginx-gunicorn-and-systemd-centos-7-4b6aef3a8578
https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-centos-7
My website works if I access it via the IP address but I get a Bad Request error when I try by the domain name.
In nginx.conf my server block looks like:
server {
listen 80;
server_name 123.456.78.910 mywebsite.com www.mywebsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /var/www/userf/website;
}
location / {
proxy_set_header Host $http_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;
proxy_pass http://unix:/var/www/userf/website/website.sock;
}
}
My gunicorn.service file is:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ssej91D
Group=nginx
WorkingDirectory=/var/www/ssej91D/pwebsite
ExecStart=/var/www/userf/website/env/bin/gunicorn --workers 3 --error-logfile - --bind unix:/var/www/userf/website/website.sock website.wsgi:application
EnvironmentFile=/var/www/userf/website/.env
[Install]
WantedBy=multi-user.target
And my ALLOWED_HOSTS in django's settings.py:
ALLOWED_HOSTS = ["mywebsite.com", "www.mywebsite.com", "123.456.78.910"]
I have not added any SSL related settings to the Django settings file yet.
To test the domain name, I've tried making a test index.html file in another directory (let's call it testwebsite and then changing the nginx.conf to:
server {
listen 80;
server_name 123.456.78.910 mywebsite.com www.mywebsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location / {
root /var/www/userf/testwebsite;
}
}
This worked perfectly. My domain name showed index.html.
I've checked the logs, and they are always empty. I'll be totally honest, I just copied all of the proxy server settings from the tutorial and I don't actually understand them. I guess my suspicion is I'm doing something wrong in setting up nginx as a proxy server.
Any help would be very appreciated.
Thanks
I was missing a host in the ALLOWED_HOSTS list.
The host name of the droplet I'm using is different because I'm sharing it.
I am currently working on deploying my project over https however I am running into some issues. I have it working with http but when I try to incorporate the ssl it breaks. I think I am misconfiguring the gunicorn upstream client in my nginx block but I am uncertain. Could the issue be in the unix binding in my gunicorn service file? I am very new to gunicorn so I'm a little lost.
Here is my configuration below.
Gunicorn:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
Environment=PYTHONHASHSEED=random
User=USER
Group=www-data
WorkingDirectory=/path/to/project
ExecStart=/path/to/project/project_env/bin/gunicorn --workers 3 --bind unix:/path/to/project/project.sock project.wsgi:application
[Install]
WantedBy=multi-user.target
Nginx (working-http):
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /path/to/project;
}
location / {
include proxy_params;
proxy_pass http://unix:/path/to/project/project.sock;
}
}
Nginx (https):
upstream server_prod {
server unix:/path/to/project/project.sock fail_timeout=0;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain;
}
server {
server_name server_domain;
listen 443;
ssl on;
ssl_certificate /etc/ssl/server_domain.crt;
ssl_certificate_key /etc/ssl/server_domain.key;
location /static/ {
root /path/to/project;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://server_prod;
break;
}
}
}
Your gunicorn systemd unit file seems OK. Your nginx is generally OK too. You have posted too little info to get an appropriate diagnostic. I'm guessing you are missing passing the X-Forwarded-Proto header to gunicorn, but it could be something else. Here's an nginx configuration file that works for me:
upstream gunicorn{
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
# for UNIX domain socket setups:
server unix:/path/to/project/project.sock fail_timeout=0;
# for TCP setups, point these to your backend servers
# server 127.0.0.1:9000 fail_timeout=0;
}
server {
listen 80;
listen 443 ssl http2;
server_name server_domain;
ssl_certificate /etc/ssl/server_domain.crt;
ssl_certificate_key /etc/ssl/server_domain.key;
# path for static files
root /path/to/collectstatic/dir;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When Nginx is handling SSL it is helpful to pass the protocol information
# to Gunicorn. Many web frameworks use this information to generate URLs.
# Without this information, the application may mistakenly generate http
# URLs in https responses, leading to mixed content warnings or broken
# applications. In this case, configure Nginx to pass an appropriate header:
proxy_set_header X-Forwarded-Proto $scheme;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
proxy_pass http://gunicorn;
}
}
Iam new to nginx.
I have configured nginx,gunicorn and django.
when i start nginx, it gives an error as,
404 Not Found
nginx/1.1.19
as it is not pointing to django.
Now i need to point out nginx to django(using gunicorn as middleware) in conf file using location or root.
Can anyone tell me how to point out nginx to django.
Thank you
I've got many Apps running like this:
server {
# listen, statics, media, etc
location / {
proxy_pass http://127.0.0.1:8000; # Gunicorn Server
}
}
First, you need to actually have the gunicorn process running. Do this either manually, or ideally using a process management tool such as supervisord. Here's a sample supervisord script that runs a gunicorn process on a django project:
[program:example]
user=ubuntu
group=ubuntu
directory=/home/ubuntu/dev/example
command=python manage.py run_gunicorn -c gunicorn_config.py
autostart=true
autorestart=true
redirect_stderr=True
Then you need a proper nginx conf. Here's a minimal sample based off a site running in production:
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
server_name example.com;
location / {
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# use this if you're serving static assets locally
location /static/ { # make sure this is your STATIC_ROOT
alias /home/ubuntu/dev/example/static/;
access_log off;
}
}