Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker images and permissions problems for /devel #464

Closed
KrisThielemans opened this issue Jan 1, 2021 · 16 comments · Fixed by #545
Closed

docker images and permissions problems for /devel #464

KrisThielemans opened this issue Jan 1, 2021 · 16 comments · Fixed by #545
Milestone

Comments

@KrisThielemans
Copy link
Member

I've tried to get Docker going inside the VM (see also #462). The jupyter notebook server was running fine. However, SIRF-exercises was not in /devel. This looks like a permission problem:

$ docker start -ai sirf
/opt/SIRF-SuperBuild ~
/devel /opt/SIRF-SuperBuild ~
cp: cannot create directory './SIRF-Exercises': Permission denied
/usr/bin/unzip
/usr/local/bin/service.sh: line 49: ./SIRF-Exercises/scripts/download_*.sh: No such file or directory
/opt/SIRF-SuperBuild ~
~
[I 11:35:40.868 NotebookApp] JupyterLab beta preview extension loaded from /opt/pyvenv/lib/python2.7/site-packages/jupyterlab
[I 11:35:40.869 NotebookApp] JupyterLab application directory is /opt/pyvenv/share/jupyter/lab
[I 11:35:40.872 NotebookApp] Serving notebooks from local directory: /devel
[I 11:35:40.872 NotebookApp] The Jupyter Notebook is running at:
[I 11:35:40.872 NotebookApp] http://(0e8f0467d1c4 or 127.0.0.1):8888/
[I 11:35:40.872 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

I ran ./sirf-compose-service as recommended.

@casperdcl
Copy link
Member

casperdcl commented Jan 3, 2021

as mentioned in #462 (comment) and

[ -d SIRF-Exercises ] || cp -a $SIRF_PATH/../../../SIRF-Exercises .
which unzip || sudo apt-get install -yqq unzip
for i in SIRF-Exercises/scripts/download_*.sh; do ./$i $PWD; done
it'll try to download & unzip data for SIRF-Exercises. The error maybe is due to (on the host machine) SIRF-SuperBuild/docker/devel/SIRF-Exercises existing already but not as a directory?

Maybe need [ -e SIRF-Exercises ] instead of -d?

@casperdcl casperdcl added the bug label Jan 3, 2021
@KrisThielemans
Copy link
Member Author

KrisThielemans commented Jan 3, 2021 via email

@casperdcl
Copy link
Member

is devel writable by the same UID as picked up by docker-compose?

@KrisThielemans KrisThielemans added this to the v3.0 milestone Apr 15, 2021
@KrisThielemans
Copy link
Member Author

assigning it to 3.0 although that might be too ambitious

@KrisThielemans
Copy link
Member Author

This worked fine on Travis, so maybe it's my local set-up, so I'll close this

@KrisThielemans
Copy link
Member Author

KrisThielemans commented May 12, 2021

@casperdcl, @paskino and I looked at this in a bit more detail. Paskino and I saw that from in docker, /devel was owned by 1001:1001. So it cannot write to it. Changing ownership to sirfuser:sirfuser resolved that problem.

Our current impression is that this only happens if we build a new image ourselves (in the VM), while it's fine in the image built in Travis.

Any idea how we can make sure that the permission is ok? As it's mounted in the yml files, presumably it's there that we have to fix it?

@KrisThielemans
Copy link
Member Author

I discover that on the VM, sirfuser is 1001:1001, while in the docker image it is 1000:1000 which will explain the mismatch. I guess this Stackoverflow message will be relevant https://stackoverflow.com/questions/40462189/docker-compose-set-user-and-group-on-mounted-volume. However, people don't quite seem to agree on a good solution there.

@casperdcl
Copy link
Member

If you build from scratch (rather than resuming from an existing/pulled image) in an env where GROUPS and UID are defined then it should be picked up automatically

GROUP_ID: ${GROUPS:-1000}
USER_ID: ${UID:-1000}

@KrisThielemans
Copy link
Member Author

aha. So are you saying that when we build from scratch, we should set USER_ID to the userid of the current user? I presume that will then make sure that the uid for host and docker user are the same, so the problem disappears.

How come this is not necessary from a "pulled" image then? I suppose docker does some smart stuff with the pull then. (Also not sure why that'd work on a Windows host, but fine).

Somehow I'd prefer a solution where we fix this in the container (one option would be to add it to the entrypoint.sh or wherever we do the copying of the data) but maybe that's not reliable enough.

@casperdcl
Copy link
Member

casperdcl commented May 12, 2021

aha. So are you saying that when we build from scratch, we should set USER_ID to the userid of the current user? I presume that will then make sure that the uid for host and docker user are the same, so the problem disappears.

yes

How come this is not necessary from a "pulled" image then?
Somehow I'd prefer a solution where we fix this in the container (one option would be to add it to the entrypoint.sh or wherever we do the copying of the data) but maybe that's not reliable enough.

Entrypoint does indeed set perms

echo "$UID:$GID Creating and switching to: $mainUser:$USER_ID:$GROUP_ID"

but it would need again need GROUPS & UID to be correctly propagated. 1000:1000 is typically the default on most Linux installs but not a guarantee.

Also not sure why that'd work on a Windows host, but fine.

Windows basically ignores file ownership

@KrisThielemans
Copy link
Member Author

thanks!

still a bit confused. without matching the UID:GID, everything worked fine as long as I did (in the container)

chown -R sirfuser:sirfuser /devel

@KrisThielemans KrisThielemans changed the title docker service image does not create SIRF-exercises self-built docker images cannot write to /devel May 12, 2021
@paskino
Copy link
Contributor

paskino commented May 13, 2021

If you build from scratch (rather than resuming from an existing/pulled image) in an env where GROUPS and UID are defined then it should be picked up automatically

GROUP_ID: ${GROUPS:-1000}
USER_ID: ${UID:-1000}

Are GROUPS and UID environment variables? How would we set them?

@KrisThielemans
Copy link
Member Author

yes they are. for instance

GROUPS=1001 USER_ID=1001 ./sirf-docker-compose bla bla

@casperdcl
Copy link
Member

GROUPS=1001 UID=1001 ./sirf-docker-compose bla bla

Not GROUP_ID/GID/USER_ID (because on most Linux systems, GROUPS and UID are probably already set).

@KrisThielemans
Copy link
Member Author

Needs extra doc somewhere, but we can postpone that for later.

@KrisThielemans KrisThielemans modified the milestones: v3.0, v3.1 May 16, 2021
@KrisThielemans KrisThielemans changed the title self-built docker images cannot write to /devel docker images and permissions problems for /devel May 21, 2021
@KrisThielemans
Copy link
Member Author

I continue to have problems with this, now with a pulled service image, and have now changed the title of the issue to reflect the wider problem. As often, I misunderstood @casperdcl recommendation as I thought it was only necessary for a self-built image, but that wasn't the case. However

Doing what @casperdcl recommends fails:

GROUPS=1001 UID=1001 ./sirf-compose-server run --rm sirf /bin/bash -c 'id'
bash: UID: readonly variable
0: Creating and switching to: sirfuser:1000:1000
uid=1000(sirfuser) gid=1000(sirfuser) groups=1000(sirfuser)

I can get further with the following by exporting UID, but cannot get the gid to work:

export UID
GROUPS=1001  ./sirf-compose-server run --rm sirf /bin/bash -c 'id; env'
0: Creating and switching to: sirfuser:1001:1000
uid=1001(sirfuser) gid=1000(sirfuser) groups=1000(sirfuser)
LANG=en_GB.UTF-8
DISPLAY=:0
HOSTNAME=62556a6d6dbc
OLDPWD=/
GADGETRON_RELAY_HOST=0.0.0.0
GROUP_ID=1000
PWD=/home/sirfuser
HOME=/home/sirfuser
USER_ID=1001
DEBIAN_FRONTEND=
mainUser=sirfuser
TERM=xterm
SHLVL=1
LANGUAGE=en_GB:en
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

where you can see that GROUP_ID isn't set. export GROUPS doesn't help. I can only get this to work if either I edit docker-compose.yml and hard-wire the number, i.e. change

GROUP_ID: ${GROUPS:-1000}
USER_ID: ${UID:-1000}

to

   GROUP_ID: 1001
   USER_ID: ${UID:-1000}

or I use a different variable name, e.g.

   GROUP_ID: ${GID:-1000}

and then do GID=${GROUPS} ./sirf-compose-devel ....

The only reason for this behaviour that I can see is that the GROUPS bash variable is special and somehow bash doesn't pass it to a forked/spawned/whatever process.

Background reading

Here's my current understanding on all this after reading up a bit, e.g. from https://blog.gougousis.net/file-permissions-the-painful-side-of-docker/.

To quote from that website on the "source of all evil":

Let me remind you here that file permissions on bind mounts are shared between the host and the containers...Whenever we create a file on host using a user with UID x, this file will have x as owner UID inside the container.

(Note that this is for Linux. On Mac, Docker uses NFS and apparently this doesn't give UID problems, and according to @casperdcl, neither are there problems on Windows).

On the VM, there are 2 users: vagrant (uid 1000) and sirfuser (uid 1001). We log-in as sirfuser. Using sirf-compose-server starts up the container with container-uid 1000. Therefore, the container-user cannot write to /devel.

On the container, entrypoint.sh creates a user (sirfuser) with UID/GID set from (container) env variables GROUP_ID and USER_ID if they are set:

USER_ID=${USER_ID:-1000}
GROUP_ID=${GROUP_ID:-1000}
mainUser=${mainUser:-sirfuser}

echo "$UID:$GID Creating and switching to: $mainUser:$USER_ID:$GROUP_ID"
# groupadd -g $GROUP_ID -o -f $mainUser
addgroup --quiet --system --gid "$GROUP_ID" "$mainUser"
# useradd --shell /bin/bash -u $USER_ID -o -c "" -M -d $HOME \
# -g $mainUser -G sudo $mainUser \
# -p $(echo somepassword | openssl passwd -1 -stdin)
adduser --quiet --system --shell /bin/bash \
--no-create-home --home /home/"$mainUser" \
--ingroup "$mainUser" --uid "$USER_ID" "$mainUser"
with ownership of files in
/opt and $HOME set
for i in /opt/* "$HOME"; do
if [ -d "$i" ]; then
chown -R $mainUser "$i"
chgrp -R $mainUser "$i"
fi
done

Those 2 container variables are (or should be) set from GROUPS and UID when using sirf-compose*

GROUP_ID: ${GROUPS:-1000}
USER_ID: ${UID:-1000}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants