Docker’ı admin kullanıcısı ile yönettiğinizi ve php-fpm image’ını kullandığınızı varsayalım.
Host’unuzdaki /home/admin/www
klasörü container’ınızın /var/www/project
klasörüne mount edilmiş.
- Docker exec komutu ile container’ın içinden bir dosya oluşturduğunuzda bu dosyanın sahibi root kullanıcısı olacaktır.
- Sitenize webden bir dosya upload ettiğinizde bu dosyanın sahibi www-data olacaktır.
- Docker dışından admin kullanıcısı ile www klasörüne bir dosya oluşturduğunuzda bu dosyanın sahibi admin kullanıcısı olacaktır.
Bir önceki yazımdaki çözümü uyguladığınızda 1. ve 2. işlemler www-data kullanıcısını kullanıp oluşturdukları dosyalara erişebileceklerdir fakat 3. aşamadaki işlem ile oluşturulmuş dosyalara erişemeyeceklerdir.
Unix/Linux dosyaların sahibinin kullanıcı adını ve grubunun adını değil kullanıcısının ve grubunun id’lerini tutar.
Örneğin www-data kullanıcısının oluşturduğu dosyanın uid’si 33, admin kullanıcısının oluşturduğu dosyanın uid’si 1000 olacaktır. Genellikle aynı id’ler ile gruplar da oluşturulur. www-data(33) user’ı www-data(33) group’u gibi.
Bu durumda eğer container’ın www-data kullanıcısının id’sini 33 yerine 1000 yaparsak, 3 işlemde de dosyalar 1000 id’si ile oluşturulacaktır. uid ve gid değeri 1000 olan bir dosyanın sahibine docker dışından baktığımızda admin, container’ı içinden baktığımızda ise www-data gözükecektir. İsimleri farklı olsa da id’ler aynı olduğu için dosya izni sorunları olmayacaktır.
Çözüm
Host söylemediği sürece Container’lar host’un uid ve gid bilgisine erişemez. Container’a build aşamasında kullanabilmesi için argument olarak uid ve gid değerlerini verebiliriz.
- Dockerfile’a aşağıdaki satırları ekleyin.
ARG HOST_UID
ARG HOST_GID
ENV HOST_UID $HOST_UID
ENV HOST_GID $HOST_GID
RUN sed -ri 's#^www-data:x:33:33:www-data:/var/www:#www-data:x:'"$HOST_UID"':'"$HOST_GID"':www-data:/home/www-data:#' /etc/passwd
RUN sed -ri 's#^www-data:x:33:#www-data:x:'"$HOST_GID"':#' /etc/group
RUN mkdir /home/www-data && chown -R www-data:www-data /home/www-data
USER www-data
- Container’ı derlerken host’unuzun uid ve gid değerlini argument olarak ekleyin.
docker build --build-arg HOST_UID=$(id -u) --build-arg HOST_GID=$(id -g) .
Detay
Yukarıdaki şekilde container’ı derlediğinizde Dockerfile aşağıdaki işlemleri yapacak:
- Argument(buildda kullanılan değişken) olarak alınan uid ve gid değeri env(terminalde kullanılan değişken)’a aktarılıyor.
/etc/passwd
ve/etc/group
dosyalarında tutulan www-data kullanıcısının uid ve gid değeri host’tan gelen uid ve gid değeri ile değiştiriliyor.- www-data kullanıcısının home klasörü root kullanıcısına ait olan
/var/www
yerine/home/www-data
ile değiştiriliyor. /home/www-data
klasörü oluşturulup, klasör sahibi www-data kullanıcısı olacak şekilde değiştiriliyor.- Container’ın varsayılan olan root kullanıcısı yerine www-data kullanıcısı ile çalışması sağlanıyor.