dockerfile - Change directory command in Docker?

ID : 10085

viewed : 38

Tags : dockerdockerfilecddocker

Top 5 Answer for dockerfile - Change directory command in Docker?

vote vote

97

To change into another directory use WORKDIR. All the RUN, CMD and ENTRYPOINT commands after WORKDIR will be executed from that directory.

RUN git clone XYZ  WORKDIR "/XYZ" RUN make 
vote vote

88

You can run a script, or a more complex parameter to the RUN. Here is an example from a Dockerfile I've downloaded to look at previously:

RUN cd /opt && unzip treeio.zip && mv treeio-master treeio && \     rm -f treeio.zip && cd treeio && pip install -r requirements.pip 

Because of the use of '&&', it will only get to the final 'pip install' command if all the previous commands have succeeded.

In fact, since every RUN creates a new commit & (currently) an AUFS layer, if you have too many commands in the Dockerfile, you will use up the limits, so merging the RUNs (when the file is stable) can be a very useful thing to do.

vote vote

76

I was wondering if two times WORKDIR will work or not, but it worked :)

FROM ubuntu:18.04  RUN apt-get update && \     apt-get install -y python3.6  WORKDIR /usr/src  COPY ./ ./  WORKDIR /usr/src/src  CMD ["python3", "app.py"] 
vote vote

66

Mind that if you must run in bash shell, you need not just the RUN make, but you need to call the bash shell before, since in Docker, you are in the sh shell by default.

Taken from /bin/sh: 1: gvm: not found, which would say more or less:

Your shell is /bin/sh, but source expects /bin/bash, perhaps because it puts its initialization in ~/.bashrc.

In other words, this problem can occur in any setting where the "sh" shell is used instead of the "bash", causing "/bin/sh: 1: MY_COMMAND: not found".

In the Dockerfile case, use the recommended

RUN /bin/bash -c 'source /opt/ros/melodic/setup.bash' 

or with the "[]" (which I would rather not use):

RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"] 

Every new RUN of a bash is isolated, "starting at 0". For example, mind that setting WORKDIR /MY_PROJECT before the bash commands in the Dockerfile does not affect the bash commands since the starting folder would have to be set in the ".bashrc" again. It needs cd /MY_PROJECT even if you have set WORKDIR.

Side-note: do not forget the first "/" before "opt/../...". Else, it will throw the error:

/bin/bash: opt/ros/melodic/setup.bash: No such file or directory 

Works:

 => [stage-2 18/21] RUN ["/bin/bash", "-c", "source /opt/ros/melodic/setup.bash"]                                  0.5s  => [stage-2 19/21] [...] 

See ā€œ/bin/sh: 1: MY_COMMAND: not foundā€ at SuperUser for some more details on how this looks with many lines, or how you would fill the ".bashrc" instead. But that goes a bit beyond the actual question here.

PS: You might also put the commands you want to execute in a single bash script and run that bash script in the Dockerfile (though I would rather put the bash commands in the Dockerfile as well, just my opinion):

#!/bin/bash set -e  source /opt/ros/melodic/setup.bash 
vote vote

51

You can use single RUN command for all of them

RUN git clone XYZ && \     cd XYZ && \     make XYZ 

Top 3 video Explaining dockerfile - Change directory command in Docker?

Related QUESTION?