difference between RUN cd and WORKDIR in Dockerfile - bash

In terms of the way Docker works, is there any difference between RUN cd / and WORKDIR / inside a Dockerfile?

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). The ENV and WORKDIR directives before it affect how it starts up. If you have a RUN step that just changes directories, that will get lost when the shell exits, and the next step will start in the most recent WORKDIR of the image.
FROM busybox
WORKDIR /tmp
RUN pwd # /tmp
RUN cd / # no effect, resets after end of RUN line
RUN pwd # still /tmp
WORKDIR /
RUN pwd # /
RUN cd /tmp && pwd # /tmp
RUN pwd # /
(For the same reason, RUN export doesn't do anything that outlives the current Dockerfile instructions, and RUN . or the non-standard RUN source won't cause environment variables to be set.)

Related

Attempting to use a volume in my docker container (windows) and when I run docker run it does not appear to work

A simple bash script whereby a user can search through a folder and organise their files by type. For this I need to give my container access to my C drive and navigate to the right directory where the code is executed and where the folders are.
Since it s windows I know I need to use winpty and use \ rather than / when navigating.
winpty docker run -it -v basic-vol:/C:\Users\XYZ\dev\repos\filefind filefind:latest
I am not sure why this is not working. Here is my Dockerfile too:
FROM ubuntu
RUN chmod 700 .
WORKDIR /app
COPY . .
VOLUME [ "/c/Users/XYZ/dev/repos/"]
#when conatiner starts what is the executable
ENTRYPOINT ["/bin/bash", "file-find.sh"]
Would love your help here folks

How to run bash file in Dockerfile?

Im trying to execute bash file called start.bash by CMD["bash" ,"start.bash"] in Dockerfile. When I create the image this command is not executed for some reason even though the bash file was of course copied properly in the dockerfile.
The point is that while im trying to run this command inside the container itself its success.
Here is my Dockerfile:
# build back end
FROM node:12.22.12 AS server_build
###ENV HOSTNAME myhost
WORKDIR /VideoServiceApp
COPY ./projConf.json /VideoServiceApp
COPY ./projVideoApp.json /VideoServiceApp
COPY ./front/UIVideo ./front/UIVideo
COPY ./front/videoService ./front/videoService
COPY --from=client_build /VideoServiceApp/front/video/dist/video /VideoServiceApp/front/video/dist/video
COPY ./start.bash /VideoServiceApp
COPY ./classes ./classes
WORKDIR /VideoServiceApp/front/UIVideo
RUN npm install
WORKDIR /VideoServiceApp/front/videoService
RUN npm install && npm install -g typescript#latest
RUN tsc
EXPOSE 7717 7708
WORKDIR /VideoServiceApp
CMD ["bash" , "start.bash"]
You need to specify the full path for the command when you are using the CMD array's syntax.
CMD ["/bin/bash", "start.bash"]
You could also switch to the shell form of CMD
CMD bash start.bash
For more information read the CMD-Documentation

Does WORKDIR create a directory?

These are the first 2 lines of a Dockerfile:
FROM node:12
WORKDIR /code
Here are some things I don't understand:
From docker's documentation I know that the 2nd line sets the working directory to /code.
Where does this process occur?
Does it happen when docker runs the second line of the Dockerfile, while creating the image?
If /code doesn't exist, does it get created by docker?
Where will /code be created? In the root directory of the image?
The Dockerfile WORKDIR directive
... sets the working directory.... If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
I occasionally see SO questions that RUN mkdir a directory before switching WORKDIR to it. Since WORKDIR will create the directory, this isn't necessary.
All paths in a Dockerfile are always inside the image, except for the source paths for COPY and ADD instructions, which are inside the build context directory on the host. Absolute paths like /code will be directly inside the root directory in the image, following normal Unix conventions.
You can run temporary containers off of your image to examine this, even if the Dockerfile isn't complete yet.
host$ docker build -t my-image .
host$ docker run --rm my-image ls -l /
host$ docker run --rm -it my-image /bin/sh
0123456789ab# ls -l /
0123456789ab# exit
(This will always work, assuming the image includes core tools like sh and ls. docker exec requires the container to be running first; while you're refining the Dockerfile this may not be possible yet.)
The Workdir /path will be created inside the container.
To test this you can do sh into your container.
Steps:
docker exec -it <container-id> sh
ls (Here you will see WORKDIR)
If you want to view the intermediate image layers from your custom image
docker image inspect < image-name >
The default WORKDIR driectory if this is not specified, is the / directory.
More info at the following link,
https://www.geeksforgeeks.org/docker-workdir-instruction/

Bash commands are ignored in my ENTRYPOINT Docker bash script

I have some few libraries that I have compiled on my machine. So I want to copy all the binaries into my docker container and at first, I tried to use COPY and ADD command in my Dockerfile:
# Installing zeromq
WORKDIR /${home}/${user}/master-wheel
COPY ${PWD}/libzmq ./libzmq
COPY ${PWD}/cppzmq ./cppzmq
WORKDIR /${home}/${user}/master-wheel/libzmq/binaries
ADD * /
WORKDIR /${home}/${user}/master-wheel/cppzmq/binaries
ADD * /
Note that the directories and files do exist and upon entering into my created container, I can see that the copied directories libzmq and cppzmq do exist and I can manually copy all the binaries to the root /. However, for some reason Dockerfile doesn't copy and I can't figure out what could be the problem.
Then, I have decided to do that inside my ENTRYPOINT script and it looks like this:
#!/bin/bash
#set -e
#set -u
echo "==> Executing master image entrypoint ..."
echo "-> Setting up"
cp -r /home/ed/master-wheel/libzmq/binaries/* /
cp -r /home/ed/master-wheel/cppzmq/binaries/* /
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
ldconfig
echo "==> Container ready"
exec "$#"
Everything except two cp commands executes. I tried the same command (cp command) from my container bash terminal and it worked.
What could be the problem?
EDIT:
This part of the file works and the binaries do really get copied to the root directory:
# Installing libfreespace
WORKDIR /${home}/${user}/master-wheel
COPY ${PWD}/libfreespace ./libfreespace
WORKDIR /${home}/${user}/master-wheel/libfreespace/binaries
COPY * /
EDIT 2:
It seems that if I do something like this:
WORKDIR /${home}/${user}/master-wheel
COPY ${PWD}/libzmq ./libzmq
COPY ${PWD}/cppzmq ./cppzmq
WORKDIR /${home}/${user}/master-wheel/libzmq/binaries/usr/
ADD * /usr/
WORKDIR /${home}/${user}/master-wheel/cppzmq/binaries/usr/
ADD * /usr/
It works.

Dockerfile: code 127 when trying to RUN shell-script

Running Docker Toolbox on Windows 10 host.
There is a Dockerfile:
FROM 16.04
...
RUN if [ some_condition ]; then ./foo.sh; fi
...
There is a foo.sh:
#!/bin/bash
...
echo 'Me working'
Now when trying to build the Docker image:
docker build -t name_of_the_image .
Getting error:
Step 7/12 : RUN ./foo.sh
---> Running in e7e0703d3f8f
/bin/sh: 1: ./foo.sh: not found
The command '/bin/sh -c ./foo.sh' returned a non-zero code: 127
I would assume error 127 would be the Docker doesn't see the bash. Any suggestion how to fix this?
Edit: already copying all files into the Docker, Dockerfile:
FROM ubuntu:16.04
MAINTAINER Mr Anderson "mr#anderson.com"
# set workdir
COPY . /app
WORKDIR /app
# Run scripts
RUN ./foo.sh
You'll need to copy/COPY the file into the container before you can execute/RUN the script.
Also since you're using a relative path when you call the script be sure to set a WORKDIR.
COPY ./foo.sh /app/foo.sh
WORKDIR /dir
RUN chmod +x /app/foo.sh
RUN if [ some_condition ]; then ./foo.sh; fi
Also make sure the script is executable.
After some further investigation:
Using CMD over RUN is not a perfect solution because of the way those commands work. RUN can be used any amount of times, to build Docker image layer by layer, while CMD can be executed only once when the image has been build.
In my case the solution was to:
Open ./foo.sh file with VIM and run: :set fileformat=unix and save the file.
Long story short: the line ending in the shell-script were incorrect and had to be converted to the Unix ones.

Resources