Docker

Updated:

Docker is a great tool for managing web servers in easily deployable, configurable, and disposable containers. The gist of it is that much like Vagrant, you can create your own containers or spin up an existing one you find at the Docker Store. Many vendors have official containers, such as for php, wordpress, httpd, mysql, mariadb, etc. Before you build a web app for a certain framework, check to see if someone’s already made a container for it.

It is a great solution for any host OS, but the guest OSes are limited to Linux-based. In the early days of Docker Toolbox, the containers that ran on VirtualBox VMs provided a lot of Docker’s features, but there were some differences with ownership/permissions in that these settings on a Linux host are intrinsically connected to such settings in the container, but for Windows it’s just a totally separate user admin context. In macOS however, there is some overlap in the users/permissions available in the host and container. Also, back in the day, you just had to remember to look in the VirtualBox machine for all of Docker’s volumes and other data. Now you can get a lot more similarity along the lines of Docker for Linux with Docker for Windows and Docker for Mac.

An unfortunate disadvantage to the more recent Docker for Windows is that the Hyper-V extension must be enabled in order to use it. Enabling this extension also forces the disabling of the virtualization setting in your BIOS that is required to use VirtualBox. As a result, you will not be able to use both Docker for Windows and still use VirtualBox for other projects. It’s not all too bad of a situation because it turns out that Hyper-V provides many of the same features as VirtualBox so that you can use it to load OSes from disks or what-have-you into VM environments much like the program you have already known so long and loved. I have not yet tried it, but the instructions for loading, say, a Linux OS in Hyper-V look pretty straightforward.

Docker for Mac also uses a native utility in macOS called the Hypervisor framework instead of VirtualBox. The folks at Docker built a tool called Hyperkit for interfacing with this framework. Luckily, you can use can still use VirtualBox while using Docker for Mac, but you’ll definitely want to use all the advantages of Docker for Mac instead of continuing to run Docker in VirtualBox.

Both Docker for Windows and Mac are rather nice tools for working with Docker itself. The user interface for both is very similar. You basically use it to manage the service that needs to run, but it has a lot of other uses. On Windows, be absolutely sure to open the Settings and look at the Shared Drives tab where you can enable which drives can be used for bind-mounted volumes. There will even be a command-line example to show you the format for paths. You used to have to escape all this nonsense in a Window’s file path but now you can just use forward-slashes instead of backslashes.

In Docker for Mac, you’ll want to go to Preferences -> File Sharing to manage which directories and subdirectories can be used for bind-mounted volumes.

Also for both versions, you will definitely want to use Kitematic. It is an excellent companion program that allows great insight into the state of your containers, a quick way to look at their logs, their volumes, their network settings, and plenty more. It beats running a whole bunch of CLI commands anyway.

Volumes and MySQL

When using a database container like the official mariadb one, you may find yourself wanting to backup the data directory on the host. This is quite easy with a Linux host following their example run command:

$ docker run --name some-mariadb -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mariadb:tag

This will bind mount /my/own/datadir on the host to to the database data folder in the container. This also works with Docker for Windows and Mac.

You can also save the data directory to a volume by way of the VOLUME command in a Dockerfile.

VOLUME ["/var/lib/mysql"]

Sadly, I cannot recommend doing this on Docker for Windows because mysql is expecting to write files to a case-sensitive file system. From what I have read, there just may be a way to create a case-sensitive disk/directory in Windows as you can in macOS. Anyway, if you make mysql write its data files to a Windows case-insensitive directory, it will have trouble creating the necessary files. This isn’t too bad in the end because you probably don’t want to run docker from Windows in a production scenario anyway, which are where the files you’d really want to back up would be.

Even though macOS’s filesystem is also case-insensitve, you might experience better luck having the mysql data files written to a folder on a macOS host system.

A command like the following, replacing single-quotes with double-quotes on Windows, will show you the folder on the host and the guest OS that pertain to the volume.

docker inspect --format='{{range .Mounts}}docker container path: {{.Source}} Container path: {{.Destination}}{{end}}' database-container-name

Typically with the VOLUME directive in a Dockerfile, it will create a place on the host VM for the volume that is mapped to a location in the container. However, you can also use Kitematic to change the location to somewhere actually on the host rather than in the MobyLinuxVM  or Hyperkit environment.

If, however, you see paths mentioned in docker inspect that are clearly not on the host filesystem, they are probably in the VM made to run Docker. On Windows, you can use this bizarre workaround to access the MobyLinuxVM filesystem.

To access the Hyperkit VM on macOS requires a series of, frankly, even more ridiculous steps. Hold your breath because it will be a bumpy ride:

First of all, there’s no way I would have figured this all out myself. I thank this StackOverflow question for guidance. Basically, you can initiate a TTY session with the Hyperkit VM by way of the screen command by issuing the following instruction:

screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

After issuing the command, you will see a blank screen. Press enter to see the command prompt for the VM. You should be able to use regular GNU commands to look about the filesystem. You will typically find the volume folders in /var/lib/docker/volumes.

Rather than typing that whole tty path out, if you run ls -l on it, you might see, such as in my case, how it is symlinked to a much shorter path, like /dev/ttys001. The screen command can be tricky to work with, but the man pages should help you understand how to go between the TTY session and your regular command-line.

What is my IP?

You might want to know the IP address with which the guest OS in the container can reach the host. For Windows, the host IP the container can use should be the same IPv4 address set for the vEthernet (DockerNAT) network adapter that was automatically created. This address should be the first node on the Internal Virtual Switch Subnet Address shown in the Network tab of the Docker for Windows Settings.

On Docker for Mac, it’s a little easier. There will be a docker.for.mac.localhost hostname available from your container that maps to the IP for the host machine. This IP should also be the first node on the Docker subnet set in the Advanced tab of the Docker for Mac Preferences.