Adding source code to docker image using dockerfile - docker

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

Related

Docker-compose volumes sharing issue with /app folder

I'm trying to build a web application based on flask and vue.js, using docker containers.
I use volume sharing in docker-compose and I'm facing an issue with the container structure.
I'd like to share the application folder from the host with the /app container folder. To do so the docker-compose is set up as
volumes:
- type: bind
source: ./
target: /app
inspecting the container shows that the data from the host is placed inside the folder /app/app and not inside the folder /app as expected. The working directory is set up inside the docker container:
FROM continuumio/miniconda3:latest
WORKDIR /app
COPY dependency.yml .
RUN conda env create -f dependency.yml
COPY setup.py .
RUN pip install -e .
In an attempt to try to understand the relative/absolute path I tried to change the target volume to /data in the docker-compose file. In this case the application files are installed in the /app and the host files are copied in the /data folder, as expected.
The question is: why if I try to use the absolute /app folder in the container does the system use it as relative to the WORKDIR, and this happens only if the WORKDIR has the same name as the target folder?

What is "/app" working directory for a Dockerfile?

In the docker docs getting started tutorial part 2, it has one make a Dockerfile. It instructs to add the following lines:
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
What is /app, and why is this a necessary step?
There are two important directories when building a docker image:
the build context directory.
the WORKDIR directory.
Build context directory
It's the directory on the host machine where docker will get the files to build the image. It is passed to the docker build command as the last argument. (Instead of a PATH on the host machine it can be a URL). Simple example:
docker build -t myimage .
Here the current dir (.) is the build context dir. In this case, docker build will use Dockerfile located in that dir. All files from that dir will be visible to docker build.
The build context dir is not necessarily where the Dockerfile is located. Dockerfile location defaults to current dir and is otherwise indicated by the -f otpion. Example:
docker build -t myimage -f ./rest-adapter/docker/Dockerfile ./rest-adapter
Here build context dir is ./rest-adapter, a subdirectory of where you call docker build; the Dokerfile location is indicated by -f.
WORKDIR
It's a directory inside your container image that can be set with the WORKDIR instruction in the Dockerfile. It is optional (default is /, but base image might have set it), but considered a good practice. Subsequent instructions in the Dockerfile, such as RUN, CMD and ENTRYPOINT will operate in this dir. As for COPY and ADD, they use both...
COPY and ADD use both dirs
These two commands have <src> and <dest>.
<src> is relative to the build context directory.
<dest> is relative to the WORKDIR directory.
For example, if your Dockerfile contains...
WORKDIR /myapp
COPY . .
then the contents of your build context directory will be copied to the /myapp dir inside your docker image.
WORKDIR is a good practice because you can set a directory as the main directory, then you can work on it using COPY, ENTRYPOINT, CMD commands, because them will execute pointing to this PATH.
Docker documentation: https://docs.docker.com/engine/reference/builder/
The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
The WORKDIR instruction can be used multiple times in a Dockerfile. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction.
Dockerfile Example:
FROM node:alpine
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "start"]
A alpine node.js was created and the workdir is /app, then al files are copied them into /app
Finally npm run start command is running into /app folder inside the container.
You should exec the following command in the case you have sh or bash tty:
docker exec -it <container-id> sh
or
docker exec -it <container-id> bash
After that you can do ls command and you will can see the WORKDIR folder.
I hope it may help you
You need to declare a working directory and move your code into it, because your code has to live somewhere. Otherwise your code wouldn't be present and your app wouldn't run. Then when commands like RUN, CMD, ENTRYPOINT, COPY, and ADD are used, they are executed in the context of WORKDIR.
/app is an arbitrary choice of working directory. You could use anything you like (foo, bar, or baz), but app is nice since it's self-descriptive and commonly used.

Can not copy files properly to docker image

Hello i am trying to recreate inside a docker image my host folder that contains:
Publish (folder containing a .NET app )
dockerfile
conf.json
dockerfile
FROM microsoft/aspnetcore
WORKDIR /app
ADD . /app
ENTRYPOINT ["dotnet","/publish/Bench.dll"]
EXPOSE 8300
When i am trying to see what it created using docker exec -it <id> bash it just takes all the content of publish and throws it inside app without copying conf.json.
I have also tried with
COPY . /app,
COPY /publish /app+COPY conf.json /app to no avail.
Whatever i am trying it won't copy the folder as-is and it wont put the json file beside it.
What am i doing wrong?
So I tested this out. I had the publish folder dockerfile and conf.json in the same directory where I build the image from. That is the key. Here I am using nginx as my base image. The following is the command I used to build the nginx image
docker build -t test/nginx .
and the dockerfile is as below. So I create the app directory by using the RUN command. You will have to use the similar command in .net to create that directory if it doesn't exist. Also pay attention to the docker build logs. It will tell you things that are important. Also you could add an ls command in the dockerfile to list the files in the folder /app if you want to.
FROM nginx
RUN mkdir /app
WORKDIR /app
ADD . /app
After I create a container from the image I built, i can navigate to /app folder and view my
Dockerfile, config.json and publish folder in there. Hope this helps
Let me know if you have any questions

Dockerfile COPY creates undesired subdirectory in image

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
...

How to specify working directory for ENTRYPOINT in Dockerfile

The Docker image (Windows-based) includes an application directory at C:\App. Inside that directory reside several sub-folders and files, including a batch file called process.bat. The Dockerfile (used to build the image) ends like this:
ENTRYPOINT [ "C:\\App\\process.bat" ]
When I instantiate this image using the command: docker run company/app, the batch file runs, but it fails at the point where other files under C:\App are referenced. Essentially, the working directory is still C:\ from the Docker container's entry-point.
Is there a way to set the working directory within the Dockerfile? Couple of alternatives do exist:
Add -w C:\App to the docker run
In the batch file, I can add a line at the beginning cd /D C:\App
But is there a way to specify the working directory in the Dockerfile?
WORKDIR /App is a command you can use in your dockerfile to change the working directory.
If /App is a mounted volume then you should specify VOLUME /App before WORKDIR to use it with ENTRYPOINT, otherwise it does not be seen by ENTRYPOINT:
VOLUME ["/App"]
WORKDIR /App
ENTRYPOINT ["sh", "start.sh"]
Which start.sh is within /App directory.

Resources