August 14, 2013

Advanced

How To Install and Configure Django with Postgres, Nginx, and Gunicorn

Prerequisites


This tutorial assumes you have already set up your droplet (VPS) with Debian 7 or a similar distro of Linux (such as Ubuntu). If you have not already done this, please follow the tutorial on setting up a droplet here.

For convenience, I've broken this tutorial into two parts. The first part (steps 1 - 6) covers installation only. If you are a more advanced Django user who just needs help getting things installed you can stop at step 6. If you already have everything installed and just want to know how to configure everything, then skip ahead to step 7. If you feel like you need help from start to finish, then just go through the steps in order and you should have no problems. Let's get started!

Step One: Update Packages


Before we do anything, we need to make sure that all the packages installed on our VPS are up to date. In order to do this, connect to your desired VPS via SSH and run the following commands:

sudo apt-get update

sudo apt-get upgrade

The first command downloads any updates for packages managed through apt-get. The second command installs the updates that were downloaded. After running the above commands if there are updates to install you will likely be prompted to indicate whether or not you want to install the updates. If this happens, just type "y" and then hit "enter" when prompted.

Step Two: Install and Create Virtualenv


Installing virtualenv is very simple. Just run the command below:

sudo apt-get install python-virtualenv

That's all there is to it! Now let's create our virtualenv so we can install Django and other Python packages within it:

sudo virtualenv /opt/myenv

Notice that a new directory "myenv" was created in the "/opt" directory. This is where our virtualenv will live. Make sure to replace "/opt/myenv" with the path to where you want your virtualenv installed. I typically put my env's in /opt, but this is strictly preference. Some people create a directory named "webapps" at the root of the VPS. Choose whatever method makes the most sense to you.

Step Three: Install Django


Now we need to activate our virtualenv so that when we install Python packages they install to our virtualenv. This is how you activate your virtualenv:

source /opt/myenv/bin/activate

You should now see that "(myenv)" has been appended to the beginning of your terminal prompt. This will help you to know when your virtualenv is active and which virtualenv is active should you have multiple virtualenv's on the VPS.

With your virtualenv active, we can now install Django. To do this, we will use pip, a Python package manager much like easy_install. Here is the command you will run:

pip install django

You now have Django installed in your virtualenv! Now let's get our database server going.

Step Four: Install PostgreSQL


Most Django users prefer to use PostgreSQL as their database server. It is much more robust than MySQL and the Django ORM works much better with PostgreSQL than MySQL, MSSQL, or others.

Since we don't need our virtualenv active for this part, run the following command to deactivate:

deactivate

This will always deactivate whatever virtualenv is active currently. Now we need to install dependencies for PostgreSQL to work with Django with this command:

sudo apt-get install libpq-dev python-dev

Now that you have done this, install PostgreSQL like so:

sudo apt-get install postgresql postgresql-contrib

PostgreSQL is now installed on your machine and ready to roll.

Step Five: Install NGINX


NGINX is an incredibly fast and light-weight web server. We will use it to serve up our static files for our Django app. To install it just run this command:

sudo apt-get install nginx

Keep in mind that you still need to start NGINX, but we will go over this in when we start configuring our VPS.

Step Six: Install Gunicorn


Gunicorn is a very powerful Python WSGI HTTP Server. Since it is a Python package we need to first activate our virtualenv to install it. Here is how we do that:

source /opt/myenv/bin/activate

Make sure you see the added "myenv" at the beginning of your terminal prompt. With your virtualenv now active, run this command:

pip install gunicorn

Gunicorn is now installed within your virtualenv.

If all you wanted was to get everything installed, feel free to stop here. Otherwise, please continue for instructions on how to configure everything to work together and make your app accessible to others on the web.

Step Seven: Configure PostgreSQL


Let's start off our configuration by working with PostgreSQL. With PostgreSQL we need to create a database, create a user, and grant the user we created access to the database we created. Start off by running the following command:

sudo su - postgres

Your terminal prompt should now say "postgres@yourserver". If this is the case, then run this command to create your database:

createdb mydb

Your database has now been created and is named "mydb" if you didn't change the command. You can name your database whatever you would like. Now create your database user with the following command:

createuser -P

You will now be met with a series of 6 prompts. The first one will ask you for the name of the new user. Use whatever name you would like. The next two prompts are for your password and confirmation of password for the new user. For the last 3 prompts just enter "n" and hit "enter". This just ensures your new users only has access to what you give it access to and nothing else. Now activate the PostgreSQL command line interface like so:

psql

Finally, grant this new user access to your new database with this command:

GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;

You now have a PostgreSQL database and a user to access that database with. Now we can install Django and set it up to use our new database.

Step Eight: Create a Django Project


In order to go any further we need a Django project to test with. This will allow us to see if what we are doing is working or not. Change directories into the directory of your virtualenv (in my case /opt/myenv) like so:

cd /opt/myenv

Now make sure your virtualenv is active. If you're unsure then just run the following command to ensure you're activated:

source /opt/myenv/bin/activate

With your virtualenv now active, run the following command to start a new Django project:

django-admin.py startproject myproject

You should see a new directory called "myproject" inside your virtualenv directory. This is where our new Django project files live.

In order for Django to be able to talk to our database we need to install a backend for PostgreSQL. Make sure your virtualenv is active and run the following command in order to do this:

pip install psycopg2

Change directories into the new "myproject" directory and then into it's subdirectory which is also called "myproject" like this:

cd /opt/myenv/myproject/myproject

Edit the settings.py file with your editor of choice:

nano settings.py

Find the database settings and edit them to look like this:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
            'NAME': 'mydb',                      # Or path to database file if using sqlite3.
            # The following settings are not used with sqlite3:
            'USER': 'myuser',
            'PASSWORD': 'password',
            'HOST': 'localhost',                      # Empty for localhost through domain sockets or           '127.0.0.1' for localhost through TCP.
            'PORT': '',                      # Set to empty string for default.
        }
    }

Save and exit the file. Now move up one directory so your in your main Django project directory (/opt/myenv/myproject).

cd /opt/myenv/myproject

Activate your virtualenv if you haven't already with the following command:

source /opt/myenv/bin/activate

With your virtualenv active, run the following command so that Django can add it's initial configuration and other tables to your database:

python manage.py syncdb

You should see some output describing what tables were installed, followed by a prompt asking if you want to create a superuser. This is optional and depends on if you will be using Django's auth system or the Django admin.

Step Nine: Configure Gunicorn


Gunicorn configuration is very specific to your applications needs. I will briefly go over running Gunicorn here with some different settings.

First lets just go over running Gunicorn with default settings. Here is the command to just run default Gunicorn:

gunicorn_django --bind yourdomainorip.com:8001

Be sure to replace "yourdomainorip.com" with your domain, or the IP address of your VPS if you prefer. Now go to your web browser and visit yourdomainorip.com:8001 and see what you get. You should get the Django welcome screen.

If you look closely at the output from the above command however, you will notice only one Gunicorn worker booted. What if you are launching a large-scale application on a large VPS? Have no fear! All we need to do is modify the command a bit like so:

gunicorn_django --workers=3 --bind yourdomainorip.com:8001

Now you will notice that 3 workers were booted instead of just 1 worker. You can change this number to whatever suits your needs.

Since we ran the command to start Gunicorn as root, Gunicorn is now running as root. What if you don't want that? Again, we can alter the command above slightly to accomodate:

gunicorn_django --workers=3 --user=nobody --bind yourdomainorip.com:8001

If you want to set more options for Gunicorn, then it is best to set up a config file that you can call when running Gunicorn. This will result in a much shorter and easier to read/configure Gunicorn command.

You can place the configuration file for gunicorn anywhere you would like. For simplicity, we will place it in our virtualenv directory. Navigate to the directory of your virtualenv like so:

cd /opt/myenv

Now open your config file with your preferred editor (nano is used in the example below):

sudo nano gunicorn_config.py

Add the following contents to the file:

    command = '/opt/myenv/bin/gunicorn'
    pythonpath = '/opt/myenv/myproject'
    bind = '127.0.0.1:8001'
    workers = 3
    user = nobody

Save and exit the file. What these options do is to set the path to the gunicorn binary, add your project directory to your Python path, set the domain and port to bind Gunicorn to, set the number of gunicorn workers and set the user Gunicorn will run as.

In order to run the server, this time we need a bit longer command. Enter the following command into your prompt:

/opt/myenv/bin/gunicorn -c /opt/myenv/gunicorn_config.py myproject.wsgi

You will notice that in the above command we pass the "-c" flag. This tells gunicorn that we have a config file we want to use, which we pass in just after the "-c" flag. Lastly, we pass in a Python dotted notation reference to our WSGI file so that Gunicorn knows where our WSGI file is.

Running Gunicorn this way requires that you either run Gunicorn in its own screen session (if you're familiar with using screen), or that you background the process by hitting "ctrl + z" and then typing "bg" and "enter" all right after running the Gunicorn command. This will background the process so it continues running even after your current session is closed. This also poses the problem of needing to manually start or restart Gunicorn should your VPS gets rebooted or were it to crash for some reason. To solve this problem, most people use supervisord to manage Gunicorn and start/restart it as needed. Installing and configuring supervisord has been covered in another article which can be found here.

Lastly, this is by no means an exhaustive list of configuration options for Gunicorn. Please read the Gunicorn documentation found at gunicorn.org for more on this topic.

Step Ten: Configure NGINX


Before we get too carried away, let's first start NGINX like so:

sudo service nginx start

Since we are only setting NGINX to handle static files we need to first decide where our static files will be stored. Open your settings.py file for your Django project and edit the STATIC_ROOT line to look like this:

    STATIC_ROOT = "/opt/myenv/static/"

This path can be wherever you would like. But for cleanliness, I typically put it just outside my Django project folder, but inside my virtualenv directory.

Now that you've set up where your static files will be located, let's configure NGINX to handle those files. Open up a new NGINX config file with the following command (you may replace "nano" with your editor of choice):

sudo nano /etc/nginx/sites-available/myproject

You can name the file whatever you would like, but the standard is typically to name it something related to the site that you are configuring. Now add the following to the file:

    server {
        server_name yourdomainorip.com;

        access_log off;

        location /static/ {
            alias /opt/myenv/static/;
        }

        location / {
                proxy_pass http://127.0.0.1:8001;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Real-IP $remote_addr;
                add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
        }
    }

Save and exit the file. The above configuration has set NGINX to serve anything requested at yourdomainorip.com/static/ from the static directory we set for our Django project. Anything requested at yourdomainorip.com will proxy to localhost on port 8001, which is where we told Gunicorn to run. The other lines ensure that the hostname and IP address of the request get passed on to Gunicorn. Without this, the IP address of every request becomes 127.0.0.1 and the hostname is just your VPS hostname.

Now we need to set up a symbolic link in the /etc/nginx/sites-enabled directory that points to this configuration file. That is how NGINX knows this site is active. Change directories to /etc/nginx/sites-enabled like this:

cd /etc/nginx/sites-enabled

Once there, run this command:

sudo ln -s ../sites-available/myproject

This will create the symbolic link we need so that NGINX knows to honor our new configuration file for our site.

Additionally, remove the default nginx server block:

`sudo rm default'

We need to restart NGINX though so that it knows to look for our changes. To do this run the following:

sudo service nginx restart

And that's it! You now have Django installed and working with PostgreSQL and your app is web accessible with NGINX serving static content and Gunicorn serving as your app server. If you have any questions or further advice, be sure to leave it in the comments section.

Share this Tutorial

Vote on Hacker News

Try this tutorial on an SSD cloud server.

Includes 512MB RAM, 20GB SSD Disk, and 1TB Transfer for $5/mo! Learn more

Create an account or login:

94 Comments

Write Tutorial
  • Gravatar alonezer7 8 months

    Finally some django tutorials! Thanks, great one

  • Gravatar tempabode 8 months

    When I am at step 3 "pip install django" I get OSError: [Errno 13] Permission denied: '/opt/myenv/build' Any idea what I should do? (I am in the virtualenv)

  • Gravatar Kamal Nasser 8 months

    @tempabode: Try running it through sudo -- does that work?

  • Gravatar tempabode 8 months

    @Kamal Nasser: It did work, but now at the command "django-admin.py startproject myproject" I am getting another permissions error (CommandError: [Errno 13] Permission denied: '/opt/myenv/myproject')

  • Gravatar tempabode 8 months

    Oh, and I am guessing that requiring to run the commands under sudo all the time may not be a good thing.

  • Gravatar Kamal Nasser 8 months

    @tempabode: Chown /opt/myenv to your user:

    sudo chown -R youruser:youruser /opt/myenv
    You should then be able to run commands as your user without having to run them as root.

  • Gravatar tempabode 8 months

    Thanks Kamal Nasser. Changing ownership for /opt/myenv/ got me past that hurdle. And I finally got Django to work. I did have to do a few other things though like use gunicorns example configuration file and use Gunicorn’s built-in Django integration. Unfortunately, part of my method involved mashing in anything the internet told me to so I'm not sure where I went right or wrong. Though, I do plan on redoing everything a few times (And trying to get SQLite working with this)

  • Gravatar stevematdavies 8 months

    Thanks for the great tutorial. Everything goes pretty smooth until I try to navigate to my site, and then I get a 502 Bad Gateway Warning

  • Gravatar Kamal Nasser 8 months

    @stevematdavies: Check nginx and unicorn's error logs. Nginx can't communicate with unicorn so it's throwing a 502 bad gateway error.

  • Gravatar vicmandlagasca 8 months

    Step Seven: could not connect to database postgres: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

  • Gravatar Kamal Nasser 8 months

    @vicmandlagasca: Postgresql isn't running. Try starting it:

    sudo service postgresql start

  • Gravatar prahaladm 8 months

    @Kamal Nasser: While trying to 'createdb mydb' (step 7), I have a similar error as @vicmandlagasca. I try to start Postgresql using the command 'sudo service postgresql start'. I get '[sudo] password for postgres:' Which password do I need to enter, I tried entering the user password, it doesn't work. Please advise.

  • Gravatar Kamal Nasser 8 months

    @prahaladm: You should run that command as root and not as postgresql.

  • Gravatar prahaladm 8 months

    @Kamal Nasser: Thank you for your prompt reply. I tried running the command as root and then following the instructions in step 7. I still get the below error. could not connect to database postgres: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? Could it be because that I have run steps 1 to 6 as a user with root privileges and then starting Postgresql from root ?

  • Gravatar Kamal Nasser 8 months

    @prahaladm: Postgresql isn't running. Try starting it:

    sudo service postgresql start

  • Gravatar prahaladm 8 months

    @Kamal Nasser: I am not sure whether you have fully read my post above on 6th Sep @ 18:25. I run the command 'root@eagle:/# sudo service postgresql start' I do not get any confirmation that the server is starting. However, when I proceed with step 7, I get the error indicating that the server isn't running.

  • Gravatar vjokaye 8 months

    @Kamal Nasser : I run "sudo service postgresql start" , but "createdb XXX" still doesn't work with the same error:"psql: could not connect to server: No such file or directory......s.PGSQL.5432" Should I edit the postgresql.conf or pg_hba.conf or missed something ?

  • Gravatar Kamal Nasser 7 months

    @prahaladm @vjokaye Check postgres' error logs:

    tail /var/log/postgresql/*.log

  • Gravatar vjokaye 7 months

    @Kamal Nasser um.. no file in var/log/postgresql/

  • Gravatar Kamal Nasser 7 months

    @vjokaye: No files at all?

    sudo ls /var/log/postgresql

  • Gravatar prahaladm 7 months

    @Kamal Nasser: Finally, I've managed to get the server started, it was an issue with locale settings. Managed to get the issue resolved by following the instruction from the below link. However, when I run command three in step 9, I get a response saying that user: nobody hasn't been defined. http://perlgeek.de/en/article/set-up-a-clean-utf8-environment

  • Gravatar vjokaye 7 months

    @Kamal Nasser: no file in "/var/log/postgresql/" directory

  • Gravatar Kamal Nasser 7 months

    @vjokaye: Please see prahaladm's comment above.

  • Gravatar Kamal Nasser 7 months

    @prahaladm: What's the output of

    id nobody
    ? What OS are you using?

  • Gravatar vjokaye 7 months

    @prahaladm: I notice while installing postgresql, the terminal except a error as" undefined locale ....C". So postgresql service doesn't work after finished install. I set my .bashrc

    export LC_ALL=C
    , reinstall postgresql and it's fixed. I don't that why.

  • Gravatar aronchick 7 months

    A few errors here - #1 "nobody" should be in quotes #2 when I use "nobody" as the user, it doesn't have write perm for /tmp.

  • Gravatar Kamal Nasser 7 months

    @aronchick: /tmp should be writable by everyone by default, have you modified its permissions?

  • Gravatar clindy.26 7 months

    hi, I have this error "createdb: could not connect to database postgres: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?"

  • Gravatar Kamal Nasser 7 months

    @clindy.26: Please see prahaladm's comment above.

  • Gravatar Oscar Giraldo Castillo 7 months

    gunicorn_django --workers=3 --bind mylocalhost:port is deprecated: https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/

  • Gravatar Alex 7 months

    Everyone who has "psql: could not connect to server" here is the complete solution: 1) fix locale with link provided by @prahaladm: http://perlgeek.de/en/article/set-up-a-clean-utf8-environment 2) COMPLETELY(!) reinstall psql as written here: http://stackoverflow.com/questions/2748607/how-to-thoroughly-purge-and-reinstall-postgresql-on-ubuntu Enjoy!

  • Gravatar john.obrien 7 months

    FYI, which Django 1.5 or greater, you need may need to set ALLOWED_HOSTS = ['127.0.0.1'] in the relevant settings when running django via gunicorn in order to avoid a system 500 error.

  • Gravatar gleb.radchenko 7 months

    @aronchick you should launch gunicorn using the same user that you mentiond in "gunicorn_config.py". Else you can't work with the files in /tmp folder correctly.

  • Gravatar garza.jonathan 7 months

    Enjoyed the tutorial. I was able to follow and get working. I am curious what are the best practices to have multiple django projects using gunicorn and nginx on the same box? With different virtualenv.

  • Gravatar prahaladm 7 months

    @ Kamal Nasser, when I run the last command in step 9. I get 'NameError: name 'nobody' is not defined'. upon your suggestion to check 'id nobody'; I get 'uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)' The OS I am using is 'Ubuntu 12.04 x32'.

  • Gravatar Kamal Nasser 6 months

    @prahaladm: Try surrounding 'nobody' with quotes: user = 'nobody' instead of user = nobody.

  • Gravatar prahaladm 6 months

    @Kamal Nasser, that did the trick. Thank you. I am trying install postgis in order to make make my postgres database spatially enabled (store and query geospatial data i.e. location, geometries etc). I get the following error when I try to './configure' a postgis installation package, before running 'make' and 'sudo make install'. Please help!! . . . checking for pg_config... /usr/bin/pg_config configure: error: the PGXS Makefile /usr/lib/postgresql/9.1/lib/pgxs/src/makefiles/pgxs.mk cannot be found. Please install the PostgreSQL server development packages and re-run configure. I didn't have the above error on my mac where I installed postgresql92-server before installing 'postgis' as suggested in the below link. https://docs.djangoproject.com/en/dev/ref/contrib/gis/install/#macports

  • Gravatar Kamal Nasser 6 months

    @prahaladm: Try installing postgresql-server-dev-9.1:

    sudo apt-get install postgresql-server-dev-9.1

  • Gravatar prahaladm 6 months

    @Kamal Nasser: I've now got postgres enabled for spatial data and I am able to successfully sync db. However, When I visit www.mydomain.com:8001 I get Django powered page www.mydomain.com I get 'Internal server error' www.mydomain.com/home I get 'Internal server error' (In my django project i've configured '/home' to direct to the relevant html page). I am unsure why I get an Internal server error. Please advise.

  • Gravatar Kamal Nasser 6 months

    @prahaladm: Check your app's error logs and see if you can find any pointers there.

  • Gravatar Kamal Nasser 6 months

    @prahaladm: It could also be an nginx error, what's the output of tail /var/log/nginx/error.log?

  • Gravatar prahaladm 6 months

    @Kamal Nasser: Couldn't find any error's in my Django app. However, there seem to be some nginx errors. 'tail /var/log/nginx/error.log' - no output 'tail /var/log/nginx/error.log.1' 2013/10/09 07:49:43 [warn] 17726#0: conflicting server name "mydomain.com" on 0.0.0.0:80, ignored 2013/10/09 07:49:43 [warn] 17727#0: conflicting server name "mydomain.com" on 0.0.0.0:80, ignored 2013/10/09 07:50:16 [warn] 17739#0: conflicting server name "mydomain.com" on 0.0.0.0:80, ignored

  • Gravatar eavinti 6 months

    when i use this command /opt/myenv/bin/gunicorn -c /opt/myenv/gunicorn_config.py myproject.wsgi where and how must be wsgi file? because i get this error: gunicorn.errors.HaltServer:

  • Gravatar Kamal Nasser 6 months

    @eavinti: Please pastebin the full error.

  • Gravatar [email protected] 6 months

    thanks... this help me a lot

  • Gravatar r.szymansky 5 months

    Hi! Help me, please: (myenv)name@droplet: /opt/myenv/myproject$ python manage.py syncdb ImportError: No module named django.core.management I did step by step from tutorial few times and still the same.

  • Gravatar r.szymansky 5 months

    Another Q: How to use this tutorial if I'd like to have python3?

  • Gravatar prahaladm 5 months

    @Kamal Nasser: When I run `tail /var/log/nginx/error.log` I get the below warning. How can I clear this warning. [warn] 6950#0: conflicting server name "myotherdomain.co" on 0.0.0.0:80, ignored I tried `sudo rm default` but the warning still remains. Please suggest.

  • Gravatar Kamal Nasser 5 months

    @r.szymansky: See if this fixes it: http://stackoverflow.com/a/6059969/3018432

  • Gravatar Kamal Nasser 5 months

    @prahaladm: Try finding out which files have "myotherdomain.co" in them:

    grep -ri "myotherdomain.co" /etc/nginx/sites-enabled

  • Gravatar prahaladm 5 months

    @Kamal Nasser: Tried running 'grep -ri "myotherdomain.co" /etc/nginx/sites-enabled' below is the reply that I got. /etc/nginx/sites-enabled/myotherproject: server_name myotherdomain.com; I then deleted 'myotherproject' folder from '/etc/nginx/sites-enabled/'. When I ran the command 'grep -ri "myotherdomain.co" /etc/nginx/sites-enabled' I did not get ant responses. However when I try and restart nginx 'sudo service nginx restart' below is the error that I get. Restarting nginx: nginx: [emerg] unexpected end of file, expecting ";" or "}" in /etc/nginx/sites-enabled/gunicorn_config.py:6 nginx: configuration file /etc/nginx/nginx.conf test failed Below id my gunicorn_config.py file. command = '/opt/myenv/bin/gunicorn' pythonpath = '/opt/myenv/myproject' bind = '127.0.0.1:8001' workers = 3 user = nobody

  • Gravatar prahaladm 5 months

    @Kamal Nasser: After uninstalling and reinstalling nginx, I do not get any errors while restarting. However, When I visit www.mydomain.com:8001 I get Django powered page www.mydomain.com I get 'Internal server error' www.mydomain.com/home I get 'Internal server error' (In my django project i've configured '/home' to direct to the relevant html page). I am unsure why I get an Internal server error. Please advise.

  • Gravatar Kamal Nasser 5 months

    @prahaladm: Hmm, is nginx running?

    sudo netstat -plutn | grep 80
    sudo ps wwaux | grep nginx

  • Gravatar david.fitch 5 months

    My nginx is not proxying requests from "/" to gunicorn. I know gunicorn is running and responding because if I wget directly to it, the response is saved to an html file and the contents are the default django project page. Even though I removed the default nginx config from sites-enabled, and restarted the service, I'm still seeing the default nginx index page that lives in /usr/share/nginx. Thoughts?

  • Gravatar prahaladm 4 months

    @Kamal Nasser: Below is the response that I get for the commands (myenv)root@eagle:~# sudo netstat -plutn | grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 12883/nginx tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 7164/python tcp 0 0 127.0.0.1:8001 0.0.0.0:* LISTEN 13189/python tcp 0 0 192.241.245.106:8001 0.0.0.0:* LISTEN 3147/python (myenv)root@eagle:~# sudo ps wwaux | grep nginx root 12883 0.0 0.3 10272 1724 ? Ss Dec05 0:00 nginx: master process /usr/sbin/nginx www-data 13348 0.0 0.2 10456 1368 ? S Dec05 0:04 nginx: worker process www-data 13349 0.0 0.2 10456 1368 ? S Dec05 0:04 nginx: worker process www-data 13350 0.0 0.2 10456 1368 ? S Dec05 0:04 nginx: worker process www-data 13351 0.0 0.3 10456 1616 ? S Dec05 0:00 nginx: worker process root 22790 0.0 0.1 4356 572 pts/3 S+ 12:07 0:00 grep --color=auto nginx

  • Gravatar axel.auvinen 4 months

    Hey, at gunicorn part. When I run command /opt/myenv/bin/gunicorn -c /opt/myenv/gunicorn_config.py myproject.wsgi it whines me about /myenv/bin/gunicorn: No such file or directory . Why it is not there?

  • Gravatar prahaladm 4 months

    @Kamal Nasser: Finally managed to overcome the error by restarting Gunicorn. Appreciate the support you've provided. Thank you.

  • Gravatar prahaladm 4 months

    @Kamal Nasser: From Step 10: You've mentioned, 'Anything requested at yourdomainorip.com will proxy to localhost on port 8001, which is where we told Gunicorn to run.' My question: Is there any way that I could make Gunicorn listen on a UNIX socket and have 'Nginx' forward requests to that. Because currently when I type in a url (http://mydomain.com) in my browser and when the page is unavailable, below is the message that I get. I would want to set Request URL (shown below) to be the url that I type in the browser (http://mydomain.com). Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8001/

  • Gravatar eminbugrasaral 4 months

    When I installed postgres, the user is switched to postgres. How can I go back to root? Because whenever I try, it asks for postgres' sudo password which I don't know. I tried the password I have for the superuser but no way. Thanks for the tutorial btw.

  • Gravatar Kamal Nasser 4 months

    @eminbugrasaral: You can run su -l root to switch to root.

  • Gravatar webofnithin 4 months

    Hey kamal. set was successful but when i opened /admin the css files were missing . it did'nt work even after changing debug true options .

  • Gravatar warrenbeyda 4 months

    @Kamal Nasser: So I tried this from my home directory /root and my project name is /root/loveless. But when I run /root/loveless/bin/gunicorn -c /root/loveless/gunicorn_config.py loveless.wsgi I get this error: 2013-12-16 02:19:04 [16392] [INFO] Starting gunicorn 18.0 2013-12-16 02:19:04 [16392] [INFO] Listening at: http://127.0.0.1:8001 (16392) 2013-12-16 02:19:04 [16392] [INFO] Using worker: sync 2013-12-16 02:19:04 [16397] [INFO] Booting worker with pid: 16397 2013-12-16 02:19:04 [16397] [ERROR] Exception in worker process: Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' 2013-12-16 02:19:04 [16397] [INFO] Worker exiting (pid: 16397) 2013-12-16 02:19:04 [16398] [INFO] Booting worker with pid: 16398 2013-12-16 02:19:04 [16398] [ERROR] Exception in worker process: Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' 2013-12-16 02:19:04 [16398] [INFO] Worker exiting (pid: 16398) 2013-12-16 02:19:04 [16399] [INFO] Booting worker with pid: 16399 2013-12-16 02:19:04 [16399] [ERROR] Exception in worker process: Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' Traceback (most recent call last): File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 46, in load_wsgiapp File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 40, in chdir OSError: [Errno 13] Permission denied: '/root/loveless' 2013-12-16 02:19:04 [16399] [INFO] Worker exiting (pid: 16399) Traceback (most recent call last): File "/root/loveless/bin/gunicorn", line 9, in load_entry_point('gunicorn==18.0', 'console_scripts', 'gunicorn')() File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 71, in run WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run() File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 143, in run Arbiter(self).run() File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 203, in run self.halt(reason=inst.reason, exit_status=inst.exit_status) File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 298, in halt self.stop() File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 341, in stop self.reap_workers() File "/root/loveless/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 452, in reap_workers raise HaltServer(reason, self.WORKER_BOOT_ERROR) gunicorn.errors.HaltServer: this is my /root/loveless/gunicorn_config.py command = '/root/loveless/bin/gunicorn' pythonpath = '/root/loveless/blog' bind = '127.0.0.1:8001' workers = 3 user = "nobody" Any help would be appreciated

  • Gravatar Kamal Nasser 4 months

    See if fergalmoran's comment helps: https://github.com/benoitc/gunicorn/issues/338#issuecomment-22495382

  • Gravatar francisalfanta 4 months

    I have followed the instruction above but I'm using CentOs, Django==1.6., Python2.7, Postgresql, nginx and gunicorn. Though along the way there are variance I manage to overcome them. When I run the gunicorn_config.py with the instruction settings is working without errors now. command = '/opt/myenv/bin/gunicorn' pythonpath = '/opt/myenv/myproject' bind = '127.0.0.1:8001' workers = 3 user = nobody But checking to my gunicorn.error.log it is listening to 127.0.0.1:8000. How come this port is been used than what specified.

  • Gravatar francisalfanta 4 months

    My nginx config is the same as the instruction above using proxy_pass http://127.0.0.1:8001;

  • Gravatar francisalfanta 4 months

    sudo netstat -plutn | grep 80 output tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1052/nginx tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 1205/python2.7

  • Gravatar hannen 4 months

    After following these instructions, everything appears to be working with the exception that my admin site does not have any CSS applied to it. Does anyone know what additional steps are needed to get CSS working with the admin site? Thanks

  • Gravatar Kamal Nasser 4 months

    @hannen: See if this helps: http://mark.hungrybugger.co.uk/2013/django-admin-css-missing-a-2013-solution/

  • Gravatar songshu.yu 3 months

    Everything was fine, until Step 9 Command 3, I got this error OSError: [Errno 1] Operation not permitted: '/tmp/wgunicorn-l1t4RV' The tmp directory has a green background, and attributes 'drwxrwxrwt 2 root root'

  • Gravatar Kamal Nasser 3 months

    @songshu.yu: Try stopping gunicorn and clearing the tmp files:

    rm /tmp/wgunicorn*
    Then try staring it with --user=nobody again, does it work?

  • Gravatar songshu.yu 3 months

    It doesn't work with --user=nobody, but it works with --user=myownusername. I think in my droplet nobody has no rights to write to /tmp/ folder.

  • Gravatar Kamal Nasser 3 months

    @songshu.yu: Hmm, the policies are different on each OS so that might be the case.

  • Gravatar john_steedman 2 months

    Kamal I'm finding this very useful but I do not have it all set up yet. Please could give a bit more context to the following line because this step has me a bit confused. Thanks,JS Additionally, remove the default nginx server block: `sudo rm default'

  • Gravatar hello 2 months

    The link to the droplet setup tutorial is broken because "here" (including the quotes) is appended to the link's target.

  • Gravatar dlman8 2 months

    I'm having the same problem as songshu, I'm running on Ubuntu 12.04 and I get the same error about the /tmp directory.

  • Gravatar Kamal Nasser 2 months

    @hello: Thanks, I've updated the article.

  • Gravatar Kamal Nasser 2 months

    @dlman8: Try running it as your user instead of "nobody", does that fix it?

  • Gravatar pkenway about 1 month

    Thanks for the guide Kamal. It was very useful and easy to follow. I got this to work using python3 in the virtualenv, and I thought I would share the tweaks I had to make to get it running: Before Step 1 install python3 "apt-get install python3" Step 2 change virtualenv /opt/myenv to virtualenv --python=/usr/bin/python3 /opt/myenv Step 4 change apt-get install libpq-dev python-dev to apt-get install libpq-dev python3-dev

  • Gravatar craig about 1 month

    Can you install something like mezzanine for a project after getting this setup?

  • Gravatar Kamal Nasser about 1 month

    @craig: I don't see why not :] Give it a shot and let us know how it goes.

  • Gravatar craig about 1 month

    Do you need to setup a separate virtualenv for each application?

  • Gravatar jose about 1 month

    Does anyone have a solution to remedy the OSError: [Errno 1] Operation not permitted: when nobody is chosen as a user for the gunicorn workers?

  • Gravatar raja.ramanathan about 1 month

    You should not invoke creation of virtual environment using sudo. This leads to the lib directory under virtual environment owned by root and having to change ownership etc., Just simply invoke "virutalenv myenv" as current user and everything will be fine after. Check out Stackoverflow: http://stackoverflow.com/questions/2658902/in-my-virtualenv-i-need-to-use-sudo-for-all-commands

  • Gravatar scandola.fabrizio 26 days

    Guys but following this tutorial to see my app I need to type mydomain.com:8001. But this is what nobody wants! What should I do to access the app from simply mydomain.com? Than You in advance!

  • Gravatar kpennell 25 days

    Hey Kamal, I'm trying to combine this tutorial with the nice Mezzanine tutorial you guys have. I think somewhere along the way my project isn't structured like yours. My env isn't in the right place or project or whatever. So I lose my way (can't get it up now). Could you include a project structure outline so we can see exactly what should be where please?

  • Gravatar kpennell 24 days

    If you're getting: RuntimeError: django project not found 2014-03-26 19:29:00 [7213] [INFO] Worker exiting (pid: 7213) 2014-03-26 19:29:00 [7208] [INFO] Shutting down: Master 2014-03-26 19:29:00 [7208] [INFO] Reason: Worker failed to boot. Make sure you're in the right place. If you follow this verbatim, it will be myproject. myproject ├── manage.py └── myproject It's odd. You don't need to be in the file where gunicorn_django is to run it. It works more like a command. I kept trying to run it in bin and no luck. gunicorn_django --bind yourdomainorip.com:8001 Here's what the tree should look like: ├── bin │   ├── activate │   ├── activate.csh │   ├── activate.fish │   ├── activate_this.py │   ├── django-admin.py │   ├── django-admin.pyc │   ├── easy_install │   ├── easy_install-2.7 │   ├── gunicorn │   ├── gunicorn_django │   ├── gunicorn_paster │   ├── pip │   ├── pip2 │   ├── pip2.7 │   ├── python │   ├── python2 -> python │   └── python2.7 -> python ├── include │   └── python2.7 -> /usr/include/python2.7 ├── lib │   └── python2.7 ├── local │   ├── bin -> /opt/myenv/bin │   ├── include -> /opt/myenv/include │   └── lib -> /opt/myenv/lib └── myproject ├── manage.py └── myproject Hope this helps another lost code learning soul...No fun being stuck.

  • Gravatar kpennell 24 days

    Kamal Nasser 6 months @prahaladm: Try surrounding 'nobody' with quotes: user = 'nobody' instead of user = nobody. Maybe you could change the tut to reflect this... unless I could?

  • Gravatar kpennell 22 days

    Haven't had any luck getting my static files to serve. 404s...error logs read: 2014/03/28 07:12:58 [error] 13768#0: *8 connect() failed (111: Connection refused) while connecting to upstream, client: 220.181.51.146, server: 107.170.215.138:8001, request: "GET$

  • Gravatar Kamal Nasser 22 days

    @kpennell: That means gunicorn isn't running (it's not able to connect to :8001). What URL are you trying to access? /static/* requests should be handled entirely by nginx.

    @prahaladm: Try surrounding 'nobody' with quotes: user = 'nobody' instead of user = nobody. Maybe you could change the tut to reflect this...
    I wasn't sure if that would fix the problem. Was that necessary for it to work for you? If so, I'll update the article!

  • Gravatar kpennell 19 days

    Kamal, thanks for the response. Worked on this for 2 weeks. Can't seem to get it. Perhaps I'll just start from scratch.

  • Gravatar ramanovandi 14 days

    stuck on step ten, anyone to help me.. my problem on this step sudo nano /etc/nginx/sites-available/myproject , i can't find directory site-available?

  • Gravatar Kamal Nasser 13 days

    @ramanovandi: The directory is actually called sites-enabled. If that still doesn't work, please post the output of the following command:

    sudo ls /etc/nginx

  • Gravatar ramanovandi 8 days

    this output for command sudo ls/etc/nginx http://prntscr.com/39bvmq

  • Gravatar Kamal Nasser 8 days

    @ramanovandi: What OS are you using? This article is written for Ubuntu, you might be able to get it to work on CentOS or other RHEL-based distros but the steps might not be exactly the same. CentOS's nginx package does not contain sites-enabled and sites-available directories. All of the virtualhosts are in nginx.conf. See https://blog.kamal.io/post/nginx-apache-like-server-structure/.

Leave a Comment

Create an account or login:
Ajax-loader