Dockerfile - Label, Env, Run and Workdir

Label

Label command is used to add metadata to docker objects such as images, containers, local daemons, volumes, networks, swarm nodes and swarm services.

Labels are key-value pairs stored as a string that can be used to organize your images, add licensing information, etc. We can add multiple labels to a docker object.

Let's see how it works.

gaurav@learning-ocean:~$ vi Dockerfile
FROM ubuntu:14.04
LABEL name="learning-ocean"
LABEL email="[email protected]"

We have added two labels here one as name and the other as email. Now let's build the image.

gaurav@learning-ocean:~$ docker image build -t myubuntu:10 |less

The image is created. To check if the labels are added or not, we will use the following command:

We can see the labels are added in the output of the above command:

...
   "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "email": "[email protected]",
                "name": "learning-ocean.com"
            }
        },
...

ENV

The ENV instruction is used to provide environment variables to an image which are persisted when a container is run.

Let's see how we can use it.

Below is the dockerfile with environment variables Name and Pass.

FROM ubuntu:16.04
LABEL name="learning-ocean.com"
LABEL email="[email protected]"
ENV name gaurav
ENV pass password

Now, we build this image.

learning-ocean:dockerfiles gaurav$ docker image build -t myubuntu:11 .

Running the container.After this we can check if our environment variables are available in this container or not by using the following command.

learning-ocean:dockerfiles gaurav$ docker container run -it myubuntu:11
root@a02557a286c3:/# env
pass=password
HOSTNAME=a02557a286c3
TERM=xterm
name=gaurav
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
SHLVL=1
HOME=/root
_=/usr/bin/env

We can see above the environment variables we created are available in this container.

RUN

The RUN instruction is used to execute any command in a new layer on top of the current image and the resulting image will be used for the next step in the docker file.

Let's see an example:

RUN statements in the below dockerfile are supposed to create a text file with the current working directory as their content.

learning-ocean:dockerfiles gaurav$ cat Dockerfile
FROM ubuntu:16.04
LABEL name="learning-ocean.com"
LABEL email="[email protected]"
ENV name gaurav
ENV pass password
RUN pwd>/tmp/1stpwd.txt
RUN cd /tmp
RUN pwd>tmp/2ndpwd.txt
learning-ocean:dockerfiles gaurav$

build imaga and create a container from that image and check

learning-ocean:dockerfiles gaurav$ docker image build -t myubuntu:11 .
learning-ocean:dockerfiles gaurav$ docker container run -it myubuntu:1
root@0624737baf96:/# cd /tmp/
root@0624737baf96:/tmp# cat 1stpwd.txt
/
root@0624737baf96:/tmp# cat 2ndpwd.txt
/
root@0624737baf96:/tmp#

After building this image, running the container and checking the content of the files we see that the content of both the files is the same whereas the current working directory in the file '2ndpwd.txt' should have been "/tmp".

This happened because we were expecting that the three RUN statements will be executed sequentially but actually each RUN instruction is executed independently and in a separate layer by docker. Each RUN instruction will be executed in its own container and each statement will start the execution from its root directory.

WORKDIR

The WORKDIR instruction is used to set or change the working directory for any instruction that follows it in the dockerfile.

Let's see its usage:

learning-ocean:dockerfiles gaurav$ cat Dockerfile
FROM ubuntu:16.04
LABEL name="learning-ocean.com"
LABEL email="[email protected]"
ENV name gaurav
ENV pass password
RUN pwd>/tmp/1stpwd.txt
RUN cd /tmp
RUN pwd>/tmp/2ndpwd.txt
WORKDIR /tmp
RUN pwd>/tmp/3rdpwd.txt
learning-ocean:dockerfiles gaurav$

We will create a new image from the below docker file and run the container and then check the content of file '3rdpwd.txt' it should contain the current working directory i.e "/tmp" which is changed in the previous step using workdir instruction.

learning-ocean:dockerfiles gaurav$ docker container run -it myubuntu:1
root@2ea45d442c74:/tmp# cd /tmp/
root@2ea45d442c74:/tmp# cat 1stpwd.txt
/
root@2ea45d442c74:/tmp# cat 2ndpwd.txt
/
root@2ea45d442c74:/tmp# cat 3rdpwd.txt
/tmp
root@2ea45d442c74:/tmp#

We can see here that the content of the file 3rdpwd.txt is /tmp which was the directory we switched to using workdir instruction.