Docker: What's the deal with `WORKDIR`?

August 16, 2018

Back to Tips and Tricks Table of Contents

There is little to no documentation about Docker’s WORKDIR keyword. From Page 1 of my tutorial, I mention the following:

WORKDIR changes the directory to /HelloWorld/. RUN cd HelloWorld does not work, not only because I have tried it, but because at every RUN, you are adding a new layer, which happens at the / level of the image. More info here.

But there are precious little details available. The Docker Glossary? As of this writing, there’s nothing. As a result of my own experiences with WORKDIR, I have come to some conclusions. I would have preferred documentation.

These observations can be summarized as follows: WORKDIR is a RUN mkdir and cd all in one, if we were in bash-land. Observation 2: This freedom comes at a cost. You can write a lot of different things, and it will not fail during the build. However, it will probably fail after the build, or in a run, if you mess it up.

Observation 1: you can create directories with WORKDIR!

For instance, let the Dockerfile be the following:

FROM ubuntu:16.04

WORKDIR /MyNewDir/SecondLevel/

Then, we can build as usual:

$ docker build -t test0workdir .

and run:

$ docker run -it test0workdir bash

When I run, the bash shell shows that I am in the /MyNewDir/SecondLevel directory, and testing with pwd further confirms this:

root@f12c89445e1b:/MyNewDir/SecondLevel# pwd
/MyNewDir/SecondLevel

Conclusion: no need to use two lines

RUN mkdir /opencv/build
WORKDIR /opencv/build 

when one will do: WORKDIR /opencv/build. Real-life example is in Page 3 of the tutorial.

Observation 2: major care is needed with backslashes and paths because there’s no way for WORKDIR to fail unlike cd

Let a Dockerfile consist of the following:

FROM ubuntu:16.04

WORKDIR /MyNewDir
WORKDIR MyNewDir/SecondLevel/

You might be tired, in a rush, whatever. You might think the third line of text means /MyNewDir/SecondLevel/. Following the standard build/run routine, though, we get:

$ docker build -t test1workdir .
$ docker run -it test1workdir bash
root@6ae8acc37940:/MyNewDir/MyNewDir/SecondLevel# pwd
/MyNewDir/MyNewDir/SecondLevel

The actual WORKDIR = /MyNewDir/MyNewDir/SecondLevel. Since I don’t use Docker that often, I have adopted always using absolute paths that start with / as an easy way not to mess this up.

Back to Tips and Tricks Table of Contents

© Amy Tabb 2018 - 2020. All rights reserved. The contents of this site reflect my personal perspectives and not those of any other entity.