Thursday, June 29, 2017

Up and Running with Django, Docker and Let’s Encrypt

This post first appeared here

In an ideal world, software companies would have dedicated teams for tasks such as managing infrastructure, software development or deployments. However, depending on the size of the company/team, this separation between Development and Ops (information technology operations) may not always be feasible.

At Ubiwhere we try to adhere to this methodology as much as possible, but there are times when our team becomes overwhelmed with their daily tasks. This means a developer can get “held up” waiting for the Sysadmin/Devops team to have time to help deploy a new app following recommended best practices.
This issue prompted a co-worker to spearhead the development of django-yadpt-starter, a small open-source tool to bootstrap new projects in Django, a Web Framework very near and dear to our heart. This tool essentially allows a developer to create a new Django project, based on our own custom Django Project Template with a fully automated setup using Docker Containers and a Let's Encrypt SSL certificate, all while adhering to recommended best practices.
A few key features:
  • Simplified initial setup with a single command and a couples answers;
  • Automatic generation and renewal of Let's Encrypt certificates;
  • Adheres to best practices;
  • Uses Docker and Docker-Compose;
  • Provides different environments: One without a valid certificate for local development and another with a valid certificate (for Production or Staging).
Now, any developer can create Production Ready Web Apps in minutes without “bothering” our sysadmin team, since this has already been validated by them.
Our main goal while building this tool was to package many moving parts in a consistent and reusable manner, all while keeping its usage simple.
We started with the obvious choice, Django Project Template, but quickly hit our first hurdle. At the time, Django didn’t have native support for passing extra context variables to project templates. Fortunately, we found a django package that allowed us to achieve this.
The next step was to create a docker-compose.yml configuration file with the “correct dependencies”. The nice thing about this approach is its pluggable nature. In other words, if your use case dictates you must use MongoDB instead of PostgreSQL, you can easily swap them in the compose file. We’ve added the stack we use at Ubiwhere but any component of the stack can be changed or upgraded.
Last but not least, security! The internet is teeming with insecure websites and we have no desire or intention to add yet another to the list. Fortunately, Let’s Encrypt allows anyone to generate free and valid SSL/TLS certificates. Since setting up SSL/TLS isn’t always trivial, another co-worker stepped in and containerized certbot, allowing us to easily add it to the mix.
In essence, the certbot container simplifies the process of generating and renewing a Let’s Encrypt certificate. This certificate is stored in a docker named volume, shared with the nginx container.
django-yadpt-starter still needs work, but despite that we’re already using it in production on a few of our sites and we couldn't be prouder.