Docker on MacOSX does not correctly translate file permissions on volumes

I am using a simple Linux machine in Docker. Using it with Linux, I clone my dev repository and mount the repo as a volume in Docker. Then, when I enter the Docker container, the files in the volume belong to user 1000 in group 1000 (everything is fine, because Docker correctly saves all file owners). Now I'm trying to do the same in macOS, but on my macOS machine my uid is 501 and my gid is 20. But when I go to the container, I understand that the files inside it have gid and uid 0, the same as root. What can I do to keep file ownership in Docker?

+5
source share
2 answers

TL DR

The osxfs driver pretends that the files belong to the USER in which the container is running. If you see that the files are mounted as root, your container is probably configured to run as root.


Longer version

The osxfs driver on macOS talks a bit about ownership. Here is the relevant section of the documentation (my attention):

of property

Initially, any container process that requests property metadata for an object , said that its uid and gid belong to the object . When any container process changes ownership of a shared file system object, for example, with chown , new owner information is stored in the extended attribute com.docker.owner object. Subsequent property metadata requests return previously set values. Ownership-based permissions apply only at the OS X file system level, and all access processes behave like the user running Docker. If the user does not have permission to read extended attributes on an object (for example, when that permissions of objects are 0000 ), osxfs will try to add an access control list (ACL) entry that allows the user to read and write extended attributes. If this attempt fails, the object appears to belong to the process of accessing it until the extended attribute is read again.

In other words,

  • Inside the container, the osxfs driver pretends that everything that uid / gid works in the container is also the uid / gid to which the mounted files belong.

  • If you upload files (in the container) to something else, chown is not executed on real files; this owner information is stored in the extended file attribute, and this value is used by the container (and ignored by macOS).

  • Real files belong to those who own them on macOS, outside the container. Access control is determined using these real file owners and the uid / gid of the user running the Docker application (which is probably your Mac login user).

I use the container on my Mac as an example. I built this container, and here is part of its Docker file:

 FROM ubuntu:16.04 RUN useradd -d /planner -m planner WORKDIR /planner USER planner 

As you can see, this container works as a custom "scheduler". As is typical in Ubuntu, being the first user added to this new system, it has uid 1000 and gid 1000.

Outside, on my Mac, my uid and gid are also typical (501, 20), but not the same as the scheduler user in my container.

I run this container with the external directory installed, which contains my code. Therefore, I can restart the application during development without restoring the container (normal use case).

 version: '2' services: uwsgi: image: planner:latest build: ./uwsgi volumes: - ./uwsgi/planner:/planner 

If I look at the source directory ( ./uwsgi/planner ) on my Mac, the files belong to me (uid 501, gid 20).

 -rw-r--r-- 1 dan staff 3103 Oct 24 23:28 README.md drwxr-xr-x 4 dan staff 136 Sep 14 2016 doc -rwxr-xr-x 1 dan staff 260 Sep 14 2016 manage.py drwxr-xr-x 7 dan staff 238 Jan 11 00:00 site_planner drwxr-xr-x 4 dan staff 136 Jan 10 19:07 node_modules drwxr-xr-x 12 dan staff 408 Mar 30 12:30 planner -rw-r--r-- 1 dan staff 112 Oct 5 10:28 requirements.txt 

But looking at the mounted directory inside the container, you can see that while the paths, dates and sizes are the same, osxfs disguises the owner and tells the container’s operating system that these files actually belong to the “scheduler”. The actual username and uid are not important here. The osxfs driver simply uses what the current user is. If you have a user with uid 1005 named "joe", then this is what you will see.

 -rw-r--r-- 1 planner planner 3103 Oct 25 03:28 README.md drwxr-xr-x 4 planner planner 136 Sep 14 2016 doc -rwxr-xr-x 1 planner planner 260 Sep 14 2016 manage.py drwxr-xr-x 7 planner planner 238 Jan 11 05:00 site_planner drwxr-xr-x 4 planner planner 136 Jan 11 00:07 node_modules drwxr-xr-x 12 planner planner 408 Mar 30 16:30 planner -rw-r--r-- 1 planner planner 112 Oct 5 14:28 requirements.txt 

Now this is just the osxfs driver on Mac. And this is done in the name of simplicity - on the Mac you are probably developing, and the nuances of file permissions are just a pain you have to work with. Also note that you cannot execute this mode on your Mac without using sudo or another tool to elevate your privileges.

 $ chown 1000 manage.py chown: manage.py: Operation not permitted 

This is important because, in addition to vmnetd, all the Docker processes running on your Mac work as you, not as root. (This includes the osxfs process, as you can see in this screenshot.)

Activity monitoring showing docker processes

On a Linux server, it works more, as you expect it to work. For example, as part of the same service that I used in my example, I have a postgres container and it uses an external directory for its data store. On my Mac, this directory is full of files that belong to me (but the container thinks they belong to the user "postgres"). But, on the server, real uids are stored in an external file system.

 $ ls -ln pgdata total 120 drwx------. 6 999 999 4096 Oct 31 21:06 base drwx------. 2 999 999 4096 Mar 8 19:22 global drwx------. 2 999 999 4096 Oct 31 21:06 pg_clog drwx------. 2 999 999 4096 Oct 31 21:06 pg_commit_ts drwx------. 2 999 999 4096 Oct 31 21:06 pg_dynshmem drwx------. 4 999 999 4096 Oct 31 21:06 pg_logical drwx------. 4 999 999 4096 Oct 31 21:06 pg_multixact drwx------. 2 999 999 4096 Mar 8 19:22 pg_notify drwx------. 2 999 999 4096 Oct 31 21:06 pg_replslot drwx------. 2 999 999 4096 Oct 31 21:06 pg_serial drwx------. 2 999 999 4096 Oct 31 21:06 pg_snapshots drwx------. 2 999 999 4096 Mar 8 19:22 pg_stat drwx------. 2 999 999 4096 Apr 4 17:08 pg_stat_tmp drwx------. 2 999 999 4096 Mar 20 15:36 pg_subtrans drwx------. 2 999 999 4096 Oct 31 21:06 pg_tblspc drwx------. 2 999 999 4096 Oct 31 21:06 pg_twophase drwx------. 3 999 999 4096 Mar 17 18:30 pg_xlog -rw-------. 1 999 999 4 Oct 31 21:06 PG_VERSION -rw-------. 1 999 999 4496 Oct 31 21:06 pg_hba.conf -rw-------. 1 999 999 1636 Oct 31 21:06 pg_ident.conf -rw-------. 1 999 999 88 Oct 31 21:06 postgresql.auto.conf -rw-------. 1 999 999 22233 Oct 31 21:06 postgresql.conf -rw-------. 1 999 999 37 Mar 8 19:22 postmaster.opts -rw-------. 1 999 999 68 Mar 8 19:22 postmaster.pid 

Here the files belong to uid 999, gid 999. This is not my uid (it is 5046 on this particular server).

999 is the uid postgres inside the container, and it opens externally in file permissions here.

In other words, the problem you are facing depends on the Mac, and you should not have the same problem using Linux in the production process.

+10
source

What can I do to maintain ownership of the dockers?

why do you need it?

if you use a host mounted volume (via docker run , with -v $PWD:/my/app args, for example) in your container, it doesn’t matter what permissions are in the image itself.

You can edit files on your Mac, and the changes will be immediately reflected in the container.

that’s all I’ve ever done with my mac, and I never had problems editing files on my volume or the changes that are reflected in the container

-3
source

Source: https://habr.com/ru/post/1266078/


All Articles