How about greetings everyone, this is my first article in <» DesdeLinux (of several that I have in my drafts xD), I hope it is useful to you 😀
Well, in my new and current job, at the moment the migration of several systems to Django is being carried out (how strange eh ?? xD) and one of my tasks, apart from development, is putting these into production, so how good apprentice, since it was my first time putting an application into production on a real server: $ I started to read the official doc of each of the required packages of the stack (Gunicorn and Supervisord most of all), and seeing that the tutorials In Spanish they were not very clear to me in some aspects, I decided to create a mini guide with the steps that I followed to put the application into production, based on the Django, Gunicorn, Supervisord, Nginx and Postgresql stack.
In the case where I work, the servers still run on Debian Squeeze, but the guide should be fully valid for other distributions ... so let's get straight to the point and get started:
I will work as a super user. First of all, the following packages are required:
PIP -> Tool to install and manage packages for Python
aptitude install python-pip
Nginx -> Web server (we will use it as a reverse proxy and to cache the static files 'img, js, css') We install it with:
aptitude install nginx
Supervisor -> Application to manage and monitor our application, although it is used for much more. We install it with:
aptitude install supervisor
Virtualenv -> It helps us to create a customized virtual execution environment for our application. We install it with:
aptitude install python-virtualenv
gunicorn -> web server for python (we won't install this yet)
I assume they should already have postgresql installed and configured
psychopg2 -> Postgresql connector for python (we won't install it yet either)
Create virtual environment with virtualenv:
First we are going to move to the working directory that we will use for putting into production:
cd /var/www/
Then in this directory we will create the virtual environment:
virtualenv ENV-nombreApp
We move to the directory that I just created virtualenv
cd ENV-nombreAPP
We copy the application in this directory and now we proceed to activate the environment with:
source bin/activate
The prompt should now look like (ENV)usuario@host:
This will now make everything we do is stored in the directory / var / www / ENV-appname / without affecting system packages
Now we move to the application directory:
cd nombreApp
We proceed to install the list of application dependencies (if necessary), in which they are specified in the file requirements.txt:
pip install -r requirements.txt
We can also install packages individually, for example, to install the connector of postgresql:
pip install psycopg2
GUnicorn installation and configuration:
To install it we do it in the same way:
pip install gunicorn
Now we are going to configure it, for this we are going to create a file called gunicorn-deploy.py in the root of our application, (although the name can be anything) with the following content:
bind = "127.0.0.1:8001" # dirección a donde accederá Nginx
logfile = "/var/www/logs/nombreApp/gunicorn.log" # dirección donde estarán los logs de la aplicación
workers = 1 # dependerá en medida de la carga de trabajo que tenga la aplicación, también depende del hardware con que se cuente
loglevel = 'info' # tipo de logging
Supervisord configuration:
Now let's set the supervisor, for that we generate the configuration file with
echo_supervisord_conf > /etc/supervisord.conf
Now we edit the configuration file:
vim /etc/supervisord.conf
And we uncomment the following lines by removing the; (semicolon):
[unix_http_server] file = / tmp / supervisor.sock [supervisord] logfile = / var / log / supervisord.log logfile_maxbytes = 50MB logfile_backups = 10 loglevel = debug pidfile = / var / run / supervisord.pid nodaemon = false minfds = 1024 minprocs = 200 [rpcinterface: supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface: make_main_rpcinterface [supervisorctl] serverurl = unix: [program: appname] command = / var / www / ENV-appname / bin / django_unicorn -c / var / www / ENV -Appname / appname / gunicorn-deploy.py directory = / var / www / ENV-appname / appname / autostart = true autorestart = true user = Username redirect_stderr = true stdout_logfile = / var / www / logs / appname / supervisord.log
Now we will create the script for supervisord to start with the system, for that we will create the file:
vim /etc/init.d/supervisord
And we add the following content:
# Supervisord auto-start # # description: Auto-starts supervisord # processname: supervisord # pidfile: /var/run/supervisord.pid SUPERVISORD = / usr / local / bin / supervisord SUPERVISORCTL = / usr / local / bin / supervisorctl case $ 1 in start) echo -n "Starting supervisord:" $ SUPERVISORD echo ;; stop) echo -n "Stopping supervisord:" $ SUPERVISORCTL shutdown echo ;; restart) echo -n "Stopping supervisord:" $ SUPERVISORCTL shutdown echo echo -n "Starting supervisord:" $ SUPERVISORD echo ;; that C
And now we give execute permissions to the file so that it can start with the system:
sudo chmod +x /etc/init.d/supervisord
We update the links to start the service:
sudo update-rc.d supervisord defaults
We start the service:
sudo /etc/init.d/supervisord start
Setting up nginx:
This step is also quite simple, we will create the following configuration file of for our application:
vim /etc/nginx/sites-enabled/nombreApp
And we will add the following content to you
server {listen 9001; # port where they want nginx server_name to listen www.domain.com; # or 192.168.0.100, address that we will access access_log /var/log/nginx/Appname.access.log; # where we will have the application log location / {# where nginx will call when accessing www.dominio.com/ proxy_pass http://127.0.0.1:8001; proxy_set_header Host $ http_host; } location / static / {# where nginx will access when we enter www.domain.com/static/ alias / var / www / ENV-appname / appname / staticfiles /; }}
And we restart nginx:
service nginx restart
Setting up Django:
Let's modify the django configuration file:
vim nombreApp/settings.py
We look for the line that says DEBUG=True and we change the valueremaining DEBUG=False
We add the DB parameters:
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', # or mysql, or whatever 'NAME': 'DBName', 'USER': 'DBUser', 'PASSWORD' are using : 'password DB', 'HOST': 'localhost', # or the one they need 'PORT': '', # or the one they are using}}
We look for the line ALLOWED_HOSTS = [] and we add the domain or the address through which we will access, leaving something like ALLOWED_HOSTS = ['www.domain.com']
We configure the directory for the static files, we look for the line that says STATIC_ROOT = ' '
and we change the value, placing the absolute path where we want our static files to be, in my case I left it more or less like this STATIC_ROOT='/var/www/ENV-nombreApp/nombreApp/statics/'
Almost finished, we execute the following command:
./manage.py collectstatic
This will create a folder with the name 'static in the path that we specify in the settings.py ', that's where all our static files will be.
And finally we restart the supervisor to take the new changes:
supervisorctl restart nombreApp
And that would be all, in the end it was not so much true? it seemed simple to me 😀
I hope it is useful to you, greetings 😉
I understand that the Django app should not be placed in the root of the web server folder (/ var / www)? For security, I don't know if I'm wrong.
Greetings.
All right !!! It was something that I was totally unaware of, I will update the entry 😛 and as soon as I return on Monday I will make changes in the xD application
Thank you
Epale brother good tutorial. Recently I was also in the same but in Debian 7, I had to search and read more or less. I recommend that you create the virtual environment of virtualenv in the user's home in a hidden folder.
Regards!
hahaha ctm I yesterday documenting Django and you are already going through the galaxy 999999 Greetings men xD
Very good article =) just a week ago I deployed my django app but I did it with uwsgi and nginx, do you know what advantage gunicorn has? I've seen it mentioned a lot.
It's nice to see that django is becoming very popular, the truth is the best framework I've seen =)
For the STATIC_ROOT what I do is define a global variable. Something like this:
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_PATH, '../backend/static')
Where backend is an app that I created. This way I make sure that where I deploy the project, the global path is the same.
Interesting, I will try in the future.
By the way, does anyone know how to enable accents and non-ascii characters in a django application?
I've looked everywhere, none of the following methods work for me:
sys.setdefaultencoding ('utf-8') # in sites.py
# - * - coding: utf-8 - * - # in every python file
Editing site.py, and putting utf-8 instead of ascii is supposed to work, but $ file models.py informs me that my file is still an ascii.
Any Suggestions?
It worked!!!!
very good tutorial but you could do one of how to upload my app on a web server already in production
Thank you