Change directory command in Docker?

DockerDockerfileCd

Docker Problem Overview


In docker I want to do this:

git clone XYZ
cd XYZ
make XYZ

However because there is no cd command, I have to pass in the full path everytime (make XYZ /fullpath). Any good solutions for this?

Docker Solutions


Solution 1 - Docker

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

Solution 2 - Docker

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.

Solution 3 - Docker

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

Solution 4 - Docker

You can use single RUN command for all of them

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

Solution 5 - Docker

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRParadoxView Question on Stackoverflow
Solution 1 - DockerJavier CastellanosView Answer on Stackoverflow
Solution 2 - DockerAlister BulmanView Answer on Stackoverflow
Solution 3 - DockerMian Asbat AhmadView Answer on Stackoverflow
Solution 4 - Dockeraditya DameraView Answer on Stackoverflow
Solution 5 - Dockerquestionto42standswithUkraineView Answer on Stackoverflow