Docker and –userns-remap, how to manage volume permissions to share data between host and container?

If you can prearrange users and groups in advance, then it’s possible to assign UIDs and GIDs in such specific way so that host users correspond to namespaced users inside containers.

Here’s an example (Ubuntu 14.04, Docker 1.10):

  1. Create some users with fixed numeric IDs:

    useradd -u 5000 ns1
    
    groupadd -g 500000 ns1-root
    groupadd -g 501000 ns1-user1
    
    useradd -u 500000 -g ns1-root ns1-root
    useradd -u 501000 -g ns1-user1 ns1-user1 -m
    
  2. Manually edit auto-generated subordinate ID ranges in /etc/subuid and /etc/subgid files:

    ns1:500000:65536
    

    (note there are no records for ns1-root and ns1-user1 due to MAX_UID and MAX_GID limits in /etc/login.defs)

  3. Enable user namespaces in /etc/default/docker:

    DOCKER_OPTS="--userns-remap=ns1"
    

    Restart daemon service docker restart, ensure /var/lib/docker/500000.500000 directory is created.

    Now, inside containers you have root and user1, and on the host — ns1-root and ns1-user1, with matching IDs

    UPDATE: to guarantee that non-root users have fixed IDs in containers (e.g. user1 1000:1000), create them explicitly during image build.

Test-drive:

  1. Prepare a volume directory

    mkdir /vol1
    chown ns1-root:ns1-root /vol1
    
  2. Try it from a container

    docker run --rm -ti -v /vol1:/vol1 busybox sh
    echo "Hello from container" > /vol1/file
    exit
    
  3. Try from the host

    passwd ns1-root
    login ns1-root
    cat /vol1/file
    echo "can write" >> /vol1/file
    

Not portable and looks like a hack, but works.

Leave a Comment