Cookiecutter template for django projects
This is just another cookiecutter template for django projects, matching my job requirements. There are many out there which are great but I needed one following my consolidated workflow.
Running this you will have:
- a development ready django project with all the packages installed and the database created and ready to go.
- a bin command which will set up the remote machine for you (using ansible) and will display a maintenance page
- some production commands to manage the deploy and related stuff.
For the bootstrap4 version, please use the bootstrap branch, the master one uses semantic-ui.
Cookiecutter is uset to create a working directory already configured.
Ansible is used to set up the local and remote machines
Fabric is used to manage the deploy and other related tasks.
- mysql db
- django development server
- mysql db
- nginx server
- django db settings managed with environment variables
- some must-have (in my opinion) packages installed:
- django-baton (optional)
- django-suit (optional)
- django-grappelli (optional)
- django-filer (optional)
- django-disqus (optional)
- pages with integrated ckeditor
- git repository initialized and ready
- bootstrap 4.2.1
- bin command to set up your production machine
- fabfile ready for deployment
- environment variables for configuration
jQuery as js framework, bootstrap as css framework, momentjs to deal with datetime objects.
- jQuery 1.11.3
- bootstrap v4.2.1
- FontAwesome 4.7.0
$ pip install cookiecutter
Install ansible (and run it under python3)
pip3 install ansible
Run cookiecutter against this repo
$ cookiecutter https://github.com/abidibo/cookiecutter-django
Answer the following questions:
- project_name: name of the project. Default "My New Project"
- project_description: project description. Default "My New Project description"
- repo_name: name of the repository. Default "[project_name | lower | replace(' ', '-')]"
- core_name: name of the main application. Default "[repo_name | replace('-', '_')]"
- admin: django admin app package. Possible values: django-baton, django-suit, django-grappelli, default. Default "django-baton"
- use_filer: whether or not to install django-filer [y|n]. Default "n"
- use_disqus: whether or not to install django-disqus [y|n]. Default "n"
- language_code: language code. Default "en-us"
- timezone: timezone. Default "Europe/Rome"
- author: project author. Default "abidibo"
- email: project author email. Default "email@example.com"
- remote_user: user for deployment to the production server. Default "[repo_name]"
- domain: production domain. Default "www.example.com"
- remote_root_mysql_pwd: password for the remote mysql root user. Default "". You can set it later inside the
- db_user: user for the remote database. Default "[remote_user]"
- db_user_pwd: user password for the remote database. Default ""
- webapp_dir: absolute path to the remote deploy directory
Then provide your sudo password in order to provision your local environment.
If all works great now you should have:
- a new folder (I'll call it root) containing all your bootstrapped project
- all the necessary packages installed
- a fresh virtualenv with all the dependencies already installed (folder
.virtualenvin the root)
- a new database ready to go with, all migrations applied
- a new git repository initialized
- a README file explaining how to clone and get started with the project
$ cd [repo_name] $ python [repo_name]/manage.py createsuperuser $ bin/runserver
And visit http://localhost:8000
setup local environment manually
maybe you don't want ansible to setup the local environment for you (for example if you are on a mac some commands will fail), so just interrupt the execution of cookiecutter (CTRL-C) when you're prompted for the sudo password. You can then check the provisioning files, change them and then launch
change the SECRET_KEY:
$ dotenv set SECRET_KEY <secret_key_here>
you can change the remote SECRET KEY adding a line
you can also not specify the remote params during the installation. You will have a working local environment ready to go. But in this case you'll have to set them manually to configure the remote setup script which uses ansible. In this case check the followinf files:
Remote setup is done with ansible, using the root user. Run
and provide the root password when prompted.
If all goes well now you should have your remote machine ready for deploy. Visit your domain and you should see a maintenance page already there.
SSH connection error
If you see this error
fatal: [remote] => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.
means you missed adding an entry for one or more hosts in the ~/.ssh/known_hosts file, it's enough to try an ssh connection in order to add the domain to your list, then relauch
DB task error
If an error occurs in the create db user task:
msg: (1396, "Operation CREATE USER failed for ...
maybe you're trying to create a user which already existed and was delete. In this case just run this sql in the mysql database:
Deploy and Stuff
In the deployment process, the last revision of the git repository is deployed to the remote server. So be sure to have committed all your changes:
$ git add --all $ git commit -a -m "first commit"
Be sure the provided remote user has ssh access to the remote host, then deploy should be as easy as:
$ cd [repo_name] $ fab production deploy
launched inside the
root/repo_name folder. This command does the following things:
- create an archive of the last repository revision
- upload it to the server
- untar it in a folder "
app-revision_id" inside the releases folder
- copy the .env file inside this folder
- upgrade the virtualenv
- move the current release in the previous release (releases/previous)
- link the releases/current folder to the new release folder
- restart uwsgi and reload nginx
- open a shell in the remote
When performing the first deploy you can create a superuser account using the shell which the script leaves open at the end.
###Other useful fab commands
$ fab production rollback
If the deploy revision is broken, or introduces unexpected errors, with this command it is possible to rollback to the previous revision. Launching it another time will swap between the two revisions.
$ fab production reloadServer
Reloads the web server
$ fab production restart
Restarts the uwsgi service and the web server
$ fab production dumpDbSnapshot
Downloads the production current db snapshot in the backup folders. The dumped file has the remote current revision name.
$ fab production loadDbSnapshot
Loads the current remote db snapshot in the local db.
$ fab production offline
Puts the site in maintenance mode
$ fab production online
Exits from maintenance mode
$ fab production getRemoteRevision
Prints to screen the currently deployed revision