generic django project
This is my starting point for a new Django site, mixed and stirred from several public sources and spiced with my own enhancements.
- server OS: Debian/Ubuntu based Linux
- local OS: MacOS X (only some local settings are OSX specific)
- web server: Nginx/gunicorn or Nginx/fcgi
- Python version: 2.7 or 3.x
- Django version: 1.9 (1.6+ should work)
- FeinCMS version: 1.5+
- version control: Git
- deployment tool: Fabric
- local development database: SQLite3
- server database: MySQL or PostgreSQL
- process control (optional): supervisord or daemontools
Django’s startproject doesn’t do enough. I’m a programmer, thus lazy, and try to reduce redundant work like repeating the same setup steps over and over. (DRY)
Just copying/cloning this generic project to a new site isn’t ideal either, since general changes don’t affect all dependent sites, but I got no idea how to do that.
I’m trying to keep this current and to implement what I learn from my actual projects and best practice advise. But since I mostly do other things than starting new django projects, I’m always far behind.
- While I try to adhere to best practices, there are probably security holes - use at your own risk.
- Since I update this template after experiences with my actual sites, the commits are often not atomic.
- pip-installed requirements are not fixed on a version.
- I could also support runit, but I didn't want to replace init.
- I’m not using daemontools any more, so its configuration is outdated.
- gunicorn runs internally on an unix socket, because I find file locations easier to control than server ports.
- I’m integrating Let’s Encrypt certificates and automating their renewal.
- My nginx settings get an A+ rating at SSLLabs
- Learn more from Two Scoops of Django, http://agiliq.com/books/djangodesignpatterns/, https://github.com/callowayproject/django-app-skeleton, https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
- Include Sphinx template
django-admin.py startproject --template=https://github.com/fiee/generic_django_project/zipball/master --extension=py,rst,html,txt,ini,sh MY_PROJECTwork
- Finally learn proper testing
- Split templates for simple site, cerebrale site, reusable app
This project template itself has no special license. Do with it what you want. Attribution is appreciated. Corrections are welcome. I’m not responsible for your failure, damage or loss.
Since it’s a collection of (modified) snippets from different sources that may have different licenses, it would be impossible to untangle.
Following Django’s documentation I suggest to use a 2-clause BSD license for your own projects.
- Rename "django_project" (this would be the project root as created by
- Replace all occurrences of lowercase "project_name" with your project name.
This is also the webserver and database server username!
The "project_name" directory is the one that would be created by
- Check the settings in server-setup and django_project/settings: fabfile.py, gunicorn-settings.py, supervisor.conf_, settings/base.py_, settings/local.py_ etc.
- Adapt LICENSE to your needs if you might publish your project. The 2-clause BSD license is just a suggestion.
- Set up an email account for your project’s error messages and configure it in settings/base.py_ and .env
git init, always commit all changes
manage migrate(initialize migrations)
fab webserver setup(once)
fab webserver deploy(publish new release - always last committed version!)
Following 12-factor design, we now set our passwords and other secret settings as environment variables to avoid to have them in version control. I suggest to go the dotenv route:
Put your settings into a
.env file in the
to use with django-dotenv-rw. Don’t forget to tell git to ignore .env files!
DJANGO_SETTINGS_MODULE=settings DATABASE_PASSWORD=secret123 EMAIL_PASSWORD=secret123
Alternatively add the settings to the end of your virtualenvs
export DJANGO_SETTINGS_MODULE=settings export DATABASE_PASSWORD=secret123 export EMAIL_PASSWORD=secret123
Create the user
I suggest to copy ``makeuser.sh``_ to your webserver’s root/admin account and use it to create system and database accounts.
scp makeuser.sh email@example.com:/root/bin/
Otherwise look into that script. This is just a part of the necessary setup:
create user and sudo-enable it (I suggest via a
admingroup, but you can also add the user to
adduser project_name --disabled-password --gecos "" adduser project_name admin
create database user and database (schema):
mysql -u root -p # at first setup only: we installed MySQL without user interaction, # so there’s no root password. Set it! use mysql; update user set password=password('...') where user='root'; # create user and database for our project: create user 'project_name'@'localhost' identified by '...'; create database project_name character set 'utf8'; grant all privileges on project_name.* to 'project_name'@'localhost'; flush privileges; quit;
/var/www/project_name(or use virtualenvs’
activatescript), see above.
Open your firewall for tcp 433 (not default on some systems).
Request a SSL certificate, see e.g. https://www.nginx.com/blog/free-certificates-lets-encrypt-and-nginx/
sudo /opt/letsencrypt/letsencrypt-auto --config /etc/letsencrypt/configs/www.project_name.de.conf certonly
If you use FeinCMS’ Page, consider first, which extensions you’ll need –
see the docs and the FAQ –
afterwards you would need to change the database table
page_page by hand,
since the changes aren’t always detected by migration!
At the moment (April 2016) the released version of FeinCMS isn’t yet compatible with Django 1.9; you must use the git checkout.
Links / Sources
- Nginx configuration: http://wiki.nginx.org/NginxConfiguration
- Secure Nginx TLS configuration: https://www.sherbers.de/howto/nginx/ (German)
- Gunicorn configuration: http://gunicorn.org/configure.html
- logrotate: e.g. http://www.linux-praxis.de/lpic1/manpages/logrotate.html
- daemontools: http://cr.yp.to/daemontools.html
- supervisord: http://supervisord.org
- Let’s Encrypt certificates with Nginx: https://www.nginx.com/blog/free-certificates-lets-encrypt-and-nginx/
- Let’s Encrypt certificates with Nginx: https://gist.github.com/xrstf/581981008b6be0d2224f