I'm trying to deploy a django project with uWSGI and nginx. I have the next configuration files:
uwsgi.ini
[uwsgi]
#Django-related settings
chdir = /home/amlalchy/api_aml_platform
module = api.wsgi
#static-map = /static=/home/amlalchy/api_aml_platform/services/static
#Process-related settings
master = true
processes = 10
# The socket(use the full path to be safe)
socket = /tmp/aml.sock
chmod-socket = 664
uid = www-data
gid = www-data
# Clear environment on exit
vacuum = true
uwsgi.service
[Unit]
Description=uWSGI Emperor service
After=network.target
[Service]
#User=amlalchy
#Group=www-data
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown amlalchy:www-data /run/uwsgi'
ExecStart=/bin/bash -c 'cd /home/amlalchy/api_aml_platform && source /home/amlalchy/anaconda3/bin/activate AmlPlatform && uwsgi --ini /etc/uwsgi/sites/uwsgi.ini'
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target
api.conf for the nginx configuration
server {
listen 80;
server_name server.prueba.com;
charset utf-8;
client_max_body_size 128M;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
root /home/amlalchy/api_aml_platform/services;
}
location /media {
root /home/amlalchy/api_aml_platform;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/aml.sock;
uwsgi_read_timeout 300s;
uwsgi_send_timeout 300s;
}
}
I'm getting this error in /var/log/enginx/error.log :
2020/01/13 10:30:12 [error] 12641#12641: *1 open() "/home/amlalchy/api_aml_platform/services/static/css/global.css" failed (2: No such file or directory), client: 127.0.0.1, server: server.prueba.com, request: "GET /static/css/global.css HTTP/1.1", host: "127.0.0.1", referrer: "http://127.0.0.1/api/login/
I am newbie and I don't know what I'm missing because the static files exists... so I would be really grateful for any tip on my error.
Thanks in advance.
Where are your static files (css/js/images)? How do you deploy them?
As #ruddra suggested, how do you run your?
./manage.py collectstatic
Related
I am trying to deploy django with gunicorn and nginx on heroku, and i'm kinda confused with the way to config gunicorn and nginx, when i searched through internet, they usually create gunicorn.socket
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
and gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
but when i go to gunicorn docs : https://docs.gunicorn.org/en/stable/deploy.html. nginx has a config file like this
worker_processes 1;
user nobody nogroup;
# 'user nobody nobody;' for systems with 'nobody' as a group instead
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
# 'use epoll;' to enable for Linux 2.6+
# 'use kqueue;' to enable for FreeBSD, OSX
}
http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
sendfile on;
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
server unix:/tmp/gunicorn.sock fail_timeout=0;
# for a TCP configuration
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name example.com www.example.com;
keepalive_timeout 5;
# path for static files
root /path/to/app/current/public;
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 X-Forwarded-Proto $scheme;
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;
proxy_pass http://app_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /path/to/app/current/public;
}
}
}
So i wonder what the different between these and which is the best way to setup gunicorn, nginx.
Thanks
you can try following steps to deploy django project using nginx, supervisor and gunicron
1- Create new gunicorn script in /myprojectenv/bin/script name e.g gunicorn_start
#!/bin/bash
NAME="myproject"
DJANGODIR=/home/sammy/myprojectdir/myproject
SOCKFILE=/home/sammy/myprojectdir/myproject/run/proj_name.sock
USER=sammy
GROUP=www-data
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=myproject.settings
DJANGO_WSGI_MODULE=myproject.wsgi
echo "Starting $NAME as whoami"
cd $DJANGODIR
source ../myprojectenv/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
exec ../myprojectenv/bin/gunicorn ${DJANGO_WSGI_MODULE}:application
--name $NAME
--workers $NUM_WORKERS
--user=$USER --group=$GROUP
--bind=unix:$SOCKFILE
--log-level=debug
--log-file=-
2- Install supervisorctl
pip or yum install supervisor
3- Create conf file under /etc/supervisor.d
Example config file
[program:myproject]
directory=/home/sammy/myprojectdir/myproject
command=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn_start --workers 3 --bind uxix:/home/sammy/myprojectdir/myproject/run/proj_name.sock myproject.wsgi:application
autostart=true
autorestart=true
stderr_logfile=/home/sammy/myprojectdir/myproject/Logs/gunicorn_supervisor.log
stdout_logfile=/home/sammy/myprojectdir/myproject/Logs/gunicorn_supervisor.log
user=sammy
group=www-data
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8
4- Supervisorctl reread & supervisorctl update
5- nano /etc/nginx/site-available/app.conf
6- ln -s /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled
7- systemctl restart nginx
Please change folder names and path according to your project.
I am trying to deploy django project on digitalocean using nginx and gunicorn.
My project have the following structure
projects
|_isli
|_isli
|_forecast #project directory
|_manage.py
|_forecast.sock
|_forecast
|_wsgi.py
|_settings.py
|_urls.py
My project created inside root directory without creating additional sudo user. I know that isn't right solution but i decide so.
In my settings.py file inside allowed hosts i specified ip address
ALLOWED_HOSTS = ['165.22.23.233']
In official digitalocean docs have tutorial about deploying django using nginx and gunicorn Deploying django using Nginx and Gunicorn
in this article used method where gunicorn setted up as socet here is my setup /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/root/projects/isli/isli/forecast
ExecStart=/root/projects/isli/env/bin/gunicorn --log-level debug --error-logfile /var/log/gunicorn/error.log --access-logfile /var/log/gunicorn/access.log --workers 3 --bind unix:/root/projects/isli/isli/forecast/forecast.sock forecast.wsgi:application
[Install]
WantedBy=multi-user.target
after creating gunicorn.service file i run systemctl start gunicorn than systemctl enable gunicorn after it in my project directory was created forecast.sock file
Than i setup nginx in /etc/nginx/sites-available/forecast with following
server {
listen 165.22.23.233:80;
location = /favicon.ico {access_log off; log_not_found off;}
location / {
include proxy_params;
proxy_pass http://unix:/root/projects/isli/isli/forecast/forecast.sock;
}
}
Than systemctl restart nginx
When i am trying to access http://165.22.23.233:80 from browser its promt me 502 bad gateway. After it in /var/log/nginx/error.log file i see following
2020/02/09 16:29:01 [crit] 13533#13533: *11 connect() to unix:/root/projects/isli/isli/forecast/forecast.sock failed (
13: Permission denied) while connecting to upstream, client: 178.176.218.110, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/root/projects/isli/isli/forecast/forecast.sock:/", host: "165.22.23.233"
As i understood through this error my problem is that nginx can not access to /root/projects/isli/isli/forecast/forecast.sock file. After it i tried to check permissions to each entity of above path by
namei -nom /root/projects/isli/isli/forecast/forecast.sock
And here is output
f: /root/projects/isli/isli/forecast/forecast.sock
drwxr-xr-x root root /
drwx------ root root root
drwxr-xr-x root root projects
drwxr-xr-x root root isli
drwxr-xr-x root root isli
drwxr-xr-x root root forecast
srwxrwxrwx root root forecast.sock
In output above root user have permissions to each entity to my socket path but why error say me that permission denied
You need to separate listen from server_name:
server {
listen 80;
server_name 165.22.23.233; # (Example 192.168.0.1, example.com)
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /root/projects/isli/isli/forecast/;
}
location / {
include proxy_params;
proxy_pass http://unix:/root/projects/isli/isli/forecast/forecast.sock;
}
}
I'm using the Digital Ocean tutorial (here) to set up a app that allows for a file upload (videos ranging from 5 mb to 1 GB). I know that large file uploads is not an ideal use case, but the client and the server are sitting in neighboring buildings connected via LAN (fast speeds in transfer) and FTP was not an option provided to me.
When the files are small enough (30-40 mb), the app works fine. With 100 mb+ videos, I get a "502 - bad gateway" error on the client side.
Nginx error log shows the following:
2017/07/17 15:52:18 [error] 18503#18503: *9 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: <client-ip>, server: <my-hostname>, request: "POST /videos HTTP/1.1", upstream: "http://unix:/www/app/app.sock:/videos", host: "<my-hostname>", referrer: "<app-domain>/videos"
The Gunicorn error log shows no errors.
My gunicorn settings:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=django
Group=www-data
WorkingDirectory=/www/app
EnvironmentFile=/www/app/.env2
ExecStart=/home/django/.pyenv/versions/django/bin/gunicorn --access-logfile /backup/logs/app_gunicorn_access.log --error-logfile /backup/logs/app_gunicorn_errors.log --workers 3 --worker-class=tornado --timeout=600 --graceful-timeout=10 --log-level=DEBUG --capture-output --bind unix:/www/app/app.sock app.wsgi:application
[Install]
WantedBy=multi-user.target
What am I doing wrong?
EDIT ->
NGINX config
server {
listen 80;
server_name <my-hostname>;
rewrite ^/(.*) https://<my-domain>/$1 permanent;
}
server {
listen 443 ssl;
proxy_read_timeout 600s;
keepalive_timeout 5;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
server_name <my-hostname>;
client_max_body_size 0;
ssl_certificate /ssl_certs/hostname_bundle.cer;
ssl_certificate_key /ssl_certs/hostname.key;
root /www/app;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /www/app/staticfiles/;
}
location /media/ {
alias /backup/app_media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/www/app/app.sock;
include /etc/nginx/mime.types;
}
location /robots.txt {
alias /www/app/robots.txt;
}
}
Fixed the issue by changing the worker class from tornado to default (sync) workers while keeping the timeout long enough for large uploads to complete. Obviously there might be more elegant solutions to this issue, but I'm yet to come across anything. Exec line in gunicorn.service is as follows:
ExecStart=/home/django/.pyenv/versions/django/bin/gunicorn --access-logfile /backup/logs/app_gunicorn_access.log --error-logfile /backup/logs/app_gunicorn_errors.log --workers 3 --timeout=600 --graceful-timeout=10 --log-level=DEBUG --capture-output --bind unix:/www/app/app.sock app.wsgi:application
-I'm using a virtual machine with Ubuntu 12.04.3 LTS
-I'm doing a Django project with Uwsgi + nginx
-I added "192.168.33.50 myproject.com" to my hosts file
-I started uwsgi + supervisor + nginx process
-When I'm trying to access to myproject.com, I'm getting this error in /var/log/nginx/error.log:
2013/11/13 07:43:21 [crit] 14741#0: *1 connect() to
unix:/tmp/uwsgi_myproject.sock failed (2: No such file or
directory) while connecting to upstream, client: 192.168.33.1, s$
Edition 1
This is my uwsgi.ini:
[uwsgi]
module = myproject.wsgi:application
master workers = 3
logto = /vagrant/log/uwsgi.log
socket = /tmp/uwsgi_myproject.sock
pidfile = /tmp/uwsgi_myproject.pid chmod-socket = 666
auto-procname need-app vacuum
Edition 2
If I execute this command in console:
uwsgi --ini /vagrant/uwsgi.ini --chdir /vagrant/myproject/ --socket
/tmp/uwsgi_myproject.sock --pidfile /tmp/myproject.pid
With that command, uwsgi starts and I can access to myproject.com but it's supossed that uwsgi starts with supervisor of django
Edition 3
This is myproject.conf in /etc/nginx/conf.d/
server {
listen 80;
charset utf-8;
sendfile off;
# ONIX files
client_max_body_size 100M;
location /media/imagen {
include uwsgi_params;
#The uwsgi_pass must comply with the details in supervisord.conf
uwsgi_pass unix:/tmp/uwsgi_myproject.sock;
}
location /media/resources/protected {
root /vagrant/myproject/myproject;
internal;
}
location /media {
root /vagrant/myproject/myproject;
}
location /static {
root /vagrant/myproject/myproject;
}
location / {
include uwsgi_params;
#The uwsgi_pass must comply with the details in supervisord.conf
uwsgi_pass unix:/tmp/uwsgi_myproject.sock;
uwsgi_read_timeout 300;
}
}
EDITED: ADDED SUPERVISOR.CONF ASKED BY #ChrisC
[supervisord]
logfile={{ PROJECT_DIR }}/../log/supervisord.log
pidfile=/tmp/supervisor_PROJECTNAME.pid
user=PROJECTNAME
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8,LC_LANG=en_US.UTF-8
[unix_http_server]
file = /tmp/supervisor_PROJECTNAME.sock
[program:__defaults__]
directory={{ PROJECT_DIR }}
startsecs=5
[program:autoreload]
exclude=true
[program:uwsgi]
command=uwsgi --ini {{ PROJECT_DIR }}/../uwsgi.ini --chdir {{ PROJECT_DIR }} --socket /tmp/uwsgi_PROJECTNAME.sock --pidfile /tmp/uwsgi_PROJECTNAME.pid
stopsignal=INT
The problem was in the configuration of the supervisor. The supervisor wasn't loading the uwsgi process well.
when I try to access my site I only see 502 error.
Here's my nginx configuration:
upstream pzw_server {
# server unix:/home/pzw/pzw/run/gunicorn.sock fail_timeout=0;
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80;
server_name my_server_ip_addr;
client_max_body_size 4G;
access_log /home/pzw/pzw/log/nginx-access.log;
error_log /home/pzw/pzw/log/nginx-error.log;
location /static/ {
alias /home/pzw/pzw/static/;
}
location /media/ {
alias /home/pzw/pzw/media/;
}
location / {
try_files $uri #proxy;
}
location #proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://my_server_ip_addr;
}
}
Gunicorn startup script which I'm using:
#!/bin/bash
NAME='app_name'
DJANGODIR=/home/pzw/pzw
SOCKFILE=/home/pzw/pzw/run/gunicorn.sock
USER=pzw
GROUP=pzw
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=app_name.settings
VIRTENVDIR=/home/pzw/.virtualenvs/pzw
echo "STARTING $NAME"
cd $DJANGODIR
source "${VIRTENVDIR}/bin/activate"
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
exec "${VIRTENVDIR}/bin/gunicorn_django" \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--debug \
--log-level debug #\
# --bind=unix:$SOCKFILE
Nginx logs following error:
2013/08/03 23:26:04 [error] 8582#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: my_ip, server: my_server_ip, request: "GET / HTTP/1.1", upstream: "http://my_server_ip:80/", host: "my_server_ip"
When I try to connect to 127.0.0.1:8000 on my server using lynx everything seems to be fine. Initially I tried to use unix socket, but since it didn't work(same error), I switched to TCP. Gunicorn logs nothing about connection with nginx.
The proxy_pass directive in your nginx server configuration should reflect the upstream server you configured.
proxy_pass http://pzw_server;
http://wiki.nginx.org/HttpUpstreamModule
xaxes,
Whenever you set your TEMPLATE_DEBUG to False, you also need to set ALLOWED_HOSTS so that Django knows which hosts/domains to process requests for. Apparently, the localhost works implicitly when ALLOWED_HOSTS is just the empty list.
I hope this helps!