vrijdag 3 maart 2017

Fixing dockerfile issues running macOS

I have become a great fan of Docker as an easy way to test software and to run various development enviroments on the Mac. However, not all docker images that are available through dockerhub / Kitematic work out of the box on the Mac. The issues I've come across are generally linked to one or two causes:

  1. Images need to explicitly expose a port when running on the Mac.
  2. Exposed volumes don't always work as expected.
For both issues I've found a solution.

Exposing ports

As stated, dockerfiles on macOS need to explicitly expose the ports they listen to. So the original Dockerfile MUST have a statement like

EXPOSE 30000
If it doesn't, you can fix this by creating you own Dockerfile and building you own image. In this example we'll do this to fix the ascdc/iiif-manifest-editor Dockerfile. First, create a folder to store the new Dockerfile. Now create a Dockerfile with simply this content:
FROM ascdc/iiif-manifest-editor
That is all! Now just use this to build your image:
docker build -t myimage .
Run this container:
docker run -d -p 3000:3000 --name mycontainer myimage
The container will now be available at http://localhost:3000 with your browser on macOS.

Fixing volume-related issues

Directories inside a docker container can be exposed on macOS through the VOLUME directive in the Dockerfile. Unfortunately, data in this volume can't always be accessed properly in Docker. For example tenforce/virtuoso exposes a volume that is actually a symbolic link to an other folder. Docker on macOS doesn't properly deal with that. My solution was to create my own Dockerfile (as explained above) that exposes not the symlinked directory but the original directory the symlink points to. For virtuoso I also had to explicitly expose the ports so it ended up like:

FROM tenforce/virtuoso
VOLUME /var/lib/virtuoso/db
WORKDIR /var/lib/virtuoso/db
Given this incompatibility between the filesytems used by Docker and macOS you will probably run into problems when for example you try to have a MySQL container store it datafiles on the macOS side. Preferably just keep them inside the container.