Docker: have a Ubuntu development machine within seconds, from Windows or Mac

Much faster than any Virtual Machine, Docker allows you to run a Ubuntu image and gain interactive access to its shell, so you can have _all_ your dependencies in an isolated Linux environment and develop from your favourite IDE, anywhere.

Introduction

Setting up development environments is often a pain in the neck.

Package management has come a long way, but it can only do so much considering the diversity of dependencies commonly in use.

If you are on Windows and need some Linux features, even worse! You will have to emulate bash (or facing the OverlayFS problems dealing with NTFS on the Windows Bash).

Either way, nothing is better than being inside a REAL LINUX ENVIRONMENT, with all required dependencies installed into it.

The alternative, would be Virtual Machines. The slow virtual machines. Vagrant has done a good job automating their setup. But they are so slow, and so heavy, very much because of their architecture, it’s true.

But we have to suffer no longer. Docker can give you free-of-charge an instantaneous Linux Development Environment (after base layers are downloaded), and I will show you how its done here!

Starting simple: Instantaneous Ubuntu, in case you are on Windows or Mac

In this first part, I will get familiar with the basis of working with an interactive docker container.

This is the very ground level knowledge on how using Docker as a user environment, rather than a standalone container with an app running in it, and very important to what we are going to do here.

Running the Ubuntu Machine

The Docker Support for Windows has already been out there for a while and and it’s pretty good. If you haven’t yet downloaded it, it’s time to do so.

Run the command:

docker run -t -i ubuntu /bin/bash

Either if are on Windows or Mac, you will see something rather familiar:

root@50afd5fb7cc5:/#

This is a Linux root bash, and despite the no-waiting for loading, it’s really a full fledged linux machine, ready to receive your commands. You can try ls / to check the file system.

Practicing on the Ubuntu Machine

Before we move on, let’s practice on this linux box, because it will die soon anyway, so we can do really whatever we want here.

Notice, all these commands will be run within the prompt root@50afd5fb7cc5:/#. If you exit this prompt, you are back to your operating system, and you require extra steps to have this machine up and running again.

apt-get install -y curl

You will notice the response:

Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package curl

The apt-get doesn’t even know the package curl. The reason for this is that this ubuntu image, in order to be as light as it can be, came without the “layer” that would pull the package list.

Let’s do it and get curl installed.

apt-get update
(...) # downloading package list
apt-get install -y curl
# curl package installed
curl https://www.google.com

Once this is finished, you will exit, and go back to your operating system.

exit

Cleaning up the dumped docker containers

Once you exited your docker container, it’s no longer available. The reason for this is because it will only live time enough to perform it’s entrypoint task.

The lifetime of a container is the life time of its single main process. This forces every docker container to have a specific purpose and live by the unix maxima: “do this one thing, do it well”.

Time to check docker, see what happened with it:

docker ps -a

And you will see something like this:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                    NAMES
50afd5fb7cc5        ubuntu              "/bin/bash"              17 minutes ago      Exited (0) 16 seconds ago                            serene_allen
1f21f7c52653        postgres            "docker-entrypoint..."   23 hours ago        Up 23 minutes               0.0.0.0:5432->5432/tcp   postgres

When you don’t attribute a name to your container, docker attributes a random name. On my case, serene_allen. In yours, it will be different, but you can certainly find your ubuntu by its image name, invariably ubuntu.

I don’t wanna leave this image there, and in order to do the cleanup, I will use this command here:

docker rm -f serene_allen

And then, another docker ps -a will reveal that my serene_allen container is gone.

Ubuntu machine with external “Volume”

It’s possible to run containers with “volumes” attached to it, directly from your machine, so that the containers will have the exact same version of files you are editing locally.

First, have a folder in your local machine, easy to find in terms of absolute path, and make sure you have some files/folders in this folder. You may already have your sources folder, use that, it will be ideal.

I’m using a hypothetical C:\Users\hudson\Workspaces, use your own absolute path instead of it.

On Windows

Make sure you have the C: (or any other driver you will map) shared in your Docker Configuration:

Then run on your docker CLI powershell:

docker run `
--name ubuntu `
-e HOST_IP=192.168.1.166 `
-v //c/Users/hudson/Workspaces:/src `
-t -i `
ubuntu /bin/bash

On Mac

Simply run on your Terminal:

docker run \
--name ubuntu \
-e HOST_IP=$(ifconfig en0 | awk '/ *inet /{print $2}') \
-v /Users/hudson/Workspaces:/src \
-t -i \
ubuntu /bin/bash

A Few Notes

  • This is a named container: ubuntu
  • The HOST_IP should have your host machine’s (the one that runs docker) IP address, in order for your container to able to access services (such as the database) in your host machine.
  • We are mapping the volume using the “-v” flag [local]:[destination], which will be mounted inside our container

Now, inside the virtual machine, check your /src and notice that your source can be found there.

ls /src
belfastjug
boxfish hudsonmendes lean-pirates oohm spring

We can now edit files in our IDE and run them in our Docker

There’s nothing stopping us from it now.

Say that you use your favourite editor (mine is Visual Studio Code, at the moment), and you want to run your app (rails server, your gradle boot, your sails lift), but you don’t have the dependencies installed in your machine? It’s now possible from your Docker container.

Happy coding!