Best practices while building the Dockerfile.
The context in Dockerfile is relative to the current working directory of the Dockerfile and that the location where Dockerfile is present becomes its context.
Which means we can create a Directory with some content and place our Dockerfile inside it and then traverse a number of directories away from the directory and can still execute the build command
Here is an example of out general approach to building an image from a Dockerfile with . context:
# docker build --tag nginx-linuxcent .
And we list the image as follows:
[vamshi@docker01 ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx-linuxcent latest 0b0a4ea4d48a 3 minutes ago 210.1 MB
The build context is a
. dot and the Dockerfile is present in the same directory.
If You are working locally you don’t really need a repository name and specifying just the image name is sufficient and then adding a tag is considered optional, in such cases a
latest tag is appended to the end of the newly build image
As a standard practice that the Dockerfile doesn’t traverse back from the current working directory. Lets see an demonstration of of building a Dockerfile by giving the relative path from its Dockerfile.
[vamshi@node01 ~]$ ls nginx/ default.conf Dockerfile-nginx index.html nginx.conf Portal.tar.gz
Here is our nginx/Dockerfile-nginx.
cat Dockerfile-nginx FROM nginx:1.17.2-alpine COPY index.html /usr/share/nginx/html/ ADD Portal.tar.gz /tmp/new1/portal CMD ["/usr/sbin/nginx"]
Our command to build this Dockerfile-nginx now becomes:
[vamshi@docker01 ~]$ docker build -t nginx-linuxcent -f nginx/Dockerfile-nginx nginx/ Sending build context to Docker daemon 155.4 MB Step 1/4 : FROM nginx:1.17.2-alpine ---> 55ceb2abad47 Step 2/4 : COPY index.html /usr/share/nginx/html/ ---> cc652d0fc2b7 Removing intermediate container 11f195a0e2ac Step 3/4 : ADD Portal.tar.gz /tmp/new1/portal1/ ---> b18a86545c47 Removing intermediate container 1e1849be08b4 Step 4/4 : CMD /usr/sbin/nginx ---> Running in fdac087b636b ---> 02e2795eab12 Removing intermediate container fdac087b636b Successfully built 02e2795eab12
Or you can also mention the absolute path as shown below.
[vamshi@docker01 ~]$ # docker build -t nginx-linuxcent -f /home/vamshi/nginx/Dockerfile-nginx /home/vamshi/nginx/
The above example successfully builds a docker image. The Directory nginx/ is its build context as nginx/Dockerfile-nginx is the relative path of the input Dockerfile-nginx to docker build command.
Dockerfile and the context being different
Placing the Dockerfile-nginx inside the nginx directory and context placed one directory above the Dockerfile-nginx.
We now need to modify and carefully place the ADD/COPY commands relative to its directory in order for it to work properly, The context being one directory ahead, they should be prefixed with the directory name as we see below:
FROM nginx:1.17.2-alpine COPY nginx/index.html /usr/share/nginx/html/ ADD nginx/Portal.tar.gz /tmp/new1/portal1/ CMD ["/usr/sbin/nginx"]
Now our docker build command takes the following syntax:
[vamshi@docker01 ~]$ docker build -t nginx-linuxcent -f nginx/Dockerfile-nginx . Sending build context to Docker daemon 155.4 MB Step 1/4 : FROM nginx:1.17.2-alpine ---> 55ceb2abad47 Step 2/4 : COPY nginx/index.html /usr/share/nginx/html/ ---> Using cache ---> cc652d0fc2b7 Step 3/4 : ADD nginx/Portal.tar.gz /tmp/new1/portal1/ ---> Using cache ---> b18a86545c47 Step 4/4 : CMD /usr/sbin/nginx ---> Using cache ---> 02e2795eab12 Successfully built 02e2795eab12
Here the context remains outside the directory and the Dockerfile is present inside the subdirectory, the ADD/COPY commands are prefixed with the relative path of the dubirectory
Common errors Encountered with context mismatch:
unable to prepare context: The Dockerfile must be within the build context
How to tag a Docker image with a repository name during build process?
You can name your Dockerfile anything and it doesnt matter to the build process as long as you refer it with the -f
The standard naming convention is as shown below.
# docker build -t <DOCKER_IMAGE-NAME>:<TAG> -f Dockerfile .
# docker build -t <REPOSITORY/REGISTRY NAME>/<DOCKER_IMAGE-NAME>:<TAG> -f Dockerfile .
# docker build --tag mydocker-registry-name/nginx-linuxcent:version1.0 -f Dockerfile .
Here the Dockerfile need not be explicitly mentioned with
-f as the name of the file is Dockerfile and the context being .
# docker build --tag mydocker-registry-name/nginx-linuxcent:version1.0 - .
The Build context
. at the end is important because it signifies the current context and the context cannot span backward.
The tag name is a must for best practices and helps in identifying the newly build images and tagging enables visible versioning and better identification of images.
Docker build with no-cache
Creating Docker images with the
--no-cache option when you do not use cache when building the image, The default option for this is set to false and can be used explicitly to enforce no-cache..
It can be at times important when building container images which are dependent upon downloading latest libraries from the internet or practically from your on-premise code repository which contains the freshly compiled code artifacts.
Build the Docker image with no cache:
# docker build --no-cache -t mydocker-registry-name/nginx:version0.1 -f Dockerfile .
Once the docker container is successfully built, we can take a look at the newly created image as below.
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE mydocker-registry-name/nginx: version0.1 bcdd25553d01 3 minutes ago 298 MB
The docker build context becomes the present path of the Dockerfile.The docker image build is a simple process if things are neatly organized and the context can be quiet tricky if you are managing multiple Docker builds. You have the flexibility to give the absolute of relative path to the docker build.
Its always advised to implement the relative path and use the
. dot as context being in the same directory where your Dockerfile is present to run the Docker builds.
Ensure to use the no-cache option
And have a proper tagging in place to enable better version identity of your docker images.
If at all you need to build an image being in different context then always write the Dockerfile relative to the directory path of current context