More on running containers
If you have not done so already, let’s pull the latest Ubuntu container from Docker:
# cd ~/tmp
module load singularity
# salloc --cpus-per-task=1 --time=3:00:0 --mem-per-cpu=3600
singularity pull ubuntu.sif docker://ubuntu
We already saw some of these commands:
singularity shell ubuntu.sif
launches the container and opens an interactive shell inside itsingularity exec ubuntu.sif <command>
launches the container and runs a command inside itsingularity run ubuntu.sif
launches the container and executes the default runscript
Singularity matches users between the container and the host. For example, if you run a container that needs to be root, you also need to be root outside the container.
Running a single command
singularity exec ubuntu.sif ls /
singularity exec ubuntu.sif ls /; whoami
singularity exec ubuntu.sif bash -c "ls /; whoami" # probably a safer way
singularity exec ubuntu.sif cat /etc/os-release
Running a default script
We’ve already done this! If there is no default script, Singularity will give you the shell to type in your commands.
Starting a shell
We’ve already done this!
$ singularity shell ubuntu.sif
Singularity> whoami # same username as in the host system
Singularity> groups # same groups as on the host system
At startup Singularity simply copied the relevant user and group lines from the host system to files
/etc/passwd
and /etc/group
inside the container. Why do this? The container must ensure that you cannot
modify anything on the host system that you should not have permission to, i.e. you are restricted to the same
user permissions within the container as you are on the host system.
Mounting external directories and copying environment
By default, Singularity containers are read-only, so you cannot write into its directories. However, from inside the container you can organize read-write access to your directories on the host filesystem. The command
singularity shell -B /home,/project,/scratch ubuntu.sif
will bind-mount /home,/project,/scratch
inside the container so that these directories can be accessed for
both read and write, subject to your account’s permissions, and then will run a shell. Inside the container:
pwd # most likely your working directory
echo $USER
ls /home/$USER
ls /scratch/$USER
ls /project/def-sponsor00/$USER
You can mount host directories to specific paths inside the container, e.g.
singularity shell -B /project/def-sponsor00/${USER}:/project,$SCRATCH:/scratch ubuntu.sif
ls /project
ls /scratch
Note that by default Singularity typically mounts some of the host’s directories. The flag -C
will hide the
host’s filesystems and environment variables, but then you need to explicitly bind-mount the needed paths (to
store results), e.g.
singularity shell -C -B /scratch ubuntu.sif # inside see only /scratch
You can disable specific mounts, e.g. the following will start the container without a home directory:
singularity shell --no-mount home ubuntu.sif
cd # no such file or directory
Alternatively, you can disable mounting /home
with the --no-home
flag. And you can disable multiple mounts
with something like --no-mount tmp,sys,dev
.
In general, without -C
, Singularity inherits all environment variables from the build/pull time. You can add
the -e
flag to remove only the host’s environment variables from your container, to start in a cleaner
environment:
$ singularity shell -e -B /home,/project,/scratch ubuntu.sif
Singularity> echo $USER
Singularity> $(whoami)
On the other hand, you can pass variables environment variables to your container by prefixing their names:
$ SINGULARITYENV_HI=hello singularity shell mpi.sif
Singularity> echo $HI
hello
Finally, you don’t have to pass the same bind (-B
) flags every time – instead you can put them into a
variable (that can be stored in your ~/.bashrc
file):
export SINGULARITY_BIND="/home,/project/def-sponsor00/${USER}:/project,/scratch/${USER}:/scratch"
singularity shell ubuntu.sif
You can have more granular control (e.g. specifying read only) with the --mount
flag – for details see the
official
Bind Paths and Mounts documentation.
Key points
- Your current directory and home directory are usually available by default in a container.
- You have the same username and permissions in a container as on the host system.
- You can specify additional host system directories to be available in the container.
- It is a very good idea to use
-C
to hide the host’s filesystems while mounting only few specific directories.