5

When I run singularity exec foo.simg whoami I get my own username from the host, unlike in Docker where I would get root or the user specified by the container.

If I look at /etc/passwd inside this Singularity container, an entry has been added to /etc/passwd for my host user ID.

How can I make a portable Singularity container if I don't know the user ID that programs will be run as?

I have converted a Docker container to a Singularity image, but it expects to run as a particular user ID it defines, and several directories have been chown'd to that user. When I run it under Singularity, my host user does not have access to those directories.

It would be a hack but I could modify the image to chmod 777 all of those directories. Is there a better way to make this image work on Singularity as any user?

(I'm running Singularity 2.5.2.)

rgov
  • 3,516
  • 1
  • 31
  • 51
  • Singularity does understand `SINGULARITY_TARGET_UID=999 SINGULARITY_TARGET_GID=999` as environment variables, but it only allows them when running as root (on the host). – rgov Apr 10 '20 at 15:34

2 Answers2

3

First, upgrade to the v3 of Singularity if at all possible (and/or bug your cluster admins to do it). The v2 is no longer supported and several versions <2.6.1 have security issues.

Singularity is actually mounting the host system's /etc/passwd into the container so that it can be run by any arbitrary user. Unfortunately, this also effectively clobbers any users that may have been created by a Dockerfile. The solution is as you thought, to chmod any files and directories to be readable by all. chmod -R o+rX /path/to/base/dir in a %post step is simplest.

Since the final image is read-only, allowing write permission doesn't do anything and it's useful to get into the mindset about only writing to files/directories that have been mounted to the image.

tsnowlan
  • 3,472
  • 10
  • 15
3

There is actually a better approach than just chmod 777, which is to create a "vanilla" folder with your application data/conf in the image, and then copy it over to a target directory within the container, at runtime.

Since the copy will be carried out by the user actually running the container, you will not have any permission issues when working within the target directory.

You can have a look at what I done here to create a portable remote desktop service, for example: https://github.com/sarusso/Containers/blob/c30bd32/MinimalMetaDesktop/files/entrypoint.sh

This approach is compatible with both Docker and Singularity, but it depends on your use-case if it is a viable solution or not. Most notably, it requires you to run the Singularity container with --writable-tmpfs.

As a general comment, keep in mind that even if Singularity is very powerful, it behaves more as an environment than a container engine. You can make it work more container-like using some specific options (in particular --writable-tmpfs --containall --cleanenv --pid), but it will still have limitations (variable usernames and user ids will not go away).

sarusso
  • 654
  • 5
  • 10
  • p.s. The "tmpfs" filesystem is stored in RAM and usually defaulted to 16MB by sysadmins, if you need more space you can consider persistent overlays instead: https://sylabs.io/guides/3.5/user-guide/persistent_overlays.html – sarusso May 18 '20 at 15:25