Using sagemath with docker/podman

docker
podman
sage
Author

Emmanuel Jeandel

Published

March 4, 2024

Sage is typically the kind of program that should be executed in a container, as it requires a lot of libraries with very precise versions, and you might not use most of them for other purposes.

Here is how to use Sage with docker or podman. The use case is as follows: you don’t want to be root to execute the commands. (If you use docker, you will still need to be in the docker group or something)

Docker

Assuming you’re in the docker group, you can install sage with the command

docker pull sagemath/sagemath

You can then run sage with one of the following commands (sage or jupyter)

docker run -it sagemath
docker run -p 8888:8888 sagemath/sagemath sage-jupyter

(add -it to the last command if you want to be able to quit it from the command line)

Now suppose you want to share the directory my_directory with sage/jupyter.

You can do it this way:

docker run -p 8888:8888 -v my_directory:/home/sage/notebooks sagemath/sagemath sage-jupyter

Podman

podman is my preferred solution, because it doesn’t require you to be root.

The first commands are almost identical:

podman pull docker.io/sagemath/sagemath
podman run -it sagemath
podman run -p 8888:8888 sagemath sage-jupyter

The difficulty is how to share a directory.

The obvious solution would be:

podman run -it -p 8888:8888  --userns=keep-id -v my_directory:/home/sage/notebooks:Z sagemath sage-jupyter

but it doesn’t work with the default storage driver. The --userns=keep-id option requires essentially podman to do a chmod -R on the whole volume. However, with the overlay driver, podman can’t do it efficiently and instead needs to copy all of the files again. It takes a thousand of minutes.

There are two solutions.

First solution

The first solution is to change the storage driver to use fuse-overlayfs. You can do it globally, by changing the file ~/.config/containers/storage.conf:

[storage]
  driver = "overlay"
[storage.options.overlay]  
  mount_program=  "/usr/bin/fuse-overlayfs"

and then the previous command works:

podman run -it -p 8888:8888  --userns=keep-id -v my_directory:/home/sage/notebooks:Z sagemath sage-jupyter

However, this means using fuse-overlayfs for all images and not only for sage. Another solution is to specify it on the command line:

podman run -it -p 8888:8888  --storage-opt overlay.mount_program=/usr/bin/fuse-overlayfs --userns=keep-id -v my_directory:/home/sage/notebooks:Z sagemath sage-jupyter

Second solution

A different solution is to be root inside the container, instead of user 200:

podman run -it -p8888:8888  --user 0 -v /home/ejeandel/sage:/home/sage/notebooks:Z sagemath sage-jupyter --allow-root

Being root inside the container is not always the best, but I don’t think it’s aproblem for this specific use.