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.
Related
I have a Dockerfile and I want to add/copy a file.txt from my Desktop. How can I do?
This is my docker file:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build-env
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim
WORKDIR /app
COPY --from=build-env /app/out ./
# COPY ...
RUN useradd -ms /bin/bash moduleuser
USER moduleuser
ENTRYPOINT ["dotnet", "csharpexamplemodule.dll"]```
Short answer: You don't (see Adding files from outside context).
As far as copying (COPY / ADD) goes the file you want to copy to the container needs to be in the same context. Context in this case is the directory of your dockerfile or one of it's subdirectories. Assuming your dockerfile is not on the desktop as well, you are left with 2 options.
Copy the file from your desktop to the context that docker gets, as mentioned above
If you don't need the file during the build stage but still within your container, you can use docker mount (docker mount docs).
if you check the docker documentation of the copy command, you should see the following:
https://docs.docker.com/engine/reference/builder/#copy
COPY obeys the following rules:
The <src> path must be inside the context of the build;
you cannot COPY ../something /something, because the first
step of a docker build is to send the context directory
(and subdirectories) to the docker daemon.
So I would suggest you copy the file from your desktop to your docker context (where you run the docker command from). Or to create a symbolic link.
PS: It is a good practice to avoid using ADD if you don't need the tar and remote URL handling.
This question is asked before yet After reviewing the answers I am still not able to copy the solution.
I am still new to docker and after watching tutorials and following articles I was able to create a Dockerfile for an existing GitHub repository.
I started by using the nearest available image as a base then adding what I need.
from what I read the problem is in WORKDIR and CMD commands
This is error message:
python: can't open file 'save_model.py': [Errno 2] No such file or directory*
This is my Dockerfile:
# syntax=docker/dockerfile:1
FROM tensorflow/serving:2.3.0-rc0-devel-gpu
WORKDIR app
COPY requirements-gpu.txt .
# install dependencies
RUN pip install -r requirements-gpu.txt
# copy the content of the local src directory to the working directory
COPY /home/pc/Desktop/yolo4_deep .
# command to run on container start
CMD ["python","./app/save_model.py","./app/object_tracker.py" ]
src
save_model.py
object_tracker.py
...
requirements.txt
Dockerfile
I tried WORKDIR command to set the absolute path: WORKDIR /home/pc/Desktop/yolo4_Deep_sort_nojupitor the result was Same Error.
I see multiple issues in your Dockerfile.
COPY /home/pc/Desktop/yolo4_deep .
The COPY command copies files from your local machine to the container. The path on your local machine must be path relative to your build context. The build context is the path you pass in when you run docker build . — in this case the . (the current directory) is the build context. Also the local machine path can only reference files located under the build context — i.e. paths containing .. (parent directory) or / (root directory) are not allowed.
WORKDIR app
WORKDIR sets the path inside the container not on your local machine. So WORKDIR /app means that all commands — RUN, CMD, ENTRYPOINT — will be executed from the /app directory.
CMD ["python","./app/save_model.py","./app/object_tracker.py" ]
As mentioned above WORKDIR /app causes all operations to be executed from the /app directory. So ./app/save_model.py is actually translated as /app/app/save_model.py.
Thanks for help Everyone.
As I mentioned earlier I'm beginner in the docker world. I solved the issue by editing the copy command.
# syntax=docker/dockerfile:1
FROM tensorflow/serving:2.3.0-rc0-devel-gpu
WORKDIR /home/pc/Desktop/yolo4_deep
COPY requirements-gpu.txt .
# install dependencies
RUN pip install -r requirements-gpu.txt
# copy the content of the local src directory to the working directory
COPY src/ .
# command to run on container start
ENTRYPOINT ["./start.sh"]
I'm trying to put a dockerfile in a subdirectory of my main startup project AppMain. AppMain has a dependency project called AppDependency. When the dockerfile is in the root directory of AppMain, all works correctly, but when it's nested in a subdirectory of the AppMain, it fails with
4>Step 5/20 : COPY ["AppMain/AppMain.csproj", "AppMain/"]
4>COPY failed: stat /var/lib/docker/tmp/docker-builder453314675/AppMain/AppMain.csproj: no such file or directory
So that makes sense to me since it's nested in a subdirectory, so I simply added a "../" in front of the COPY commands but that results in the following context exception:
4>COPY failed: Forbidden path outside the build context: ../AppMain/AppMain.csproj ()
Alright so that makes sense as well because the docker documentation states that the context starts where the dockerfile is located, but this leads me to ask the real question.
If it cannot copy outside of the where the dockerfile is located and it works when its located in the root of AppMain, then why doesn't it fail when copying the AppReference project which obviously is above where the docker file is located and outside the context since it would have to go up one directory and then down to the AppReference project?
Is there a way to achieve having a dockerfile nested in a subdirectory?
The entire docker file is listed below.
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["AppMain/AppMain.csproj", "AppMain/"]
COPY ["AppReference/AppReference.csproj", "AppReference/"]
RUN dotnet restore "AppMain/AppMain.csproj"
COPY . .
WORKDIR "/src/AppMain"
RUN dotnet build "AppMain.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "AppMain.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "AppMain.dll"]
When use docker build -t xxx . to build in the subdirectory, only the contents in . will submit to docker daemon for docker build. The things in parent folder will not be able to submit to docker engine to build.
So, you need to move the execution directory back to the parent folder with cd .., then use next to build, it will then send the . which now is the contents of parent folder to engine(But you need now specify dockerfile, like this)
docker build -t xxx -f ./YOUR_Subdirectory/Dockerfile .
It is really working.
What it is ?
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
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
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.