Dockerfile - Add, Copy, User

USER

The USER instruction is used to switch the user for any instruction that follows it in the dockerfile.

Let's see an example.

In the below dockerfile we will see an example for running statements

RUN whoami \> /tmp/1stwhoami.txt as a root user and RUN whoami \> /tmp/1stwhoami.txt as another user which we will add while creating this image.

To do this we have added couple of new instructions in the dockerfile below:

Here first we are installing two packages namely openssh-server and python in the image.

After this we are creating a new user 'gaurav' using the 'useradd' command.

In the useradd command we are defining the user's home directory, user's group, providing the password in an encrypted form, and specifying the username.

The username and password are being passed using environment variables defined in the preceding instructions.

FROM ubuntu:14.04
LABEL name="learning-ocean"
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
RUN apt-get update && apt-get install -y openssh-server && apt-get install -y python
RUN useradd -d /home/gaurav -g root -G sudo -m -p $(echo "$PASS" | openssl passwd -1 -stdin) $NAME
RUN whoami>/tmp/1stwhoami.txt
USER $NAME
RUN whoami>/tmp/2ndwhoami.txt

If you notice we have also added a new instruction to switch the user using the USER instruction in the line after RUN whoami > /tmp/1stwhoami.txt.

We will see the contents of 1stwhoami.txt and 2ndwhoami.txt after building the image and running the container to verify if the user has been switched or not.

gaurav@learning-ocean:~/dockerfiles$ docker image build -t myubuntu:81 .

run container from created image and verify:

gaurav@learning-ocean:~/dockerfiles$ docker container run -it myubuntu:81
Gaurav@79599638d94c:/tmp$ cat 1stwhoami.txt
root
Gaurav@79599638d94c:/tmp$ cat 2ndwhoami.txt
Gaurav
Gaurav@79599638d94c:/tmp$

On running the container we can see that the text files contain the user names as expected.

COPY

The COPY instruction is used to copy the files or directories from the specified source to the destination inside the container's filesystem.

Let's see an example again.

In this example we will see how we can copy the directory testproject and its content to a directory named project inside the tmp directory in a container.

gaurav@learning-ocean:~/dockerfiles$ ls
Dockerfile  testproject
gaurav@learning-ocean:~/dockerfiles$ ls testproject/
index.html  test.html  test.php
gaurav@learning-ocean:~/dockerfiles$

For doing this we have added two instructions at the bottom of the existing dockerfile to create a directory inside tmp and a COPY instruction to provide the source directory to be copied to the destination inside the container to which it needs to be copied.

FROM ubuntu:14.04
LABEL name="learning-ocean"
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
RUN apt-get update && apt-get install -y openssh-server && apt-get install -y python
RUN useradd -d /home/gaurav -g root -G sudo -m -p $(echo "$PASS" | openssl passwd -1 -stdin) $NAME
RUN whoami>/tmp/1stwhoami.txt
USER $NAME
RUN whoami>/tmp/2ndwhoami.txt
RUN mkdir -p /tmp/project
COPY testproject /tmp/project

Now we will build the image and run the container to check if the files have been copied.

 docker image build -t myubuntu:81 .

verify:

gaurav@learning-ocean:~/dockerfiles$ docker container run -it myubuntu:81
Gaurav@f46db1563db6:/tmp$ ls
1stpwd.txt  1stwhoami.txt  2ndpwd.txt  2ndwhoami.txt  3rdpwd.txt  project
Gaurav@f46db1563db6:/tmp$ cd project/
Gaurav@f46db1563db6:/tmp/project$ ls
index.html  test.html  test.php
Gaurav@f46db1563db6:/tmp/project$

We can see above that directory and its content have been copied to the desired location.

ADD

The ADD instruction is also used to copy the files or directories from the specified source to the destination inside the container's filesystem.

The usage of ADD instruction is similar to the COPY instructions (as shown in the image below).

FROM ubuntu:14.04
LABEL name="learning-ocean"
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
RUN apt-get update && apt-get install -y openssh-server && apt-get install -y python
RUN useradd -d /home/gaurav -g root -G sudo -m -p $(echo "$PASS" | openssl passwd -1 -stdin) $NAME
RUN whoami>/tmp/1stwhoami.txt
USER $NAME
RUN whoami>/tmp/2ndwhoami.txt
RUN mkdir -p /tmp/project
ADD testproject /tmp/project

Difference between ADD and COPY in Docker

The main difference between the ADD and COPY instructions is that if the source file is in a recognized compression format such as identity, gzip, bzip2 or xz, then ADD instruction will unpack it as a directory and copy it to the destination while COPY instruction will copy the compressed file as it is without any unpacking.

Now let's see what will happen if we copy the file testproject.tar.gz using COPY and ADD instructions.

The testproject.tar.gz file contains 3 files which can be seen in the below.

gaurav@learning-ocean:~/dockerfiles$ ls
Dockerfile  testproject  testproject.tar.gz
gaurav@learning-ocean:~/dockerfiles$ ls testproject
index.html  test.html  test.php
gaurav@learning-ocean:~/dockerfiles$

Dockerfile :

FROM ubuntu:14.04
LABEL name="learning-ocean"
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
RUN apt-get update && apt-get install -y openssh-server && apt-get install -y python
RUN useradd -d /home/gaurav -g root -G sudo -m -p $(echo "$PASS" | openssl passwd -1 -stdin) $NAME
RUN whoami>/tmp/1stwhoami.txt
USER $NAME
RUN whoami>/tmp/2ndwhoami.txt
RUN mkdir -p /tmp/project
COPY testproject.tar.gz /tmp/project

build image using below command:

 docker image build -t myubuntu:81 .

verify:

gaurav@learning-ocean:~/dockerfiles$ docker container run -it myubuntu:81
Gaurav@5d417b034c06:/tmp$ ls
1stpwd.txt  1stwhoami.txt  2ndpwd.txt  2ndwhoami.txt  3rdpwd.txt  project
Gaurav@5d417b034c06:/tmp$ cd project/
Gaurav@5d417b034c06:/tmp/project$ ls
testproject.tar.gz
Gaurav@5d417b034c06:/tmp/project$

We can see here using COPY instruction the file has been copied as it is. Now let's use ADD.

FROM ubuntu:14.04
LABEL name="learning-ocean"
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
RUN apt-get update && apt-get install -y openssh-server && apt-get install -y python
RUN useradd -d /home/gaurav -g root -G sudo -m -p $(echo "$PASS" | openssl passwd -1 -stdin) $NAME
RUN whoami>/tmp/1stwhoami.txt
USER $NAME
RUN whoami>/tmp/2ndwhoami.txt
RUN mkdir -p /tmp/project
ADD testproject.tar.gz /tmp/project

Build image using below command:

 docker image build -t myubuntu:81 .

Verify:

gaurav@learning-ocean:~/dockerfiles$ docker container run -it myubuntu:81
Gaurav@55888cd83dd5:/tmp$ ls
1stpwd.txt  1stwhoami.txt  2ndpwd.txt  2ndwhoami.txt  3rdpwd.txt  project
Gaurav@55888cd83dd5:/tmp$ cd project/
Gaurav@55888cd83dd5:/tmp/project$ ls
testproject
Gaurav@55888cd83dd5:/tmp/project$ cd testproject/
Gaurav@55888cd83dd5:/tmp/project/testproject$ ls
index.html  test.html  test.php
Gaurav@55888cd83dd5:/tmp/project/testproject$

We can see in the above image that the ADD instruction has unpacked the file into the directory testproject and copied the contents.