There are many ways to deploy Django applications in * nix-environment. I will not pretend to originality, just share the
very-very-very-most .
Introductory conditions
Prerequisites:
- One client (customer) - one user in the system on the server.
- All client projects are in one file hierarchy.
- Virtualenv is good and must use.
- FTP is evil, we use modern tools (sftp).
- The number of files for project management should be kept to a minimum.
Used software:
- nginx
- uwsgi
- cron
- virtualenv
- openssh
And nefig here to be rummaged
It often happens that along with the developers, the users / clients / customers also want to have access to the file tree of their projects (i.e. "Almost" third-party people. So, to limit third-party users to the ability to rummage through server disks is a good idea. At first glance, the idea comes to limit the user to his home directory. You should not succumb to this impulse, because in his home directory the user is the king and god, and one wrong move
and you are the father can lead to the inoperability of the project. So let's go to the trick and create the following hierarchy:
/home /client -- /client -- "client" /another_project /project /www-root /static /app1 /app2 manage.py settings.py django_wsgi.py ... /var /log -- nginx'a, logrotate /tmp -- chmod 770 -- /run -- /client2 -- /client3 --
The home directory of the “client” user has client: client rights, the other directories, unless otherwise specified, are root: client and chmod 750, respectively. You must also include the nginx user in the client group in order for nginx to have access to static files within the project. Also in the system we create a group sftponly in which we include clients. Add the following to the sshd config (/ etc / ssh / sshd_config):
Match Group sftponly X11Forwarding no AllowAgentForwarding no AllowTcpForwarding no ChrootDirectory /home/%u ForceCommand internal-sftp
and line
Subsystem sftp /usr/lib/misc/sftp-server
replace with
Subsystem sftp internal-sftp
As a result, we get a situation where a user logging into the server via sftp (say using winscp) gets into his home directory, can go up one level, roam his projects, watch logs. However, it cannot climb higher or delete any important directory (chmod 750 however).
nginx - how much is in this word
Nginx is perhaps the best of http servers to upload static content and resolve issues related to dynamic generation. In our case, nginx should be assembled with the uwsgi-module (it comes in the standard package). With the default installation (at least in gentoo), nginx stores its configs in / etc / nginx. We will not violate this tradition, and even vice versa we will try to use it. In the main nginx'a config (/etc/nginx/nginx.conf), add the line to the end of the http section
include /etc/nginx/vhost.d/*.conf ;
as a result, we will be able to have one configuration file (/etc/nginx/vhost.d/project.conf) per project.
Something like this:
Lines beginning with # uwsgi # will be taken by nginx as comments, but the start script nust (which is discussed below) looks at these lines, considering them as directives for themselves.
')
nust - Nginx Uwsgi STarter
Once, when uwsgi just started to appear, knew how to fall in the process of operation, did not have an “imperial” regime, but it was already damn demanded - a script was written in haste, which, for a normal reason, they did not get rewritten for one reason - it works. So, how it works and what it does.
Nust runs on crown (crontab -e)
*/5 * * * * nust -s -c /etc/nust.conf
with its configuration file. The configuration file has two sections, the first of which relates directly to nust'y and determines the paths and utilities that are used by it, and the second one, defaults for uwsgi.
[nust] pstree = /usr/bin/pstree vhosts = /etc/nginx/vhost.d/*.conf uwsgi = /usr/bin/uwsgi uwsgi_def_args = --ini=/etc/nust.conf dbdir = /var/run kill = /bin/kill -s TERM kill_k9= /bin/kill -s KILL [uwsgi] master= disable-logging= vacuum= logfile-chown= chmod-socket=666 catch-exceptions= memory-report=
Install nust in the system as follows:
sudo pip install nust
In the nginx config with the help of the “shape comment” # uwsgi # you can override the following options:
- WORKERS - the number of parallel workflows
- MODULE - the name of the python module being started (django_wsgi.py)
- PRJ - project name
- PID - pid-file of the workflow tree (var / run / uwsgi.pid)
- LOG - path to the uwsgi log file (var / log / uwsgi.log)
- HARAKIRI - maximum query execution time, sec.
- MAX_REQ - the number of requests processed, after which the workflow will be restarted
These options are mandatory:
- USER - user from under which the project will be launched
- HOME - project home directory (NOT USER!)
- VE - the path to the virtual environment (the result of virtualenv)
- SOCKET - where to create a file socket. If not specified, it will be taken from the upstream section.
Paths can be specified in three ways:
- absolute path starts with a slash
(/ tmp) - path relative to the user's home directory
(~ / gde-to / tam /) - path relative to the project's home directory
(var / run / uwsgi.pid)
To start any Python code under uwsgi, we need a so-called module. The following code is suitable for running django and is located in
django_wsgi.py :
There is no need to register the launch of nust in the system startup scripts, since nust is run on the crown periodically. In addition to simply starting projects, nust monitors their status (dropped, not running, running, but not pinging), as well as the status of nginx virtual hosts configs. If the virtual host configuration has been changed, then the corresponding project will be restarted.
Instead of epilogue
Well, that's all. I hope I did not forget anything important. Thanks for attention.