DEV Community

Felipe Santos
Felipe Santos

Posted on


Dev Ubuntu 20.04: the history of a Virtual Machine managed as a Docker image

First, what is it? This is a pre-configured Ubuntu 20.04 virtual machine that you can use for general development. With just a few steps you can have it up and running, ready to code, and adjusted to your needs.

But why? Why not install my own Ubuntu ISO in Virtual Box and do what it takes inside of it? And that's a good question. The answer is that you don't have a fully reproducible, disposable, shareable, and managed environment that way. And I know, that sounds a lot like how Docker images work in the containers world.

That was the main motivation: Docker with their Dockerfiles and how the images can be stored in a registry, ready to be used. Luckily, for the virtual machine world we have Vagrant, which aimed to solve the problem I was trying to solve: you can define a Vagrantfile and set some commands to run when you power up the machine. And then, you have the Vagrant Cloud, a place to store these machines.

So far so good, but then things started to become more interesting. Most of the base boxes (pre-built virtual machines you can use as a base in the Vagrantfile) didn't have a desktop installed. And looking at the official guides from Vagrant, they suggest we use Packer, which can take a Linux ISO and start making modifications on top of. But it sounded too bare metal for my purpose, I just wanted to take an Ubuntu and apply some changes on it, the same way we do in Docker.

For solving that problem I first used bento/ubuntu-18.04 as the base box. It's kind of an official Ubuntu base box in the Vagrant Cloud, considering that the Canonical's one had some blocking issues. But later, when I switched to Ubuntu 20.04, I chose peru/ubuntu-20.04-desktop-amd64. It appeared to be a solid base box with desktop already installed. I even contributed to opening an Issue in its GitHub repository.

Then, I wanted to make it automatic. I wanted to do only the code part, such as adding a new tool in the virtual machine, and levering computers to build and release it for me. But there were two obstacles: I would need a CI that supports virtualization to run Vagrant and Virtual Box to build the machine. And I would also need a CI that supported a fake display, to run a simple test of the box after it's being built. Fortunately, Travis has these two. I would be happy to use the awesome GitHub Actions and even contribute with some actions for the same purpose, but sadly, it doesn't support nested virtualization.

The next step was to manage the release cycle. For my luck, I met semantic-release, a popular module to automate the releases in Node.js projects, relying on commit messages that follow a convention, and in my case, the Conventional Commits. I immediately fell in love with it and was excited to integrate into my project. I first had to find a way on how to enforce Conventional Commits on my repository, and then, make semantic-release be able to push it to Vagrant Cloud.

I managed to convert my repository into an NPM based one, mainly due to its package.json since I would be using many NPM modules. But I was so happy with the result, that this even started a side project: a Vagrant plugin for semantic-release, but still in an early development stage.

So now, if I want to add a new tool or new customization in the virtual machine, I just have to add the commands I want to a Bash script and commit to GitHub. After merging on the master branch, Travis automatically builds the virtual machine and then semantic-release deal with the bureaucracy of the versioning and releases for me.

It was also much-pleasant to receive the first Issue the project from the community, which led me to create a brand new badge to display the sizes of any boxes in Vagrant Cloud. And you can use it right now! See this preview:
Vagrant box size

I suggest you give it a try. Take a look at the Get started guide, it's simple. There are some tips for personal customizations, such as my own.

And there are still plans for the future:

  • Continue the development of the Vagrant plugin for semantic-release, to help other people automate their releases without having to rely on complex Bash scripts.
  • Create a repository template to help other people scaffold their own fully managed virtual machine, which I think can be beneficial for development teams, that want to enforce the same environment efficiently.
  • Somehow integrate with dotfiles repositories, and many other tricky adjustments to be made programmatically.

Link to Code

GitHub logo felipecrs / dev-ubuntu

A Vagrant box with desktop, tools, and adjustments for developers

Deprecation notice

I have not been using this box anymore because I prefer to use WSL2 on Windows rather than VirtualBox, so it does not make sense to me to keep maintaining it.

Furthermore, I have putted much more effort on my dotfiles, which contains the latest and greatest enhancements, and then I use it to bootstrap any VM with a single command. That means that for me, my dotfiles is replacing this project.

If this project worked well for you and you would like to keep using it (instead of moving to some dotfiles-like approach), I would suggest you to fork this repository and setup your own.

Ephemeral development environments such as Gitpod and GitHub Codespaces has never been so popular, and that is another reason why not to use a heavy VM.

The latest version of this box will still be available in Vagrant Cloud to download…

Download link

Available on Vagrant Cloud

Top comments (0)

An Animated Guide to Node.js Event Loop

>> Check out this classic DEV post <<