[docker] What is the point of WORKDIR on Dockerfile?

I'm learning Docker. For many times I've seen that Dockerfile has WORKDIR command:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 3000
CMD [ “npm”, “start” ] 

Can't I just omit WORKDIR and Copy and just have my Dockerfile at the root of my project? What are the downsides of using this approach?

This question is related to docker dockerfile

The answer is


Be careful where you set WORKDIR because it can affect the continuous integration flow. For example, setting it to /home/circleci/project will cause error something like .ssh or whatever is the remote circleci is doing at setup time.


You can think of WORKDIR like a cd inside the container (it affects commands that come later in the Dockerfile, like the RUN command). If you removed WORKDIR in your example above, RUN npm install wouldn't work because you would not be in the /usr/src/app directory inside your container.

I don't see how this would be related to where you put your Dockerfile (since your Dockerfile location on the host machine has nothing to do with the pwd inside the container). You can put the Dockerfile wherever you'd like in your project. However, the first argument to COPY is a relative path, so if you move your Dockerfile you may need to update those COPY commands.


You dont have to

RUN mkdir -p /usr/src/app

This will be created automatically when you specifiy your WORKDIR

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

Beware of using vars as the target directory name for WORKDIR - doing that appears to result in a "cannot normalize nothing" fatal error. IMO, it's also worth pointing out that WORKDIR behaves in the same way as mkdir -p <path> i.e. all elements of the path are created if they don't exist already.

UPDATE: I encountered the variable related problem (mentioned above) whilst running a multi-stage build - it now appears that using a variable is fine - if it (the variable) is "in scope" e.g. in the following, the 2nd WORKDIR reference fails ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
WORKDIR $varname

whereas, it succeeds in this ...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
ENV varname varval
WORKDIR $varname

.oO(Maybe it's in the docs & I've missed it)


Before applying WORKDIR. Here the WORKDIR is at the wrong place and is not used wisely.

FROM microsoft/aspnetcore:2
COPY --from=build-env /publish /publish
WORKDIR /publish
ENTRYPOINT ["dotnet", "/publish/api.dll"]

We corrected the above code to put WORKDIR at the right location and optimised the following statements by removing /Publish

FROM microsoft/aspnetcore:2
WORKDIR /publish
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "api.dll"]

So it acts like a cd and sets the tone for the upcoming statements.


Examples related to docker

standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker What is the point of WORKDIR on Dockerfile? E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation How do I add a user when I'm using Alpine as a base image? docker: Error response from daemon: Get https://registry-1.docker.io/v2/: Service Unavailable. IN DOCKER , MAC How to fix docker: Got permission denied issue pull access denied repository does not exist or may require docker login Docker error: invalid reference format: repository name must be lowercase Docker: "no matching manifest for windows/amd64 in the manifest list entries" OCI runtime exec failed: exec failed: (...) executable file not found in $PATH": unknown

Examples related to dockerfile

standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker What is the point of WORKDIR on Dockerfile? Can't create a docker image for COPY failed: stat /var/lib/docker/tmp/docker-builder error /bin/sh: apt-get: not found COPY with docker but with exclusion Dockerfile if else condition with external arguments Docker build gives "unable to prepare context: context must be a directory: /Users/tempUser/git/docker/Dockerfile" denied: requested access to the resource is denied : docker Understanding "VOLUME" instruction in DockerFile ARG or ENV, which one to use in this case?