If you’re not already following Mischa van den Burg on Youtube, go do it now. Mischa has some really good content for developers and engineers alike. His most recently video (as of the time of this writing) is on the topic of using devpods.sh to create a portable development environment. This got me thinking about how I create my development environments and if there was a possibility that I could leverage any of the ideas in my day-to-day work.
Present Day
My current development environment is pretty straight forward in terms of tools. I use Neovim (Actually I use LazyVim but that’s a topic for another day) and that’s about it. I have a bunch of customizations and plugins for it, but at the end of the day, it’s just Neovim doing the heavy lifting.
The Motivation
To put it bluntly; shit happens. Since starting with Mailchimp in 2016 I’ve had six laptops. Some of these were replaced after the standard three years but, in reality most were replaced due to theft, hardware failure or company acquisition. Each time, it would take me at least a day or more to get back up and running at 100%. This is wasted time. I need a better way to manage things.
Early attempts
Early in my quest to improve this situation I experimented with several options,
some of which I still use to this day. Take, for instance, my dotfiles. I use
dotbot to manage and bootstrap my
dotfiles in a way that keeps them organized and makes re-installing them a
breeze. But this leaves a few loose ends in the form of installed software
packages. I tried to mitigate this by generating a Brewfile
of all the
software I have installed, but that was never quite comprehensive enough and
seemed to always require a little extra work every time I had to rebuild the
world.
I eventually stumbled upon Nix. The idea of having a standardized way to declare packages and configuration in a single place seemed like it would be a great idea… in theory, at least. In practice, I found Nix to be more than I needed and I was spending more time fighting the configuration than it was worth. Additionally, using Nix to configure applications, while genuinely an interesting and good idea in some cases, can be problematic when you’re trying to learn a new program, plugin or configuration. Most online resources will assume you’re configuring the application directly and, while I’m sure someone who is very familiar with Nix configuration would have little trouble translating, I found it very difficult to learn to configure new software in Nix as I was usually unfamiliar with both.
Devcontainers
Finally, we arrive at the meat of the topic, devcontainers and, more specifically devpods.sh. I’ve been using containers for a long time in my development workflow. Usually, it’s for building and testing my code to ensure I’m doing so in a sterile environment that I know will work in CI (since CI does everything in a container too). I’ve even gone so far as to try and execute builds and tests on a remote docker host with varying degrees of success. But it never occurred to me to move my entire development environment in to a remote container for the simple reason that it always seemed like it would be more trouble than it was worth. Now, using devcontainers and devpods, I can easily define a fully functional environment in just a few steps and while I don’t believe I’ve yet fully realized the potential here, I am already definitely seeing how it could be a powerful option.
Now, the only thing I need to install on my physical machine is devpods itself, configure a local or cloud backend provider and clone my code. The rest of it, my editor, my test suites and my system tools are all ecapsulated inside of the devcontainer itself and a simple (reusable) setup script used during initialization of the environment.
The best part of all of this is that it’s platform agnostic. I no longer need to worry about what OS I’m on or if it supports Docker or how much battery life will suffer from running all these containers. If I’m on a low powered device such as an tablet or Chromebook, I can pull up a terminal Linux terminal, install the AppImage for devpods, configure Google Cloud, Digital Ocean or even my home K3S cluster as the backend provider, clone my code and I have the same exact development environment as I would on my Macbook Pro or desktop computer.
Conclusion
I know I didn’t really cover any technical details in this post and that was actually intentional. Mischa has covered the details of everything I’ve talked about here on his Youtube channel and his Github. So I highly encourage you to learn more by going and checking out his content and experimenting with this yourself.