We’ve been making some opinionated choices about our deployment practices at Code for South Africa. Here’s what we’re doing and why.
We’ve been making some opinionated choices about our deployment practices at Code for South Africa. We’ve found it improves collaboration and helps us build better products, more quickly. There are many ways to improve collaboration and opinionated deployments may seem like an odd one. Here’s what we’re doing and why.
We work on a number of websites and web applications, ranging from one or two page apps such as Protest Map and Hospital Finder to rich websites such as Wazimap.co.za and complex web applications like Dexter. We’re also a small team working with limited budgets and tight deadlines, so ad-hoc collaboration is an important part of helping us move quickly. We might need Jason to help Petrus out on a project just for a day or two, or I might see the opportunity to make a quick layout change to one of our websites.
As our project portfolio has grown, so has the variation in how we deploy our projects. Some projects use Fabric scripts while others are manual and rely on steps documented in README files, and all are slightly different. This makes it time consuming, difficult and frustrating to grab the project from the repo, make and test a change, submit a pull request and then deploy the change. Naturally, this meant that collaboration only happens when forced.
Surprisingly, the richness of our development environment leads to this problem. There are infinitely many ways to do build out a server, deploy a web application, serve static assets, and the like. That means we have to learn a new permutation every time we want to work on a project. By reducing our choices to one or two, we can focus more on where that richness delivers value, rather than choosing yet another way of giving a database connection string to our app. It’s more important for collaboration that we have consistency than infinite flexibility.
Humans are lazy: if collaboration is easy, it’s more likely to happen. So let’s make it easy by making it consistent.
I’m a big fan of Heroku and GitHub Pages. Both are opinionated about how web apps are deployed and, importantly, put constraints on our choices. They also have another huge benefit over any home-grown solution: extensive documentation and large communities.
We use Heroku for apps that require server-side functionality such as databases. It supports a number of languages and frameworks and has useful opinions:
If an app outgrows Heroku and we want to host it on our own cloud servers, we don’t have to start from scratch. We can use Dokku to run a Heroku-like environment using Docker.
We use GitHub Pages for static websites and client-side apps. There’s really no good reason to host a static website yourself any more. I absolutely love that I can accept a contribution and deploy it just by clicking Merge on a pull request.
Opinionated deployments also have benefits to the larger community in which we work. All of our work is open sourced on GitHub and so it’s important that the larger community can build on and contribute to our work. If we were using a home-grown solution we’d have to spend time documenting our processes. By using Heroku and Git Hub pages, we get the benefit that a lot of the community already knows those platforms and there’s great documentation out there to lean on if they don’t.
The opinionated deployments described above have the additional benefits of enforcing some other development and deployment best practices:
Heroku and GitHub’s choices aren’t the only way to do these things, but they’re consistent and well-documented.
We’re migrating all our sites and apps to use these frameworks in a bid to make collaboration simpler and easier, so we can spend more time delivering value and less time on undifferentiated heavy lifting.