Sunday, March 5, 2023

Dockerfile In Detail

Docker file Instruction Command:

FROM - Defines a base image, it can be pulled from docker hub
(for example- if we want to create a javascript application with node as backend then we need to have node as a base image, so it can run node application.)

RUN - Executes command in a new image layer( we can have multiple run commands )

CMD - Command to be executed when running a container( It is asked to have one CMD command, If a Dockerfile has multiple CMDs, it only applies the instructions from the last one.

EXPOSE - Documents which ports are exposed (It is only used for documentation)

ENV - Sets environment variables inside the image

COPY - It is used to copy your local files/directories to Docker Container.

ADD - It is more feature-rich version of the COPY instruction. COPY is preferred over ADD. Major difference b/w ADD and COPY is that ADD allows you to copy from URL that is the source can be URL but in COPY it can only have local ones.

ENTRYPOINT - Define a container's executable (You cannot override and ENTRYPOINT when starting a container unless you add the --entrypoint flag.)

VOLUME - It defines which directory in an image should be treated as a volume. The volume will be given a random name which can be found using docker inspect command.

WORKDIR - Defines the working directory for subsequent instructions in the Dockerfile(Important point to remember that it doesn't create a new intermediate layer in Image)









Difference between RUN,CMD and ENTRYPOINT?

RUN - RUN instruction allows you to install your application and packages required for it. It executes any commands on top of the current image and creates a new layer by committing the results. Often you will find multiple RUN instructions in a Dockerfile.

To run this command you will need a separate new layer and this command is mainly used to build images, and install packages and applications.

#RUN apt-get install python

CMD - CMD instruction allows you to set a default command, which will be executed only when you run container without specifying a command. If Docker container runs with a command, the default command will be ignored. If Dockerfile has more than one CMD instruction, all but last CMD instructions are ignored.
The CMD describes the default container parameters or commands. The user can easily override the default command when you use this

#CMD "echo" "Hello World!"

ENTRYPOINT - ENTRYPOINT instruction allows you to configure a container that will run as an executable. It looks similar to CMD, because it also allows you to specify a command with parameters. The difference is ENTRYPOINT command and parameters are not ignored when Docker container runs with command line parameters.
A container with an ENTRYPOINT is preferred when you want to define an executable. You can only override it if you use the --entrypoint flag.

Prefer ENTRYPOINT to CMD when building executable Docker image and you need a command always to be executed. Additionally use CMD if you need to provide extra default arguments that could be overwritten from command line when docker container runs.




The main difference between CMD and Entrypoint is that you can override the CMD instruction from Docker CLI when the container is running. However, you can't override the entrypoint command with just command line parameters. Instead, you need to use the docker run command with a particular syntax.

docker run --entrypoint [new_command] [docker_image] [optional:value]

docker run -it --entrypoint /bin/bash image2


FROM alpine:3.5
LABEL maintainer="Collabnix"

ENTRYPOINT ["/bin/echo", "Hi, your ENTRYPOINT instruction in Exec Form !"]


Executable form V/s Shell Form:

Executable form:

FROM ubuntu
RUN apt-get update && apt-get install -y nginx
ENTRYPOINT ["nginx", "-g", "daemon off;"]

docker inspect <container-id>

 "Entrypoint": [
                "nginx",
                "-g",
                "daemon off;"
            ],

nginx process id is 1

Shell Form:
FROM ubuntu
RUN apt-get update && apt-get install -y nginx
ENTRYPOINT nginx -g "daemon off;"
~                                         

 "Entrypoint": [
                "/bin/sh",
                "-c",
                "nginx -g \"daemon off;\""
            ],

Shell Format sh process id is 1:

[root@ip-172-31-34-29 DockerDemo]# docker exec -it 854e14bbc4ae sh
# top
top - 18:14:36 up 3 days, 16:16,  0 users,  load average: 0.00, 0.00, 0.00
Tasks:   5 total,   1 running,   4 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :    964.8 total,    185.0 free,    187.7 used,    592.0 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.    629.4 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0    2888    976    880 S   0.0   0.1   0:00.20 sh
    7 root      20   0   55156  12256  10660 S   0.0   1.2   0:00.00 nginx
    8 www-data  20   0   55524   3404   1468 S   0.0   0.3   0:00.00 nginx


Executable form:

asks:   6 total,   1 running,   5 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :    964.8 total,    194.4 free,    178.1 used,    592.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.    639.2 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0   55200  12152  10512 S   0.0   1.2   0:00.20 nginx
    7 www-data  20   0   55524   3368   1436 S   0.0   0.3   0:00.00 nginx
    8 root      20   0    2888    972    876 S   0.0   0.1   0:00.19 sh

[root@ip-172-31-34-29 DockerDemo]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS     NAMES
bcccebab6d82   myimg3    "/bin/sh -c 'ng…"   About a minute ago   Up About a minute             vigorous_swanson
6d03a1b2bfc6   myimg1    "nginx -g 'daemon of…"   13 minutes ago       Up 13 minutes                 unruffled_jones



The SHELL form runs the command as a child process (on a shell). The EXEC form runs the executable on the main process.

Commands are written without [] brackets and are run by the container's shell, such as /bin/sh -c

Commands are written with [] brackets and are run directly, not through a shell


Shell features
The main thing you lose with the exec form is all the useful shell features: sub commands, piping output, chaining commands, I/O redirection, and more. 
These kinds of commands are only possible with the shell form:

FROM ubuntu:latest

# Shell: run a speed test
RUN apt-get update \
 && apt-get install -y wget \
 && wget -O /dev/null http://speedtest.wdc01.softlayer.com/downloads/test10.zip \
 && rm -rf /var/lib/apt/lists/*

# Shell: output the default shell location
CMD which $(echo $0)



Most shells do not forward process signals to child processes, which means the SIGINT generated by pressing CTRL-C may not stop a child process:

# Note: Alpine's `/bin/sh` is really BusyBox `ash`, and when
#   `/bin/sh -c` is run it replace itself with the command rather
#   than spawning a new process, unlike Ubuntu's `bash`, meaning
#   Alpine doesn't exhibit the forwarding problem
FROM ubuntu:latest

# Shell: `bash` doesn't forward CTRL-C SIGINT to `top`
ENTRYPOINT top -b

# Exec: `top` traps CTRL-C SIGINT and stops
ENTRYPOINT ["top", "-b"]

FROM ubuntu
RUN apt-get update && apt-get install -y nginx
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]
#ENTRYPOINT nginx -g "daemon off;"



In general, use the shell form for RUN, and the exec form for everything else.


EXPOSE PORT:
FROM ubuntu:latest
EXPOSE 80/tcp
EXPOSE 80/udp
[root@ip-172-31-34-29 DockerDemo]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS            NAMES
3dec2971eb8c   portexpose    "nginx -g 'daemon of…"   6 minutes ago   Up 6 minutes   80/tcp           eloquent_swirles
d1f5432037e7   expose_port   "bash"                   8 minutes ago   Up 8 minutes   80/tcp, 80/udp   vibrant_liskov
Volume:
Volumes can be declared in your Dockerfile using the VOLUME statement. This statement declares that a specific path of the container must be mounted to a Docker volume. When you run the container, Docker will create an anonymous volume (volume with a unique id as the name) and mount it to the specified path.

No comments:

Post a Comment

Sample Game App Deployment on EKS cluster

 https://padmakshi.medium.com/setting-up-an-eks-cluster-and-deploying-a-game-application-a-step-by-step-guide-08790e0be117