Docker: Right for Us. Right for You?
Some reflections from our adventures in Docker
Over the last two years, we've been using Docker more and more here at Viget. We're a consulting agency so our developers are cycling on and off a wide variety of projects, often times building and maintaining multiple distinct platforms simultaneously. Docker has provided a handful of specific wins with this setup, and brought with it a handful of it's own drawbacks:
Where Docker is Good
Running multiple versions of dependencies (eg: postgres)
This used to be a large pain every now and then, now it's not. What more can I say except thank you, Docker.
New developers onboarding to a project
Now when people onboard to a project with a sprawling tech stack, they don't have to become a local devops expert in order to configure their machine to run the app locally. We can usually abstract the build and setup to a handful of
docker-compose calls and they're up and running.
Running non-standard dependencies uniformly on everyone's machine (eg: redis, elasticsearch, background worker queues)
Similar to the problem of onboarding new people, onboarding new tech to a running team can involve a lot of work if everyone has to update their stack to accomodate the new tooling. Docker encapsulates a lot of the initial setup complexity.
Where Docker is Frustrating
While Docker can make it quicker and easier to get complicated architectures running on a number of developer (and non-developer) machines, it does so at a cost. Docker adds an additional layer of infrastructure between you (the human) and an application's runtime, which acts as a hurdle for a lot of standard development tools and strategies.
For example, one of the first issues I ran into was seeing that my breakpoints were suddenly unusable. When developing in a pure local environment, something like
binding.pry (Ruby) or
breakpoint() (Python) will halt the code mid-execution, and expose an interactive REPL for inspection. If you have a Rails application running via a docker-compose.yml file, those breakpoints hang, but there's shell to interact or continue with.
There is, of course, a solution to this issue (check out the follow on post to this: Docker + Rails), but it involves learning a bit about Docker and using more than just the basic
docker-compose build/up/down commands. Which really seems to be the story for most problems we've hit: the solution is out there, and the more you know about Docker / Docker Compose, the easier it is to find it.
For the type of work we do at Viget, working on multiple projects across wildly varying tech stacks, leaning on dependencies that range from cutting edge to practically abandoned, Docker has brought our team way more upsides than it has drawbacks.
I will mention that we haven't experimented with Docker in any of our deployment / devops processes. I know this is another selling point for people (bringing production / development environments closer together in behavior), but we haven't found a use case for that that seems more appealing than our current setup (primarily built on Terraform & Ansible).
Whether or not leaning on Docker is right for you is entirely dependent on the kinds of projects you're running and what team you have working on them. Something I can say with some certainty though is that Docker has the power to hide a lot of local devops pain points, so if you and your team are drowning in those, maybe give Docker a whirl.