Deploying¶
Contents
With fabric¶
Caution
This is pretty much alpha stuff, it might change a lot in the future.
Currently the duke client only offer some useful fabric tasks for standard django deployment.
Project Configurations¶
To use it, simply create a file named fabfile.py in the root directory of your project (where your setup.py file is).
The file content should look like this:
import os
from dukeclient.fabric.utils import get_role, get_conf, get_project_path
from dukeclient.fabric.tasks import *
LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
env.roledefs.update({
'demo': ['user@demo.host.com'],
'prod': ['user@production.host.com:5555'],
# Not required, but can be useful if you want to invoke commands
# on multiple servers at once.
'http_servers': ['user@production.host.com:5555', 'user@demo.host.com'],
})
env.site = {
'domain': 'mysite.com',
'package': 'mysite.com',
'project': 'mysite',
'repos': 'svn://svn.myserver.com/mysite.com/trunk/mysite.com/',
}
env.roleconfs = {
# This is an example of how you can deploy on Plesk
'prod': {
'hosts': env.roledefs['prod'],
'user': 'username',
'group': 'usergroup',
'document-root': '/var/www/vhosts/%(domain)s/httpdocs/',
'vhost-conf': '/var/www/vhosts/%(domain)s/conf/vhost.conf',
# Most commands uses an event system which will run scripts
# at specific times.
'on-code-sync': [],
'on-code-sync-done': [],
'on-apache-reload': [
# You can run scripts before and after most of the available
# commands. In this case we tell Plesk to reload its vhost
# configuration for mysite.com
'/usr/local/psa/admin/sbin/websrvmng --reconfigure-vhost --vhost-name=%(domain)s',
],
'on-apache-reload-done': [],
# If mod_python is installed on your Apache server, you'll need
# virtualenv or you will go insane. Really.
'virtualenv': True,
},
# This example show a more basic Apache deployment
'demo': {
'hosts': env.roledefs['demo'],
'document-root': '/var/www/vhosts/demo.%(domain)s/',
'media-root': '/var/www/vhosts/demo.%(domain)s/%(domain)s/%(project)s/media/',
'static-root': '/var/www/vhosts/demo.%(domain)s/%(domain)s/static/',
'vhost-conf': '/etc/apache2/sites-enabled/demo.%(domain)s',
'virtualenv': True,
'user': 'www-data',
'group': 'www-data',
'on-deploy-done': [
'ln -sf /var/www/vhosts/demo.%(domain)s/%(domain)s/%(project)s/media/ /var/www/vhosts/demo.%(domain)s/media',
],
},
}
Deployment configurations¶
Deployment configurations must be stored in a directory named deploy/ in the root directory of your project.
Virtualhost¶
Virtual host files a threated as template, so you don’t have to adjust them every time you change a configuration.
The naming convention is <role>.vhost. So if you have a demo and a prod role, your vhost files should be name demo.vhost and prod.vhost.
Here’s an example of a standard Apache/WSGI vhost configuration file:
<VirtualHost *:80>
ServerAdmin max@motion-m.ca
DocumentRoot %(document-root)s
ServerName %(project)s.d.motion-m.ca
ErrorLog /var/log/apache2/%(package)s.d.motion-m.ca-error_log
CustomLog %(project)s.d.motion-m.ca common
Options FollowSymLinks
WSGIPassAuthorization On
WSGIScriptAlias / %(document-root)s%(package)s/%(project)s/wsgi.py
WSGIDaemonProcess %(project)s user=www-data group=www-data processes=5 threads=1
WSGIProcessGroup %(project)s
Alias /static/ %(document-root)sstatic/
Alias /media/ %(document-root)smedia/
<Directory %(document-root)smedia/>
Order deny,allow
Allow from all
AllowOverride None
</Directory>
<Directory %(document-root)sstatic/>
Order deny,allow
Allow from all
AllowOverride None
</Directory>
</VirtualHost>
Settings.py¶
The settings.py files can be automatically overwritten with a settings.py template.
For example, to set your project’s settings on a role named demo you would start by creating a file named deploy/demo_settings.py.
Now every time you deploy your code, the file deploy/demo_settings.py gets copied over myproject/local_settings.py, overriding any other settings set elsewhere.
Here’s an example which defines the default database backend:
from %(project)s.conf.settings.default import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.%%s' %% "mysql", # Read the caution below !
'NAME': '%(project)s_demo',
'USER': '%(project)s',
'PASSWORD': '*********',
}
}
Caution
Make sure to scape all the modulos by duplicating them like this: %%.
Since I use Advanced String Formating to replace the template variables you have to be careful when using a modulo (%). If you don’t escape it Python will think it has to insert a token there and will most likely throw an exception at your next buildout.
Usage¶
Deploying¶
On demo:
fab -R demo full_deploy
On prod:
fab -R prod full_deploy
On both:
fab -R http_servers full_deploy
Other commands¶
Other commands will eventually be documented properly .. meanwhile you can list them all using the fab -l command.
Per role configurations¶
Sometimes you want to tweak configurations depending on which role the project is running on.
To accomplish this, simply create a cfg file named after the role and make it extend the buildout.cfg file.
The next time buildout will be run on this role, it will find the file and use it instead of buildout.cfg.
Here’s an example of how one could set a cron job on the production server:
prod.cfg:
[buildout]
extends = buildout.cfg
parts += django-cleanup
[django-cleanup]
recipe = z3c.recipe.usercrontab
times = @monthly
command = ${buildout:directory}/.duke/bin/django cleanup
Development roadmap¶
In the long term a django duke master will be created. The scope of the functionalities isn’t yet fixed, but it’s main purpose will be to act as a deployment server. It will hold servers and projects configurations and allow easy deployment using the duke command.
There is several advantages of using centralized deployment instead of a distributed deployment strategy (with fabric). But the most important advantage for us is to be able to assign deployment rights to developers without giving them actual access to the production servers.
When centralized deployment will be implemented, we will probably move to other nice to have features like scheduled deployment and continous integration and maybe even a plugin architecture for things like website monitoring, project management and such.