Django Continuous Deployment with GitHub and Codeship
15 Dec 2014 ⚠️ This post is over 10 years old. It may no longer be up to date.By setting up continuous deployment, any code committed to the master branch of your GitHub repository will be automatically checked out and tested by Codeship, and then deployed to your production servers. For our Django site it takes less than a minute after accepting a pull request for the new code to be live. The setup is fairly straightforward.
First I set up a new GitHub user account with read-only access to the project’s private repository. On the production server I created a new SSH key and added the public key to the new GitHub account. Since the script will be automated I used a blank passphrase.
I wrote a script to automate the deploy process on the server. This script is saved into the project repository, so it gets installed into the app directory on the production server (in my case /opt/my_app
).
To allow the script to reload apache I added the following line to my /etc/sudoers
file. This allows the last line of the script to run without prompting for a password.
django ALL=(ALL) NOPASSWD: /usr/sbin/service
On Codeship I set up a free account, linked it to the GitHub project, and set up the environment variables and test commands to build and test the project. Once this is set up every push (to any branch) will run these tests. This can be overridden by adding [skip ci]
in the commit messages to help stay below the 100 builds limit.
In order to deploy the site (assuming the tests pass), Codeship needs SSH access to our server. First check /etc/ssh/sshd_config
is set up to only allow public key authentication by setting:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
Make sure your own public key saved in ~/.ssh/authorized_keys
so you don’t lock yourself out. Add the codeship public key to the ~/.ssh/authorized_keys
file for the user that will run the deployment script.
The final step is to set up a new custom deployment command on Codeship for the master branch. This will look something like this:
ssh django@my_site.com "/opt/my_app/deploy.sh"