Dockerfile COPY creates undesired subdirectory in image - docker

I want to create a Docker container and I wrote image. Everything works great except the COPY command where I got confused. My Dockerfile:
RUN HOME=/home/ros rosdep update
RUN mkdir -p /home/ros/workspace
# Copy the files
COPY $PWD/src/a_file /home/ros/workspace/src
COPY $PWD/src/b_file /home/ros/workspace/src
a_file is a directory like a b_file. When I try to copy these directories into a newly created directory called /home/ros/workspace/src I want a_file and b_file to be both inside /home/ros/workspace/src. Instead of this, I get another src directory /home/ros/workspace/src/src) and the contents of a_file and b_file are inside that directory.
What am I doing wrong?

As mentioned in other answers, $PWDrefers to the image context.
Try to use . instead.
To setup your working directory, use WORKDIR
Also, both a_file and b_file are in src/
All in all, this should work (not tested):
FROM <your-base-image>
WORKDIR /home/ros
RUN rosdep update
RUN mkdir -p workspace
# Copy the files
COPY ./src workspace/src

In your Dockerfile, PWD variable refers to image context (i.e: inside the image).
From COPY documentation:
paths of files and directories will be interpreted as relative to the source of the context of the build.
If src directories are in the root of your build context, your example it will be:
...
COPY src/a_file /home/ros/workspace/src
COPY src/b_file /home/ros/workspace/src
...

Related

docker multi-stage - why copy part of a folder resulting in bigger image than copy the entire folder?

I want to create the smallest image possible for my project, so I am using multi-stage docker with distroless. I copy only the files that needed for runtime. From several folders I copy only the .so files instead of copy all the folder and I can see that the created image get smaller.
But there is one folder that when I copy the entire folder I get smaller image significally than copy only the .so files.
With the following Dockerfile I copy the entire /usr/lib/x86_64-linux-gnu folder:
#stage 1
FROM some_image AS builder
ADD something /home/
RUN mkdir ...
cmake ...
#stage 2
FROM gcr.io/distroless/cc-debian10
COPY --from=builder /home/some/folders
COPY --from=builder /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
WORKDIR /home/
CMD ["/bin/bash"]
And the image size is 618MB.
But with the following Dockerfile I copy only the *.so files from /usr/lib/x86_64-linux-gnu folder:
#stage 1
FROM some_image AS builder
ADD something /home/
RUN mkdir ...
cmake ...
#stage 2
FROM gcr.io/distroless/cc-debian10
COPY --from=builder /home/some/folders
COPY --from=builder /usr/lib/x86_64-linux-gnu/*.so /usr/lib/x86_64-linux-gnu/*.so.* /usr/lib/x86_64-linux-gnu/
WORKDIR /home/
CMD ["/bin/bash"]
And surprisingly the image size is now 683MB. Which is 65MB bigger.
Any idea what can cause such results?
After long investigation I found that:
Copy of entire folder with symlinks preserves symlinks
Copy symlinks directly creates regular files
So in my case, copy of all *.so files cause each symlink to be copied as a regular file that this symlink is pointing on. This transition cause the increasing of my image size.
After I understand that, I google it and found a reference here

Where should I place my bash setup files when using docker?

My Dockerfile is below.
Currently I copy the dotfiles (which are referenced within the .bashrc) to /root
Is there a better way to organize them?
FROM alpine:latest
LABEL maintainer="Michael Durrant<junk#snap2web.com>"
RUN apk add bash git vim
COPY alpine_bashrc /root/.bashrc
COPY .bash_functions.sh /root
COPY .bash_aliases /root
COPY .git-completion.bash /root
RUN "/bin/bash"
Instead of having 1 COPY directive for each file, it might be advisable to have a directory instead. The limitation would be that the files must be named as they would appear in the container.
$ ls .
Dockerfile
dotfiles/
.bashrc
.git-completion.bash
.bash_functions.sh
.bash_aliases.sh
Dockerfile
...
COPY dotfiles/ root/
Each of those COPY directives creates a new layer in your container. Save space/time by having one directive.

Dockerfile - Unable to copy all files from one folder to another within container

I have the following in my Dockerfile - I'm trying to copy all the contents of the source folder (a folder of JARs) to the destination but it simply doesn't work.
Any ideas?
RUN cp -R /tmp/usr/kafka-connect/. /etc/kafka-connect/jars/
I've also tried
RUN cp -R /tmp/usr/kafka-connect/ /etc/kafka-connect/jars/
and
RUN cp -a /tmp/usr/kafka-connect/. /etc/kafka-connect/jars/
with no luck.
What am I doing wrong?
Thanks.
You need to use COPY instead of RUN.
COPY /tmp/usr/kafka-connect /etc/kafka-connect/jars
You can also use the WORKDIR instruction and then the destination path can be relative to WORKDIR.
The source path can be relative to the build context.

Adding source code to docker image using dockerfile

I have a source code and I want to add it into docker image using Dockerfile. I use COPY command, but I don't know what I should put in destination place. Can you tell me if destination is a specific directory or it is optional?
The destination directory can be a directory of your choice.
...
RUN mkdir -p /usr/src/app
COPY ./src /usr/src/app
...
The above commands in a Dockerfile would create /usr/src/app in the containers filesystem and the COPY would copy the contents of the src directory on the host to /usr/src/app in the containers filesystem.
You can use any destination path , but make sure that path exist for example
COPY source_code / opt/folder_name
Then optionally you can make this in docker as working directory
WORKDIR /opt/folder_name
in Dockerfile:
COPY ./src /dst
Where src is a folder in the same path of Dockerfile on the host (the computer on which Docker is directly running). dst is a folder on the container itself.
Here is an example:
Create a Dockerfile for an ASP.NET Core application
# Copy everything
COPY . /FolderInTheContainer/
this will copy everything in the same path of Dockerfile, to a destination folder in the container.
Here is dockerfile copy documentation:
https://docs.docker.com/engine/reference/builder/#copy

Copy specific file first and the copy all in Dockerfile

The following is what I have for my Dockerfile:
FROM node:4.6.0
WORKDIR /src
COPY node_modules/ /src/node_modules
COPY . /src/
CMD ["/bin/bash"]
I wanted to make it efficient such that node modules are copied only when there's any change in the directory. Otherwise, I want only the source files are copied into the image.
Would this work as intended?
This will copy twice. Docker cache looks at the current command and previous layer. If something has changed in the Docker context for the current command it will run. It does not use a partial cache to run.

Resources