Docker: What's the deal with `WORKDIR`?16 Aug 2018
There is little to no documentation about Docker’s
WORKDIR keyword. From Page 1 of my tutorial, I mention the following:
WORKDIRchanges the directory to
RUN cd HelloWorlddoes 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 .
$ 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
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
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.