Managing a developer shell with Docker
When I’m not in Flowhub-land, I’m used to developing software in a quite customized command line based development environment. Like for many, the cornerstones of this for me are vim and tmux.
As customization increases, it becomes important to have a way to manage that and distribute it across the different computers. For years, I’ve used a dotfiles repository on GitHub together with GNU Stow for this.
However, this still means I have to install all the software and tools before I can have my environment up and running.
Using Docker
Docker is a tool for building and running software in a containerized fashion. Recently Tiago gave me the inspiration to use Docker not only for distributing production software, but also for actually running my development environment.
Taking ideas from his setup, I built upon my existing dotfiles and built a reusable developer shell container.
With this, I only need Docker installed on a machine, and then I’m two commands away from having my normal development environment:
$ docker volume create workstation
$ docker run -v ~/Projects:/projects -v workstation:/root -v ~/.ssh:/keys --name workstation --rm -it bergie/shell
Here’s how it looks in action:
Once I update my Docker setup (for example to install or upgrade some tool), I can get the latest version on a machine with:
$ docker pull bergie/shell
At least in theory this should give me a fully identical working environment regardless of the host machine. Linux VPS, a MacBook, or a Windows machine should all be able to run this. And soon, this should also work out of the box on Chromebooks.
Setting this up
The basics are pretty simple. I already had a repository for my dotfiles, so I only needed to write a Dockerfile to install and set up all my software.
To make things even easier, I configured Travis so that every time I push some change to the dotfiles repository, it will create and publish a new container image.
Further development ideas
So far this setup seems to work pretty well. However, here are some ideas for further improvements:
- ARM build: Sometimes I need to work on Raspberry Pis. It might be nice to cross-compile an ARM version of the same setup
- Key management: Currently I create new SSH keys for each host machine, and then upload them to the relevant places. With this setup I could use a USB stick, or maybe even a Yubikey to manage them
- Application authentication: Since the Docker image is public, it doesn’t come with any secrets built in. This means I still need to authenticate with tools like NPM and Travis. It might be interesting to manage these together with my SSH keys
- SSH host: with some tweaking it might be possible to run the same container on cloud services. Then I’d need a way to get my SSH public keys there and start an SSH server
If you have ideas on how to best implement the above, please get in touch.