Using containers for Python environments can greatly simplify dependency management and ensure reproducibility. Containers encapsulate all dependencies, libraries, and configurations needed to run your Python code, making it easier to share and deploy across different systems.
In this guide, we will explore how to create and manage Python environments using containers, specifically focusing on tools like Apptainer / Singularity.
Getting Started
To get started with containers for Python environments, you will need to have a containerization tool installed. Apptainer (formerly Singularity) is a popular choice for scientific computing environments. (You can install Apptainer on your system by following the official installation guide: Apptainer Installation) On IMGW servers, VSC and ECMWF this is already installed. If the runtime is not directly available, you can use the module load apptainer command to load it.
Once the container is build, you can run it with the following command:
Bash
12345678
apptainerrunmy_container.sif
# or
./my_container.sif
# or running a command inside the container
apptainerexecmy_container.sif<command>
# or
./my_container.sif<command>
The container will automatically use the local directory and bind it to the container, so you can access your files inside the container. If you need to access non-standard directories, you can set the SINGULARITY_BIND environment variable to include those directories. For example:
Bash
123456
# using the container with access to /srvfs, /jetfs, and /gpfsexportSINGULARITY_BIND="/srvfs,/jetfs,/gpfs"
./my_container.sifpython3my_script.py/jetfs/my_data/input.txt
# or using the apptainer command directly
apptainerrun--bind/srvfs,/jetfs,/gpfsmy_container.sifpython3my_script.py/jetfs/my_data/input.txt
Example: Creating a Python Environment with Apptainer
There is a tool micromamba2container.sh available here that can help you create a container with a specific Python environment. This script uses Micromamba to create a lightweight container with the desired Python version and packages.
You can create a new container from an existing micromamba environment by specifying the environment name with the -n option:
Bash
1 2 3 4 5 6 7 8 91011
# Check your environements
micromambaenvlist
NameActivePath
──────────────────────────────────────────────────────────────────────
base*/home/user/micromambaansible/home/user/micromamba/envs/ansiblejupyterhub/home/user/micromamba/envs/jupyterhubmyenv/home/user/micromamba/envs/myenv
# Create the container for the myenv environment
./micromamba2container.sh-cmy_container-nmyenv
This will create a new container 'my_container' from the existing micromamba environment 'myenv'. Existing environments are easy, because micromamba already has all the information about the packages and dependencies in that environment, so it can directly export them into the container.
Integration into Jupyterhub
In order to use the container in Jupyterhub, you can specify the path to the container in the jupyter configuration. the only dependency is that the container has the ipykernel package installed.
Bash
12345
# Add the container to Jupyterhub# Create the configuration file for the container
./my_container.sifpython3-mipykernelinstall--user--nameMYENV--display-name"My(3.13)"
Runningwitharguments:python3-mipykernelinstall--user--nameMYENV--display-nameMy(3.13)
InstalledkernelspecMYENVin/home/user/.local/share/jupyter/kernels/myenv
This is great, but of course the runtime needs to be added. So open that file:
This ensures, that the container is launched with the correct environment and that the necessary directories are bound to the container. Make sure to use the absolute path for your container file. You can now select the kernel "My(3.13)" in Jupyterhub and it will run your code inside the container with the specified Python environment.