Most computer operating systems suffer from some version of “DLL hell” — a decidedly Windows term, but the concept applies across the board. Consider doing embedded development which usually takes a few specialized tools. You write your embedded system code, ship it off, and forget about it for a few years. Then, the end-user wants a change. Too bad the compiler you used requires some library that has changed so it no longer works. Oh, and the device programmer needs an older version of the USB library. The Python build tools use Python 2 but your system has moved on. If the tools you need aren’t on the computer anymore, you may have trouble finding the install media and getting it to work. Worse still if you don’t even have the right kind of computer for it anymore.
One way to address this is to encapsulate all of your development projects in a virtual machine. Then you can save the virtual machine and it includes an operating system, all the right libraries, and basically is a snapshot of how the project was that you can reconstitute at any time and on nearly any computer.
In theory, that’s great, but it is a lot of work and a lot of storage. You need to install an operating system and all the tools. Sure, you can get an appliance image, but if you work on many projects, you will have a bunch of copies of the very same thing cluttering things up. You’ll also need to keep all those copies up-to-date if you need to update things which — granted — is sort of what you are probably trying to avoid, but sometimes you must.
Docker is a bit lighter weight than a virtual machine. You still run your system’s normal kernel, but essentially you can have a virtual environment running in an instant on top of that kernel. What’s more, Docker only stores the differences between things. So if you have ten copies of an operating system, you’ll only store it once plus small differences for each instance.
The downside is that it is a bit tough to configure. You need to map storage and set up networking, among other things. I recently ran into a project called Dock that tries to make the common cases easier so you can quickly just spin up a docker instance to do some work without any real configuration. I made a few minor changes to it and forked the project, but, for now, the origin has synced up with my fork so you can stick with the original link.
The documentation on the GitHub pages is a bit sparse, but the author has a good page of instructions and videos. On the other hand, it is very easy to get started. Create a directory and go into it (or go into an existing directory). Run “dock” and you’ll get a spun-up Docker container named after the directory. The directory itself will be mounted inside the container and you’ll have an ssh connection to the container.
By default, that container will have some nice tools in it, but I wanted different tools. No problem; you can install what you want. You can also commit an image set up how you like and name it in the configuration files as the default. You can also name a specific image file on the command line if you like. That means it is possible to have multiple setups for new machines. You might say you want this directory to have an image configured for Linux development and another one for ARM development, for example. Finally, you can also name the container if you don’t want it tied to the current directory.
This requires some special Docker images that the system knows how to install automatically. There are setups for Ubuntu, Python, Perl, Ruby, Rust, and some network and database development environments. Of course, you can customize any of these and commit them to a new image that you can use as long as you don’t mess up the things the tool depends on (that is, an SSH server, for example).
If you want to change the default image, you can do that in ~/.dockrc. That file also contains a prefix that the system removes from the container names. That way, a directory named Hackaday won’t wind up with a container named Hackaday.alw.home, but will simply be Hackaday. For example, since I have all my work in /home/alw/projects, I should use that as a prefix so I don’t have the word projects in each container name, but — as you can see in the accompanying screenshot — I haven’t so the container winds up as Hackaday.projects.
Options and Aliases
You can see the options available on the help page. You can select a user, mount additional storage volumes, set a few container options, and more. I haven’t tried it, but it looks like there’s also a
$DEFAULT_MOUNT_OPTIONS variable to add other directories to all containers.
My fork adds a few extra options that aren’t absolutely necessary. For one, -h will give you a short help screen, while -U will give you a longer help screen. In addition, unknown options trigger a help message. I also added a -I option to write out a source line suitable for adding to your shell profile to get the optional aliases.
These optional aliases are useful for you, but Dock doesn’t use them so you don’t have to install them. These do things like list docker images or make a commit without having to remember the full Docker syntax. Of course, you can still use regular Docker commands, if you prefer.
To start, you need to install Docker. Usually, by default, only root can use Docker. Some setups have a particular group you can join if you want to use it from your own user ID. That’s easy to set up if you like. For example:
sudo usermod -aG docker $(whoami) newgrp docker sudo systemctl unmask docker.service sudo systemctl unmask docker.socket sudo systemctl start docker.service
From there, follow the setup on the project page, and make sure to edit your ~/.dockrc file. You need to make sure the
DEFAULT_IMAGE_NAME variables are set correctly, among other things.
Once set up, create a test directory, type
dock and enjoy your new sort-of virtual machine. If you’ve set up the aliases, use
dc to show the containers you have. You can use
dcr to shut down or remove a “virtual machine.” If you want to save the current container as an image, try
dcom to commit the container.
Sometimes you want to enter the fake machine as root. You can use
dock-r as a shorthand for
dock -u root assuming you installed the aliases.
It is hard to imagine how this could be much easier. Since the whole thing is written as a Bash script, it’s easy to add options (like I did). It looks like it would be pretty easy to adapt existing Docker images to be set up to be compatible with Dock, too. Don’t forget, that you can commit a container to use it as a template for future containers.
If you want more background on Docker, Ben James has a good write-up. You can even use Docker to simplify retrocomputing.