21/01/2018 - DOCKER
Docker containers are always run as root
user by default. As a result all running processes, shared volumes, folders, files will be owned by root
user. It becomes real problem when we need to modify files and folder in shared folders within host OS or docker container.
In order to solve such issue, we need to match host OS and docker container user's UID
s. The root
user's UID
is always 0
. Running docker as root
user is also considered as a bad security practice.
Current user's information.
ubuntu@linux:~$ echo $HOME
/home/ubuntu
ubuntu@linux:~$ pwd
/home/ubuntu
ubuntu@linux:~$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
ubuntu@linux:~$ mkdir data
ubuntu@linux:~$ nano Dockerfile
FROM ubuntu:16.04
ENV GOSU_URL https://github.com/tianon/gosu/releases/download/1.4/gosu
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN apt-get update \
&& apt-get -y install \
ca-certificates \
curl \
&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& curl -o /usr/local/bin/gosu -SL "$GOSU_URL-$(dpkg --print-architecture)" \
&& curl -o /usr/local/bin/gosu.asc -SL "$GOSU_URL-$(dpkg --print-architecture).asc" \
&& gpg --verify /usr/local/bin/gosu.asc \
&& rm /usr/local/bin/gosu.asc \
&& rm -rf /var/lib/apt/lists/* \
&& chmod +x /usr/local/bin/gosu \
&& chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
If you read the comments below, you'll see what it does.
ubuntu@linux:~$ nano entrypoint.sh
#!/bin/bash
set -e
# If "-e uid={custom/local user id}" flag is not set for "docker run" command, use 9999 as default
CURRENT_UID=${uid:-9999}
# Notify user about the UID selected
echo "Current UID : $CURRENT_UID"
# Create user called "docker" with selected UID
useradd --shell /bin/bash -u $CURRENT_UID -o -c "" -m docker
# Set "HOME" ENV variable for user's home directory
export HOME=/home/docker
# Execute process
exec /usr/local/bin/gosu docker "$@"
ubuntu@linux:~$ docker build -t app_img .
Sending build context to Docker daemon 3.584kB
Step 1/5 : FROM ubuntu:16.04
---> dd6f76d9cc90
Step 2/5 : ENV GOSU_URL https://github.com/tianon/gosu/releases/download/1.4/gosu
---> Running in 127ef4efcb80
---> 10d786ca796c
Removing intermediate container 127ef4efcb80
Step 3/5 : COPY entrypoint.sh /usr/local/bin/entrypoint.sh
---> 2756497869e5
Step 4/5 : RUN apt-get update && apt-get -y install ca-certificates curl && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && curl -o /usr/local/bin/gosu -SL "$GOSU_URL-$(dpkg --print-architecture)" && curl -o /usr/local/bin/gosu.asc -SL "$GOSU_URL-$(dpkg --print-architecture).asc" && gpg --verify /usr/local/bin/gosu.asc && rm /usr/local/bin/gosu.asc && chmod +x /usr/local/bin/gosu && chmod +x /usr/local/bin/entrypoint.sh
---> Running in 2aacad96c07c
---> 939ec3165391
Removing intermediate container 2aacad96c07c
Step 5/5 : ENTRYPOINT /usr/local/bin/entrypoint.sh
---> Running in e01eef5a0659
---> c042ca8f6891
Removing intermediate container e01eef5a0659
Successfully built 8d88aea7ed50
Successfully tagged app_img:latest
We tell container to use local user's UID
and link local data
folder to container's /var/log
folder.
ubuntu@linux:~$ docker run -i -t -v $(pwd)/data:/var/log -e uid=$UID --name app_con app_img /bin/bash
Current UID : 1000
docker@3afdd4887dc5:/$
Check current user's UID.
docker@3afdd4887dc5:/$ id
uid=1000(docker) gid=1000(docker) groups=1000(docker)
Create file in container.
touch /var/log/guest.log && echo "Written in container" >> /var/log/guest.log
docker@3afdd4887dc5:/$ ls -l /var/log
-rw-r--r-- 1 docker docker 21 Jan 21 19:36 guest.log
docker@3afdd4887dc5:/$ cat /var/log/guest.log
Written in container
Create file in local OS and check existing files.
ubuntu@linux:~$ ls -l
drwxrwxr-x 2 ubuntu ubuntu 4096 Jan 21 19:36 data
ubuntu@linux:~$ touch data/host.log && echo "Written in host" >> data/host.log
ubuntu@linux:~$ ls -l data/
-rw-r--r-- 1 ubuntu ubuntu 37 Jan 21 19:40 guest.log
-rw-rw-r-- 1 ubuntu ubuntu 16 Jan 21 19:41 host.log
ubuntu@linux:~$ cat data/guest.log
Written in container
Written in host
ubuntu@linux:~$ cat data/host.log
Written in host
Check files in container again.
ubuntu@linux:~$ docker run -i -t -v $(pwd)/data:/var/log -e uid=$UID --name app_con_1 app_img /bin/bash
Current UID : 1000
docker@51952cf6bb61:/$ ls -l /var/log/
-rw-r--r-- 1 docker docker 37 Jan 21 19:40 guest.log
-rw-rw-r-- 1 docker docker 16 Jan 21 19:41 host.log
As opposed "version 1" above, we will not tell container to use local user's UID
. Instead, it will use 9999
as default value.
ubuntu@linux:~$ docker run -i -t -v $(pwd)/data:/var/log --name app_con_2 app_img /bin/bash
Current UID : 9999
docker@a997362050f4:/$ id
uid=9999(docker) gid=9999(docker) groups=9999(docker)
The test results above would be same for this version too.