How Not to Use Containers: A Guided Tour
How Not to Use Containers: A Guided Tour
This developer shares his experience with developing inside a container and some of the challenges he faced in creating an environment he could code in.
Join the DZone community and get the full member experience.Join For Free
Containers (more specifically, instances of OS-level virtualization), because of their utility in production and CI/CD environments, can start to seem like a viable remedy for headaches in the development process. I decided to give development from inside a container a try, and what follows is my experience of the process.
Spoiler alert: developing software from inside a container wasn’t the panacea I’d hoped for.
The impetus for my investigation was mostly headaches around managing dependencies. When I’m writing Python, for instance, the docopt package tends to get me in trouble. It’s a package for parsing and using an app’s command line arguments. I love it for its simplicity, how easy it is to use, and that it’s just as powerful as I need it to be. I even use it for scripts I’ve thrown together for personal use. It’s one of those frequently used packages that just ends up installed everywhere I go, whether I intend it to or not.
And that’s the problem: docopt is so ubiquitous in my environments that I forget it probably represents a new dependency whenever I pass along a script or push changes that depend on it. When that happens, the application fails everywhere docopt isn’t installed.
You may also enjoy: Why Should We Care About Containers for Development?
When I finally resolved to do something about this, I leaned toward containers. My previous experience with containers was very hands-off; I only utilized them in the context of CI and deployment where they seemed to add value. But I’d heard they could also make my life developing software easier by letting me work in a more isolated environment. Unfortunately, when I went hands-on with containers for development I had some real challenges, not the least of which was that I’m not an expert in how to use Docker.
The experiences that follow aren’t meant to be an indictment of the tooling. Rather, you should view them as common pitfalls to be avoided. If, like me, you don’t have access to someone that’s well-versed in containers, this guide should be instructive.
The first hurdle was figuring out how to go from “Hello world” to something that addressed my specific needs. I favored Docker because it’s popular, with plenty of documentation, blogs, and Stack Overflow conversations. But Docker is a power tool, and while that can be useful for complex workflows, it doesn’t really lend itself to quickly setting up with an isolated environment to just hack in. At times, it feels like using a jackhammer to cut a cupcake. Getting through the well-documented tutorials is easy enough, but figuring out how to go from no container to something I could SSH into took awhile. Figuring out how to get back into it after exiting took embarrassingly long. It is surmountable though, with a bit of perseverance and a trail of notes. Here’s the need-to-know cheat sheet:
- Spin up a bare-bones Ubuntu Container
docker run -t -i ubuntu /bin/bash
- List the IDs of the existing containers
docker ps -a
- Get back into the container once you’ve exited
docker start -i <your container’s ID>
Pretty trivial in retrospect, but just like Git, which took me a fair amount of time to get comfortable with when I first started out, it’s paid off and now I feel at home using it. I felt optimistic that learning Docker would pan out similarly.
The next issue arose once the initial container was up and running and it was time to write some code in it. Once Git was installed, in order to clone a project to experiment with, cloning with SSH failed because I hadn’t set up authentication. If you’re like me, setting up SSH and GPG keys is always an exercise in looking for how-to docs: I can never remember exactly how I did it last time.
Once I had a project cloned I needed an editor, which would be easy enough if you’re a barebones Vim or Emacs user —just install them. But that’s like sleeping on a bed without sheets or pillows or blankets: possible but uncomfortable. Docker does make it easy to copy files over from the container’s host, so importing your local configurations for a terminal friendly editor is as simple as:
The same goes for any other configurations, including my .bashrc, .bash_aliases, and .bash_profile. However, my editor of choice is VS Code, which I don’t use directly in the terminal. Once I knew what to look for, I was able to use VS Code on my desktop to write to files in my container using the Remote Development extension pack.
Along the way I kept bumping into things I’d missed: I’d forgotten to copy my global .gitconfig, and a script I wrote that prints a constellation to the terminal when I need some vertical space. I needed to apt install curl. Everything I bumped into was another thing to negotiate before I could start developing.
With an editor working, some basic packages installed, authentication set up, and my particular flavor of configurations and scripts, my container started feeling like home. I could write, build, test, and publish code. But a container that feels like home starts to defeat the purpose of isolation. Instead of building a workshop inside my house, I’d just painstakingly crammed my house into a workshop.
While Dockerfiles, Ansible Scripts or Puppet Plans could have helped make my “home” something I could more easily recreate programmatically, I would have needed to level up my skills again and learn more sophistication. It felt like I wasn’t solving a problem so much as creating more, which left me feeling fatigued.
Since my experimentation, I’m happy to feel comfortable using Docker containers to quickly validate that something that should work in an unpolluted environment actually does. But those containers are very short lived, and I don’t develop inside them.
For Python development in particular, there are quite a few alternatives to Docker. I’ve started leaning on things like dependencies in distributions rather than individual packages, as well as “isolation from within” solutions like Python virtual environments.
The right place for development for me is the machine I spend all my time on. The one that has my favorite scripts, editors, browsers, music players, and so on. Likewise, the right tool for development is the one that keeps runtimes scoped to the projects they apply to, without requiring the developer to either leave the place that feels like home, or learn to use a jackhammer in their kitchen.
Docker For Beginners
Opinions expressed by DZone contributors are their own.