I just got back from a conference trip to Europe, DockerCon in Copenhagen, All-Systems-Go in Berlin, and then Open Source Summit in Prague.

While I was there, I needed to continue doing the development of some major refactoring of RancherOS for my LinuxKit talk – which meant I needed to be able to “docker pull” from both builds and temporary testing VM’s, from horrible hotel Wifi, and from overloaded conference Wifi – not great.

Because the bandwidth from Australia isn’t wonderful, I had already modified the builds and test tooling to use a local Docker registry mirror – so all I really needed to do was setup the same caching infrastructure I have on my home office network, but on a roaming notebook… and yup, its pretty straightforward:

The docker daemon will automatically use the local registry, and the local registry mirror on the “localhost” port 5000&5555 – and so long as you can give your VM’s a valid IP to your host, that too will work..

I have the following in my .bashrc, and these environment vars are used by the build and test tooling to pass on to the VM’s (ok, so this works because I have VMWare workstation on my Linux box):

Today’s task ended up being to update my Resume. Well, it turns out it was time to create a new one – so I turned to JSON Resume CLI – which converts the machine readable info I maintain into something that doesn’t look like the word document I’ve been carrying around since I graduated in 1995.

Happily, node.js works well using alpine, so my Dockerfile (see the GH repo for more) looks like:

-h, --help output usage information
-V, --version output the version number
-t, --theme Specify theme for export or publish (modern, traditional, crisp)
-F, --force Used by publish - bypasses schema testing.
-f, --format Used by export.
-r, --resume Used by serve (default: resume.json)
-p, --port Used by serve (default: 4000)
-s, --silent Used by serve to tell it if open browser auto or not.
-d, --dir Used by serve to indicate a public directory path.

I guess I can pop back up my todo stack to the Android Studio container I started yesterday 🙂

I’m available for short term Docker consultations and training courses. I’m in Brisbane – but I’m happy to talk to you about flying out to where you are.

After two and a half years, my contract with Docker Inc has finished.

Its been a blast – I’ve never worked in a startup before, and I was hired early enough to have a very broad scope of work – including supporting users, working as a maintainer and oss contributor, and leading the development of Boot2Docker (now replaced by Docker for Mac and Windows) – a micro Linux distribution with OSX and Windows installers to allow users on those platforms to use Docker.

Its been amazing seeing the inside of an incredibly dynamic, game-changing project that has succeeded in growing for the three years that its been around – TWiki was successful around the 2000, but never managed to convert in the way that Docker has.

I’ve spent the last week cleaning up my email, git repositories and getting started on the non-computer projects that have been languishing for the last 3 years – and started playing with the ESP8266 I have – Like I said to Nathan the other day, having a relaxing time writing C++ 🙂

Until I find the next big project, startup, or workplace?:

I’m available for short term Docker consultations and training courses. I’m in Brisbane – but I’m happy to talk to you about flying out to where you are.

The point is, without using alot of time, diskspace, or effort, I created a debian environment, created the environment I needed, and then could run my test as the user I needed.

If this was more than a once-off, I’d do the setup in a Dockerfile, and make the command I’m testing be that Dockerfile’s ENTRYPOINT – making it possible to run a suite of tests using docker build -t test . && docker --rm run test

VMWare helpfully provides a Virtual Network editor, so I can see that “Get-NetAdapter -Name “VMware Network Adapter VMnet8” is the NAT one. I’m not sure if creating a Hyper-V External vswitch will make exclusive use of the adaptor, but if so, we can always create another 🙂

FAIL. the docker containers still have no network. At this point, I’m not sure if I’ve totally broken my Windows Docker networking, hopefully some more playing later will turn up something.

Playing some more, there seems to be a new switchtype Nat – see https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/windows-server-container-tools/Install-ContainerHost/Install-ContainerHost.ps1

So re-running the command they use when installing gets us something new to try:

Its well worth continuing this exercise using things like dpkg —get-selections to remove anything else you won’t need.

Importantly, once you’ve made your smaller base image, you should use it consistently for ALL the containers you use. This means that whenever there are important security fixes, that base image will be downloadable as quickly as possible – and all your related images can be restarted quickly.

This also means that you do NOT want to squish your images to one or two layers, but rather into some logical set of layers that match your deployment update risks – a common root base, and then layers based on common infrastructure, and lastly application and customisation layers.

2. Build static binaries – or not

Building a static binary of your application (in typical Go style) makes some things simpler – but in the end, I’m not really convinced it makes a useful difference.

But in my talk, I did it anyway.

Make a Dockerfile that installs all the tools needed, builds nginx, and then output’s a tar file that is a new build context for another Docker image (and contains the libraries ldd tells us we need):

Its interesting to remember that we rely heavily on I know this, its a UNIX system – application services can have all sorts of hidden assumptions that won’t be revealed without putting them into more constrained environments.

In the same way that we don’t ship the VM / filesystem of our build server, you should not be shipping the container you’re building from source.

This analysis doesn’t try to restrict nginx to only opening certain network ports, devices, or IPC mechanisms – so there’s more to be done…

One of the talks I gave at Linux.conf.au this year was a quick-start guide to using Docker.

One of the talks I gave at Linux.conf.au this year was a quick-start guide to using Docker.

The slides begin with building Apache from source on your local host, using their documentation, and then how much simpler it is if instead of documentation, the project provides a Dockerfile. I quickly gloss over making a slim production container from that large development container – see my other talk, which I’ll blog about a little later.

The second example, is using a Dockerfile to create and execute a test environment, so everyone can replicate identical test results.

Finally, I end with a quite example of fig (Docker Compose), and running GUI applications in containers.

The official Docker language images can auto build and run your trial application a cinch. See how with golang:onbuild

We received a Pull Request to add Swagger support to document the Docker API, and @proppy asked if we could make sure we could load the schema in a standard json schema loader, for example gojsonschema

As I need to do some work on API testing when I come back from holidays, I thought I’d look at the Net:Docker CPAN module – and of course, there is no Perl on my Boot2Docker image, so its a perfect opportunity to see what I should do.

After forking and cloning the Git repository, I created the following initial Dockerfile:

RUN cpanm --installdeps .
RUN perl Build.PL
RUN ./Build build
RUN ./Build test

It fails to build during the ‘test’ step:

$ docker build -t docker-perl .

... snip ...

Step 6 : RUN ./Build test
---> Running in 367afe04c77e
Can't open socket var/run/docker.sock: No such file or directory at /usr/local/lib/perl5/site_perl/5.20.0/LWP/Protocol/http/SocketUnixAlt.pm line 27. at t/docker-api.t line 9.

Tests were run but no plan was declared and done_testing() was not seen.

I’m going to have to give this Dockerfile a DOCKER_HOST (incorrectly using http://) setting (to one of my insecure plain text tcp based servers :), and add IO::String and JSON:XS to the cpanfile.

Unfortunately, because cpanm --installdeps . uses the files in the build context, this way does not use the build cache – so its slow. Its worth duplicating the contents of the cpanfile before the COPY instruction for speed.

You can also run the container with bash – docker run --rm -it docker-perl bash so you can do some more testing, or try out more complex examples.

In this case, the ./Build test step probably needs to happen in the docker run phase, as it needs access to a working Docker daemon – this issue will be true for modules that talk to external resources.

I’ve made a pull request for the tiny changes to get me this far. Perhaps Dockerfiles like this could be a gateway into the world of contributing quick fixes for open source libraries.