Imagine the following scenario: your world-famous web application is hosted with two Docker containers (eg. with application server). Both containers have access to same host's directories (passed with Docker's
-v parameter) mounted as:
/configuration- containing few configuration files,
/logs- storing log files outside containers.
Arguably, there are lots of better solutions (including databases, log indexing systems etc.) but that's the issue we need to face now.
The following user accounts are involved:
admin- host OS
web1- first container
web2- second container
admin changes configuration file
web2 may (both, one or none of them) get
Permission denied exception.
admin reads logs written by
admin may get
Permission denied exception (without
admin lists logs directory contents
$ whoami admin $ ls -la logs -rw-r--r-- 1 1003 1003 0 05-12 11:28 application.log -rw-r--r-- 1 lightdm network 0 04-04 04:15 yetanother.log $ # lightdm user? o.O
Scenarios above show typical file permission problems, which are not strictly related to Docker or Linux itself. However, running Docker containers enforces using separate user for each container / app. The situation could be even worse, when instead of any user above its actions will be performed as
Obviously, one can just run all actions in containers as
root and use
sudo to write/read from the
admin account, however:
- performing all action as
rootcan significantly reduce security,
adminuser may not have
Solution? One to rule them all!
Let's go back to the
root only actions case.
root on host system can read & modify files owned by the
root inside the container because they both share the same User identifier (UID) value (
0 by default)- a number representing a user in Unix-like systems.
$ id -u admin # check admin UID 1002 $ chown admin file.txt # make admin user file owner $ ls -la | grep file.txt -rw-r--r-- 1 admin users 0 09-11 23:34 file.txt $ chown 1002 file.txt # same effect as before $ ls -la | grep file.txt -rw-r--r-- 1 admin users 0 09-11 23:34 file.txt
The reason of strange
ls -la output in scenario #3 are different UIDs. Possibly,
web1 has UID value
1003 (inside the container) and
web2 UID is the same as
lightdm user on the host OS.
Simple and straightforward solution to this problem, is to keep the same UID value for all users "collaborating" with each other. Setting UID value
web2 users inside their containers, can lead to the following result:
$ whoami admin $ ls -la logs -rw-r--r-- 1 admin admin 0 05-12 11:28 application.log -rw-r--r-- 1 admin network 0 04-04 04:15 yetanother.log
How to set UID value for given user?
- during manual user creation pass it as an argument option:
useradd -u UID username ...
- for existing user execute
usermod -u UID username
CAUTION! changing existing user's identifier breaks file permissions! (which are still based on old UID value) Additional
chown will be required on all owned files!
So, all you gotta do is to add a suitable command to each of your
Dockerfile, rebuild images and enjoy another solved task :-)