How to access Docker build context path inside Dockerfile - docker

I have Dockerfile defined in a directory
C:\work\Personal\API\api-service
Dockerfile
FROM maven:3.6.1-jdk-8 AS BUILD_IMAGE
COPY api-service /usr/src/app/api-service
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean install
I am trying to run docker build C:\work\Personal\API\api-service from C:
This results in error saying
COPY failed: stat /var/lib/docker/tmp/docker-builder483308674/api-init-service: no such file or directory
In order from me to copy the source code from local machine to docker, i need to know the location of build context folder inside my Dockerfile.
Is there any way to access build context folder passed to docker build command inside a Dockerfile?
In my local machine i can run docker build command from same directory as Dockerfile is located. But from CI tool i will not know where the docker buildcommand will be executed. Hence if i know the docker build context path passed as argument, i can copy the source code into docker image based on the context path.

You don't need docker build context location known inside your dockerfile.
What you need to know is:
Location of you build context. (say C:\work\Personal\mycontext which contains files and folders that you need to copy inside docker container)
Location of dockerfile (say C:\work\Personal\API\api-service\Dockerfile)
Also you need to know relative file path structure of your context. Like
- C:\work\Personal\mycontext
|
- scripts
|
- start.sh
|
- create.py
|
- target
|
- maven
|
- abc.jar
In this case your dockerfile will contain appropriate commands like COPY scripts /scripts that copy these files assuming its running from the context folder C:\work\Personal\mycontext
Your docker build command will be
docker build -f C:\work\Personal\API\api-service\Dockerfile -t image:version1 C:\work\Personal\mycontext
Note: Here -f option specify location of dockerfile in this case its C:\work\Personal\API\api-service\Dockerfile and C:\work\Personal\mycontext specify location of docker build context.
Irrespective of location from where the docker build commands runs, it will work as long as you provide exact location of dockerfile and docker build context.
More info here.
Hope this helps.

Related

Docker and DockerFile build

I am a Docker Beginner and I have some trouble with Dockerfile build..and a lot of questions
Do I have to start command build in path /var/lib/docker/builder ?
How do I know that it does not build because my Dockerfile is not correct written?
Do I have to call my folder Dockerfile?
docker build -t dokcerfile/xdebugphp .
than i got
Error response from daemon: unexpected error reading Dockerfile: read lstat /var/lib/docker/builder/Dokcerfile: no such file or directory
with
Get-Content Dockerfile | docker build -
Error response from daemon: the Dockerfile (Dockerfile) cannot be empty
You can launch docker build from any directory. If you try to COPY a file into an image that doesn't exist in the directory you name, you will see an error message that references /var/lib/docker, but that's an artifact of the Docker build implementation. (In fact, you really shouldn't look inside or try to directly use the /var/lib/docker directory at all.)
The file containing the build instructions is conventionally named Dockerfile (on systems with case-sensitive filesystems, with a capital D and no extension). It's most often located at the root of your source repository. This shouldn't be a directory.
The docker build -t option assigns a tag (name) to the image that's built. It doesn't have to correspond to a file on disk. If you're using Docker Hub to store your images (or just want to emulate its naming) these have the form username/imagename:version; there is an extended format if you're using some other Docker image registry.
You can name the Dockerfile something else; if you do, you need the docker build -f option to reference that file. If it's in a subdirectory of the repository root, the important detail is that COPY statements copy from the "context" directory you pass as the directory argument to docker build; this could be different from the directory that contains the Dockerfile. For example, if your Dockerfile has COPY index.php ., and you run docker build -f docker/xdebugphp ., the file is copied from the . current directory, which is the parent directory of the Dockerfile.
Looks like line endings, try changing dockerfile line endings to LF
Also for Docker build command you need to be in the directory where the dockerfile is or specify the path to the dockerfile
so in the directory where dockerfile is command is
docker build -t IMAGENAMEHERE .
So I solved it with this command
docker build -t imagename -f Dockerfile/xdebugphp .

how to change docker source of the context of the build

Dockerfile is:
FROM nginx
COPY html /usr/share/nginx/html
Dockerfile is in pwd directory(which is home/ubuntu/app), when use following command:
docker build -t mynginx .
I was giving an error:
copy failed: stat /var/lib/docker/tmp/docker-builder344/html: no such file or directory.
how to change docker source of the context of the build?
Docker build only look files in Dockerfile file context, mean the build will copy /home/ubuntu/app/ from this location where your Dockerfile is.
So better to place your html the /home/ubuntu/app in this location as docker build send tar of the context to docker daemon so it is recommended to keep the context minimal.
docker build -t mynginx . would expect to find Dockerfile in the current directory. Moreover, relative paths used by Dockerfile instructions would be relative to the current directory.
You can set the build context path to a different path docker build -t mynginx [some_folder_path]. Docker would search for Dockerfile there. You can modify the path to Dockerfile using -f option docker build -f [path_to_dockerfile] -t mynginx [some_folder_path]

Why does Docker require PATH when building from custom Dockerfile in another directory?

When building docker images with a Dockerfile in the same directory, the following works every time
$ docker build -t project/app:latest .
Sending build context to Docker daemon 135.9MB
...
However, when using -f to specify a different Dockerfile to use, docker complains ...
$ docker build -t project/app:latest -f ../some/path/Dockerfile.other
"docker build" requires exactly 1 argument.
See 'docker build --help'.
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
I can easily provide the PATH, and the build will work, but why is the PATH still required if I'm specifying the absolute path to the Dockerfile with -f?
The PATH is for specifying the build context (the tree from which COPY instructions copy things), which need not have any relation to the location of the Dockerfile.
Quoting the docs:
The docker build command builds Docker images from a Dockerfile and a “context”. A build’s context is the set of files located in the specified PATH or URL. The build process can refer to any of the files in the context. For example, your build can use a COPY instruction to reference a file in the context.

docker copy issues and set host env variable

I am new to docker.
I would like to understand the following questions. I have been searching but I can't find the answers to my questions.
Why do I always get a wrong path when I tried to copy the file?
Does that mean I can only copy the files into the docker image from the same directory where I have my dockerfile? Is there a way to COPY files from other directories on the host?
Is there a way to passing in host's environment variables directly in the Dockerfile without using "ARG" and --build-arg flag?
Below is what I currently have
file structure is like this:
/home/user1/docker
|__ Dockerfile
In the Dockerfile:
From
ARG BLD_DIR=/tmp
RUN mkdir /workdir
WORKDIR /workdir
COPY ${BLD_DIR}/a.file /workdir
I ran
root#localhost> echo $BLD_DIR
/tmp/build <-- BLD_DIR is a custom variable; meaning it's different on each dev env
docker build --build-arg BLD_DIR=${BLD_DIR} -t docker-test:1.0 -f Dockerfile
Always got error like
COPY failed: stat
/var/lib/docker/tmp/docker-builder035089075/tmp/build/a.file: no such file
or directory
In a Dockerfile, you can only copy files that are available in the current Docker build context.
By default, all files in the directory where you run your docker build command are copied to the Docker context folder.
So, when you use ADD or COPY commands, all your paths are in fact relative to build folder, as the documentation states:
Multiple resources may be specified but the paths of files and directories will be interpreted as relative to the source of the context of the build.
This is voluntary because building an image using docker build should not depend on auxiliary files on your system: the same Docker image should not be different if built on 2 different machines.
However, you can have a directory structure like such:
/home/user1/
|___file1
|___docker/
|___|___ Dockerfile
If you run docker build -t test -f docker/Dockerfile . in the /home/user1 folder, your build context will be /home/user1, so you can COPY file1 in your Dockerfile.
For the very same reason, you cannot use environment variables directly in a Dockerfile. The idea is that your docker build command should "pack" all the information needed to generate the same image on 2 different systems.
However, you can hack your way around it using docker-compose, like explaned here: Pass host environment variables to dockerfile.

Docker: How to copy a file from one folder in a container to another?

I want to copy my compiled war file to tomcat deployment folder in a Docker container. As COPY and ADD deals with moving files from host to container, I tried
RUN mv /tmp/projects/myproject/target/myproject.war /usr/local/tomcat/webapps/
as a modification to the answer for this question. But I am getting the error
mv: cannot stat ΓÇÿ/tmp/projects/myproject/target/myproject.warΓÇÖ: No such file or directory
How can I copy from one folder to another in the same container?
You can create a multi-stage build:
https://docs.docker.com/develop/develop-images/multistage-build/
Build the .war file in the first stage and name the stage e.g. build, like that:
FROM my-fancy-sdk as build
RUN my-fancy-build #result is your myproject.war
Then in the second stage:
FROM my-fancy-sdk as build2
COPY --from=build /tmp/projects/myproject/target/myproject.war /usr/local/tomcat/webapps/
A better solution would be to use volumes to bind individual war files inside docker container as done here.
Why your command fails
The command you are running tries to access files which are out of context to for the dockerfile. When you build the image using docker build . the daemon sends context to the builder and only those files are accessible during the build. In docker build . the context is ., the current directory. Therefore, it will not be able to access /tmp/projects/myproject/target/myproject.war.
Copying from inside the container
Another option would be to copy while you are inside the container. First use volumes to mount the local folder inside the container and then go inside the container using docker exec -it <container_name> bash and then copy the required files.
Recommendation
But still, I highly recommend to use
docker run -v "/tmp/projects/myproject/target/myproject.war:/usr/local/tomcat/webapps/myproject.war" <image_name>

Resources