By now, most IT professionals will have heard of Docker and containers. They’re either using containers, or are considering doing so in the future.
Personally, I’m something of a recent convert to the idea of using containers. Until I started in my current role at Divido, all of my employers had been using more traditional hosting environments; some were even actively hostile towards the idea of containers.
Obviously, containers aren’t the only way to host an application. The old way of dedicating an entire physical or virtual server to an application still works, and may even be necessary in some scenarios.
Containers aren’t perfect, either. Things can, and do, go wrong. New processes have to be put in place for development, deployment and security. New skills have to be learned (and there’s an enormous amount to learn).
So, what are the benefits? Why should you even bother?
One problem I’ve seen again and again is that it’s hard to set up a new environment for a given application. Typically, the process is poorly documented (if at all), and involves a significant amount of manual work, installing specific packages, setting up firewall rules…
Containers help with this by forcing you to understand the environment in which
your application is running. Your
Dockerfile becomes a self-documenting record of
the packages your application needs, of the environment variables that need to be
set, of the ports that need to be exposed. And then, next time you need a new
Dockerfile can be used for that too.
As a bonus, the generated image can be treated as immutable; if you need to run that exact version of your application again in the future (perhaps to confirm when a bug was first introduced), then you can just pull the old version and run it directly.
If you’re used to a traditional hosting environment, then you might have multiple applications running on a single server. So what happens when one of those applications is updated and requires a newer package version (say, a PHP app that requires 7.2 instead of 5.6)?
In my experience, a lot of griping, moaning and an eventual rejection of the upgrade because it’s deemed to be too risky, or because it’ll break the other applications.
You could move the app to another server, but then you’ve increased your infrastructure costs, and the client may not accept that… but with containers, each app is isolated from the others, so that they can each run whatever version of PHP (or whatever) they need.
This isolation may also force you to realise hidden dependencies between the applications, such as a shared filesystem or configuration file.
In a traditional hosting environment, it might be tricky to scale out your application (by adding more servers). This could be because it’s difficult to set up a new server (as discussed under Reproducibility), but also because it’s expensive to have more servers running than you actually need. With containers, you can run as many extra instances of your application as you need, and then shut them down again later - easily! You can even automate the scaling process.
Of course, this assumes that your application was architected to be scaled out in the first place - if not, containers aren’t going to help, and you’ll have to do some work in that area first.
Since your application is running in an isolated environment when inside of a container, it can only access the resources you allow it to. That reduces (but doesn’t eliminate) the risk that a malicious user can trick your application into giving them access to things they shouldn’t be able to get to.
Even in a containerised world, you still need to make sure that your application code itself is secure; that any libraries you’re using are up-to-date and free of known security bugs; that your OS is up-to-date. Thankfully, there are tools for all of these, and you should really be using them anyway, whether you’re using containers or not.
I think most software developers understand that differences between their development environment and production can be a cause of bugs and much frustration.
By using containers in development as well, you know that you’re using the exact same software versions that you’ll be running in production. This solves the well-known “works on my machine” problem… albeit by effectively shipping your machine to production, in the form of a container.
In many of the organisations I’ve worked for, deployment has been a painful process,
full of manual steps and considered to be high risk (particularly one company I
worked for, where deployment was “
ssh into the server and run
svn up in the
correct directory” - the guilty parties shall not be named, they know who they are).
With containers, you build an image, then pull that image on the server and run it. It’s pretty much foolproof. And rollbacks, should you need them, are as easy as running an older version of the application.
Obviously there are more advanced techniques; your CI tool can automatically pull and deploy the latest image on your behalf, for example, or you can do a rolling deployment where old and new versions of your application exist concurrently for a brief period, avoiding downtime.
Containers may not be the best solution, longer term. We may all decide that there are better ways, as yet unknown to us. That said, I’m convinced that they’re the best solution right now for most of us.
As few as three years ago, I couldn’t see what advantages containers might have; I was used to the way things used to be done, and I didn’t want to make a leap into the unknown and unproven technology.
But that was then, and the container landscape has matured significantly in the intervening period. The software is better, the user experience is better, and there are significantly fewer bugs. All this means is that now, I have no hesitation at all in recommending containers.