Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of WORKDIR on Dockerfile?

People also ask

What is the purpose of the ENV keyword in a Dockerfile?

env in your project, it's only used to put values into the docker-compose. yml file which is in the same folder. Those are used with Docker Compose and Docker Stack.

What is docker default Workdir?

The default is indeed / as stated elsewhere. It is worth mentioning, though, that you will almost never be running from an empty docker image ( FROM scratch ), so the WORKDIR is likely set by the base image you're using.

Is Workdir same as CD?

Show activity on this post. RUN cd / does absolutely nothing. WORKDIR / changes the working directory for future commands. Each RUN command runs in a new shell and a new environment (and technically a new container, though you won't usually notice this).

Can Dockerfile have multiple Workdir?

you can have multiple WORKDIR in same Dockerfile. If a relative path is provided, it will be relative to the previous WORKDIR instruction. If no WORKDIR is specified in the Dockerfile then the default path is / . The WORKDIR instruction can resolve environment variables previously set in Dockerfile using ENV.


According to the documentation:

The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.

Also, in the Docker best practices it recommends you to use it:

... you should use WORKDIR instead of proliferating instructions like RUN cd … && do-something, which are hard to read, troubleshoot, and maintain.

I would suggest to keep it.

I think you can refactor your Dockerfile to something like:

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

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” ] 

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.


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.


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)