DevOps Classroomnotes 12/Jun/2022

Working with Dockerfile

  • Dockerfile is a text file that contains instructions on how to create docker images.
  • These commands are known as directives
# This is comment
DIRECTIVE argument

Common Directives:

  • FROM:
    • This is used to set the base image/parent image
    • This can be any image from Docker hub
    • FROM <image>:<tag> if the tag is not mentioned latest tag will be applied/assumed by Docker image
    • If you want to build the docker image from scratch then use FROM scratch
  • LABEL”
    • This is key-value pair used to add metadata to Docker Image
    • LABEL <KEY>=<VALUE>
    • We can add multiple LABEL directives or multiple labels with space sepearted.
  • RUN:
    • This directive is used to execute the command during image build time.
    • This will generally have application configuration/installation etc
    • Any RUN command which impacts the storage a new layer will be created.
  • CMD:
    • This directive will be executed when the container is created when no ENTRYPOINT directive exists
    • If the CMD is not present in current image it will execute parents CMD directive
    • Container will be in running state as long as the instructions in CMD are executing
    • The CMD has two forms exec and shell form
    • EXEC form
      CMD ["executable", "param1", ... , "paramn"]
      CMD ["echo", "hello-world" ]
    • SHELL FORM
      CMD executable param1 .. paramn
      CMD echo hello-world
  • EXPOSE:
    • This directive will expose the port of the container
  • ADD:
    • This directive is used to copy files into docker image while building the image
    • Syntax ADD <src> <dest>
    • For the ADD src can be local files as well as URL’s
  • COPY:
    • This directive is used to copy files into docker image while building the image
    • Syntax COPY <src> <dest>
    • For COPY directive the source can be only local files

Lets start inspecting images

  • Lets build a Docker image called as hello:0.1.0 Refer Here for the changeset
    Preview
  • If we use scratch copying the files with kernel and executables is also our responsibility so for this session since we focus on building containers for software applications, choose the base image with necessary files is good choice.
  • Since we have built the image lets inspect it
docker image inspect hello:0.1.0

Preview
* Now lets take a docker image as parent which has some files in it Refer Here for the changes and lets build a new image hello:0.1.1
Preview
* lets inspect alpine image docker image inspect alpine:3.0

[
    {
        "Id": "sha256:e66264b98777e12192600bf9b4d663655c98a090072e1bab49e233d7531d1294",
        "RepoTags": [
            "alpine:3"
        ],
        "RepoDigests": [
            "alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2022-05-23T19:19:31.970967174Z",
        "Container": "49320ab4701345c613d266d2b3cf2ff0265c553d463f9061e479b6c8ef839a1f",
        "ContainerConfig": {
            "Hostname": "49320ab47013",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/sh\"]"
            ],
            "Image": "sha256:f9ee3a3800e8eec1d8d7fb76906dd5859498b12d27a0258b3df35bca9fa8a867",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.12",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh"
            ],
            "Image": "sha256:f9ee3a3800e8eec1d8d7fb76906dd5859498b12d27a0258b3df35bca9fa8a867",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 5524281,
        "VirtualSize": 5524281,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/dacb8a310bbe17ca0e4e83768b8c4d6ba6fe61d70916c59c49edf3242bc397c3/merged",
                "UpperDir": "/var/lib/docker/overlay2/dacb8a310bbe17ca0e4e83768b8c4d6ba6fe61d70916c59c49edf3242bc397c3/diff",
                "WorkDir": "/var/lib/docker/overlay2/dacb8a310bbe17ca0e4e83768b8c4d6ba6fe61d70916c59c49edf3242bc397c3/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:24302eb7d9085da80f016e7e4ae55417e412fb7e0a8021e95e3b60c67cde557d"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]
  • Refer Here for changeset containing RUN directive and impact on docker image layers. Build a new image hello:0.1.2
    Preview
    Preview
  • Now lets inspect hello:0.1.2 specifically layers
    Preview
  • Docker image is collection of image layers
    Preview
  • For docker container to work these layers should be combine to form a file system
  • Since docker images have layers and container need to process them docker has different storage drivers which help containers work with image layers.
  • The container which we built is not running
    Preview
  • Lets assume We want to run the container for some time (1d) Refer Here for the changes
  • Ideally the CMD should have some command or script which is executed as long as our application is running.

Scenario: Lets build a lamp server based on centos base image

  • Refer Here for the steps, skip the mysql installation part
  • Dockerfile
FROM centos:7
LABEL purpose="classroom" author="khaja"
RUN yum install httpd -y && yum install php php-mysql -y && systemctl enable httpd.service
EXPOSE 80
CMD ["sleep", "1d"]
  • This is not a good httpd but lets improve it Refer Here for the changes
    Preview
  • Using Expose Instruction is mandatory for dynamic port forwarding
    Preview
  • Refer Here for all the changes done in the Dockerfile

Exercise

  • Try creating Dockerfile for spring petclinic Refer Here
  • Try creating Dockerfile for gameoflife Refer Here

Important Commands

  • Listing Containers
    Preview
  • Remove all the contianers
    Preview

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About continuous learner

devops & cloud enthusiastic learner