Docker container varsayılan olarak her zaman root kullanıcı olarak çalışır. Sonuç olarak çalışan tüm işlemlerin, paylaşılmış klasörlerin, dosyaların vs. sahibi root olacaktır. Bu durum ana sistemde veya docker container içinde klasörler/dosyalar üzerinde değişiklikler yapmak istediğimiz zaman problem olacaktır.

Bu gibi sorunları çözmek için, ana sistem ve docker container kullanıcısının UIDlerini eşitlememiz gerekir. Docker container'in root kullanıcısının UIDsi her zaman 0 olacaktır. Docker container'i root kullanıcısı ile çalıştırmak kötü bir güvenlik sorunudur.


Ana sistem


Aktif kullanıcının bilgileri.


ubuntu@linux:~$ echo $HOME
/home/ubuntu

ubuntu@linux:~$ pwd
/home/ubuntu

ubuntu@linux:~$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)

Data klasörü


ubuntu@linux:~$ mkdir data

Dockerfile


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"]

Entrypoint.sh


Aşağıdaki yorumları okuduğunuzda ne yapıldığını anlayacaksınız.


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 "$@"

İmaj yaratma


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

Container yaratma - Versiyon 1


Container'e yerel kullanıcının UID'sini kullanmasını ve yerel data klasörü ile container'in /var/log klasörünü birbirlerine bağlamasını isteyeceğiz.


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:/$

Test


Kullanıcı'nın UID'sini kontrol etmek.


docker@3afdd4887dc5:/$ id
uid=1000(docker) gid=1000(docker) groups=1000(docker)

Container içinde dosya yaratmak.


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

Yerel sistemde dosya yaratma ve mevcut olanları kontrol etme.


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

Container içindeki dosyaları tekrar kontrol etme.


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

Container yaratma - Versiyon 2


Burada yukarıdaki "versiyon 1"'in aksine container'e, yerel kullanıcının UID'sini kullanmasını istemeyeceğiz. Onun yerine varsayılan olarak 9999 kullanılacak.


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)

Bu versiyon'daki testlerin sonuçları, yukarıdaki testler ile aynı olacaktır.