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
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.
Source: Stackoverflow.com