2

I have an OpenSuse 42.3 docker container image that I created which has a single user, which we will call 'streamuser'. I would like this to be the user that is active whenever anyone creates a container from my image. I have mounted the host's home directory to the home directory of streamuser. The trouble that I'm having is that if I run the Docker container on a Linux host, streamusercan not write anything to the host directories. This is because streamuser does not share the same UID and GID as the host. Is there a clean way to resolve this issue that avoids me setting the default user account in the image to the root account? If I login as root in the container, then I can write to the linux host, but this is undesirable.

My docker call is:

docker run  -it -d --name ${containerName}  --user="streamuser"         \
    --workdir="/home/streamuser" --volume="${home}:/home/streamuser"    \
    ${imageName}  /bin/bash -rcfile /opt/Codebase/image_env_setup_v206.sh

I have seen a solution where someone used the --volume option as passed the host passwd, sudoers, etc files up to the container. I don't like this option because it overwrites my crafted environment within the container, and it seems like a ham-fisted solution.

My dockerfile is:

FROM opensuse:42.3

RUN zypper update -y && \
    zypper install -y \
    sudo \
    vim \
    gcc-fortran \
    infinipath-psm-devel \
    openmpi \
    openmpi-devel \
    openmpi-libs \
    hdf5-openmpi \
    blas-devel \
    blas-devel-static \
    lapack-devel \
    which

RUN echo "root:streamuser_2017" | chpasswd
RUN useradd -m streamuser
RUN passwd -d streamuser
CMD /bin/bash

RUN mkdir -p -m0755 \
    /opt/codeA/lib \
    /opt/codeA/bin \
    /opt/codeB/lib \
    /opt/codeC/lib \
    /opt/codeC/bin \
    /opt/petsc/lib

USER streamuser
WORKDIR /home/streamuser

RUN source $HOME/.bashrc

COPY ./Docker/critical_dependencies/codeA_lib/* /opt/codeA/lib/
COPY ./Docker/critical_dependencies/codeA_bin/* /opt/codeA/bin/
COPY ./Docker/critical_dependencies/codeB_lib/* /opt/codeB/lib/
COPY ./Docker/critical_dependencies/petsc_lib/* /opt/petsc/lib/
COPY ./lib/* /opt/codeC/lib/
COPY ./bin/* /opt/codeC/bin/
COPY ./Docker/image_env_setup_v206.sh /opt/codeC

RUN source /opt/codeC/image_env_setup_v206.sh
wandadars
  • 1,113
  • 4
  • 19
  • 37
  • How about changing the Gid of streamuser inside the container to belong it to root group inside container? – Ayushya Aug 05 '17 at 05:56
  • @Ayushya I had thought about doing that, but I believe it is generally a frowned upon to add users to the root group. – wandadars Aug 05 '17 at 06:03
  • 1
    True, I proposed this solution, but even I agree with "user should not be added to root group" – Ayushya Aug 05 '17 at 06:06

1 Answers1

5

You could add fixuid (by Caleb Lloyd) in your Dockerfile image.
See moby/moby issue 7198:

We have created a workaround for this issue that changes a Docker container's user/group and file permissions that were set at build time to the UID/GID that the container was started with at runtime.

The project and install instructions are at: https://github.com/boxboat/fixuid

Example:

  • Docker container was built using user/group dockeruser:dockergroup as UID/GID 1000:1000.
  • Host is running as UID/GID 1001:1002.
  • Image is run with docker run -u 1001:1002.

fixuid will:

  • change dockeruser UID to 1001
  • change dockergroup GID to 1002
  • change all file permissions for old dockeruser:dockergroup to 1001:1002
  • update $HOME inside container to dockeruser $HOME
  • now container and host UID/GID match and files created in the container on host mounts will match.

It can run as the ENTRYPOINT or as part of a startup script. It is installed in the container as a binary owned by root with the setuid bit, and escalates privileges to make the appropriate changes. It should only be used in development containers.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • This looks like a good solution.Step 2 of the instructions in the Github repo is failing for me with the error: tar: fixuid: Cannot open: Permission denied tar: Exiting with failure status due to previous errors. In the instructions for Step 2 it says that the command must be run as root, but I'm not really sure how I can guarantee that that particular command is going to be run as root within my Dockerfile. – wandadars Aug 05 '17 at 07:27
  • 1
    @wandadars it can, if you add USER root just before the RUN – VonC Aug 05 '17 at 07:30
  • this would be marvelous if it would work. Unfortunately in my case it changes nothing with the message `fixuid: already ran on this system; will not attempt to change UID/GID` :( – KansaiRobot Oct 12 '20 at 06:48
  • @KansaiRobot Is that during docker build? Are you using a base image which used `fixuid` (https://boxboat.com/2017/07/25/fixuid-change-docker-container-uid-gid/)? – VonC Oct 12 '20 at 09:53