$ cat post/green-text-on-black-glass-/-we-shipped-it-on-a-friday-night-/-the-log-is-silent.md
green text on black glass / we shipped it on a Friday night / the log is silent
Title: Dockerizing Our Monolith: A Journey Through Containers
August 25, 2014. It was a Tuesday in the middle of summer, and I remember feeling like we were on the brink of something big with our monolithic application. We had been talking about microservices for months—ever since containers started to gain momentum—but the idea of fully moving off our existing architecture was daunting.
We decided that this month would be the one where we start our journey towards containers. We picked Docker as it was the buzzword on everyone’s lips, and CoreOS had just released a version with container runtime, making it seem like the perfect fit for us. Little did we know what lay ahead in those first few weeks.
Our monolith was a beast of a thing. It spanned multiple tiers: web, workers, database, and cache—all tightly coupled together. The thought of breaking this down into microservices seemed insurmountable at first. But with Docker, the idea became a bit more tangible.
We started by setting up our CI/CD pipeline to build Docker images automatically from our development branches. I remember spending hours tweaking the Dockerfile to get everything we needed in there without bloating the image too much. The initial builds took forever and were plagued with permission issues and dependencies that didn’t play nicely together. It was a steep learning curve.
One of my earliest frustrations came when I tried running a container locally. After installing all the necessary tools, I couldn’t get it to work for love nor money. Turns out, I had forgotten to add sudo in front of the command to run Docker. This little oversight caused me to waste an entire morning before finally realizing my mistake.
As we began deploying these containers on our staging environment, issues started cropping up. Network configurations were off, and inter-service communication was problematic due to the tight coupling that had been baked into the monolith for years. We found ourselves spending a lot of time debugging these sorts of issues, which felt like step backwards from where we had begun.
One day, I remember arguing with my team about whether or not we should have an init process inside our Docker containers. The idea was to keep the container clean and avoid running any unnecessary processes. However, some of my colleagues argued that this would cause problems when containers died unexpectedly, leading to application crashes. It was a classic debate: simplicity vs reliability.
Ultimately, we decided to take a pragmatic approach, using supervisord inside our Docker images to manage the process lifecycle. This way, if any child processes failed, they could be restarted without killing the whole container.
Around this time, Kubernetes made its debut at Google I/O 2014. Watching videos of Kubernetes in action was inspiring but also a bit overwhelming. The promise of orchestration and automation seemed too good to resist, even though we didn’t have enough containers yet for it to be really useful.
Despite the setbacks, there were moments of triumph. Setting up a Docker-based deployment pipeline felt like progress. We could deploy changes more frequently without having to worry about service availability during the process. That was something we hadn’t had before with our monolithic setup.
By the end of August, we had successfully containerized several services and were starting to see the benefits of this approach. The next step would be to break down even more components into smaller, isolated containers, which would set us up well for a full migration to microservices in the future.
Looking back, those first few weeks with Docker felt like a mix of excitement and chaos. But we learned so much along the way—from dealing with permission issues, understanding how init processes work, and learning the value of proper configuration management. It was a journey that I’m glad we embarked on, even if it wasn’t always smooth sailing.
This blog post captures the early days of Docker’s adoption in our organization, the challenges faced, and the lessons learned during this transition period.