Running MoCSI with Docker

Docker runs a prebuilt MoCSI image without compiling anything locally. The same image runs identically on Linux, macOS, and Windows. The MoCSI image contains both executables, compiled with VTK (shape-model input) and CSPICE (ephemeris geometry):

  • mocsi — serial

  • mocsi_mpi — parallel (MPI)

How a containerized run is structured

  • Image — the prebuilt, read-only package (e.g. mocsi:2.0.0). Built or pulled once; it persists on disk.

  • Container — one execution of the image. It starts, runs the command you give it, and exits.

  • Filesystem isolation — the container has its own filesystem and cannot see host files by default. A host directory becomes visible inside the container only if it is mounted with -v HOST_PATH:CONTAINER_PATH. MoCSI reads its config and writes its output through this mount. Without it, the input file is not found and any output is lost when the container exits.

Every command below has the same structure:

docker run [options] <image> <command-run-inside>

1. Install Docker

sudo apt-get update && sudo apt-get install -y docker.io
sudo systemctl enable --now docker

To run docker without sudo, add your user to the docker group once, then log out and back in:

sudo usermod -aG docker "$USER"

Install Docker Desktop from https://www.docker.com/products/docker-desktop/ and start it (the whale icon in the menu bar must be running).

Install Docker Desktop from https://www.docker.com/products/docker-desktop/ and start it. Run the commands below in PowerShell, where ${PWD} expands to the current directory. In the legacy cmd prompt, use %cd% instead.

Verify the installation:

docker run --rm hello-world

A “Hello from Docker!” message confirms the daemon is running.

2. Obtain the image

There are two ways to get the image: pull a published release from the registry (no compilation), or build it from source.

Option A — pull from the container registry

Published release images live in the project’s GitLab container registry and are tagged with the git release tag (v2.0.0, v2.1.0, …). A registry image is produced only for major and minor releases (tags of the form vX.Y.0); patch releases (vX.Y.Z with Z > 0) do not get their own image and continue to use the most recent vX.Y.0 image. There is no latest tag and no per-commit image.

docker pull registry.git.nrw/uni-ms/ag-gundlach/public/mocsi:v2.0.0

The registry path (registry.git.nrw/uni-ms/ag-gundlach/public/mocsi) is part of the image name, separate from any local name. If the pull is denied, authenticate first with a GitLab access token that has read_registry scope:

docker login registry.git.nrw

The pulled name is long, so the remaining commands on this page use a short local alias. Create it once with docker tag:

docker tag registry.git.nrw/uni-ms/ag-gundlach/public/mocsi:v2.0.0 mocsi:2.0.0

After this, mocsi:2.0.0 refers to the pulled image.

Note

The v2.0.0 registry image exists only after the v2.0.0 release is published. Until then, use Option B.

Option B — build from source

Run from the MoCSI source root, which contains the Dockerfile:

git clone https://gitlab.git.nrw/uni-ms/ag-gundlach/public/mocsi.git
cd mocsi
docker build -t mocsi:2.0.0 .

The -t mocsi:2.0.0 assigns a local name and tag to the resulting image; this name is your own choice and is independent of the registry path above. The first build compiles MoCSI inside the container (serial + MPI, with VTK + CSPICE) and takes roughly 10–30 minutes depending on the machine. It runs once; the image then stays on disk. List local images with:

docker images

3. Set up a run directory

Do not run MoCSI from inside the cloned source tree. The repository’s configs/ directory holds the shipped example configurations — the default .ini files the project ships with. If you mount the source checkout and run from it, MoCSI reads those defaults directly and writes its output back into the checkout, modifying files that are meant to stay unchanged.

Instead, make a separate directory for each run and copy one example into it. The examples live under configs/config_examples/ in the source tree. Each one is self-contained: a directory with an ini_files/ subdirectory holding a default.ini, the example’s main .ini, and the module .ini files.

mkdir -p ~/mocsi_runs/seb_top
cp -r /path/to/mocsi/configs/config_examples/seb_top_const_flux_bottom_1d/. ~/mocsi_runs/seb_top/
cd ~/mocsi_runs/seb_top
New-Item -ItemType Directory -Force D:\TPM\runs\seb_top
Copy-Item -Recurse D:\TPM\mocsi\configs\config_examples\seb_top_const_flux_bottom_1d\* D:\TPM\runs\seb_top\
cd D:\TPM\runs\seb_top

Edit the copied .ini files in this directory as needed. The run (next steps) mounts this directory — not the source tree — at /work, so all edits and outputs stay here and the source checkout is untouched.

Important

MoCSI expects the ini_files/ subdirectory to sit directly in the working directory: it always reads ini_files/default.ini (relative to where it runs), and the -i argument is resolved relative to ini_files/, so you pass only the bare file name — -i seb_top_const_flux_bottom_1d.ini loads ini_files/seb_top_const_flux_bottom_1d.ini. Copying a complete config_examples/<name>/ directory as above already produces the expected ini_files/ layout at the run-directory root. Do not prefix the -i value with ini_files/; that would resolve to ini_files/ini_files/… and fail.

4. Mount the run directory

The container reads inputs and writes outputs through the mounted run directory:

-v "$PWD":/work

This mounts the current host directory ($PWD, i.e. the run directory from Step 3) at /work inside the container. /work is the container’s working directory, so paths in the .ini files are resolved relative to it. Keep all inputs the run needs — the main .ini, ini_files/, shape model, SPICE kernels — under this directory and reference them with relative paths (or paths under /work). Output files are written into the same host directory and remain after the container exits.

Notes:

  • MoCSI always runs with /work as its working directory (set as WORKDIR in the image), independent of the host shell or the mount flag. The only requirement is that the directory mounted at /work contains an ini_files/ subdirectory; how that directory got there does not matter.

  • $PWD is only a convenience for “the directory I am currently in” — it is not a restriction. A different host directory can be mounted by giving its absolute path instead, e.g. -v /data/ryugu_run:/work, without cd-ing into it first.

  • -v HOST:/work and --mount type=bind,src=HOST,dst=/work are equivalent bind mounts. --mount only spells out each field, which is why it sidesteps the PowerShell quoting issue on Windows (Step 5); it does not change where or how MoCSI runs.

  • Several directories can be mounted at once by repeating -v, e.g. adding -v /shared/spice_kernels:/kernels and pointing the config at /kernels.

  • Append :ro to mount read-only, e.g. -v /shared/spice_kernels:/kernels:ro.

Windows: sharing drives with Docker Desktop

On Windows, the host directory must be on a drive that Docker Desktop is allowed to mount. The behavior depends on the backend:

  • WSL 2 backend (default). Paths inside your WSL distribution or under your Windows user profile are shared automatically. The fastest and most reliable option is to keep the run directory inside the WSL filesystem (e.g. \\wsl$\Ubuntu\home\you\run) and run the docker commands from a WSL shell, where -v "$PWD":/work works as on Linux.

  • Hyper-V backend. Enable sharing explicitly: Docker Desktop → Settings → Resources → File sharing, add the drive or folder (e.g. C:), and apply.

Path format in the -v flag:

  • In PowerShell, -v "${PWD}:/work" mounts the current directory.

  • An absolute Windows path is given with forward slashes and the drive letter lower-case, e.g. -v /c/Users/you/run:/work (equivalently -v //c/Users/you/run:/work in some shells).

  • A “drive is not shared” or “path not found” error from docker run means the drive has not been shared in Docker Desktop settings.

5. Serial run

Run from the run directory (Step 3). The -i argument is the bare file name of the config inside ini_files/ (see the note in Step 3):

docker run --rm -v "$PWD":/work mocsi:2.0.0 mocsi -i seb_top_const_flux_bottom_1d.ini

Use the explicit --mount form. It names each field, so it is not affected by PowerShell quoting:

docker run --rm --mount type=bind,src=${PWD},dst=/work mocsi:2.0.0 mocsi -i seb_top_const_flux_bottom_1d.ini

The shorter -v form also works, but the whole spec must be in one pair of quotes, "${PWD}:/work". Writing it the Linux way ("$PWD":/work, quotes around the variable only) makes Docker fail with invalid reference format, because the expanded drive-letter path then collides with the colon separators.

docker run --rm -v "${PWD}:/work" mocsi:2.0.0 mocsi -i seb_top_const_flux_bottom_1d.ini

Part

Meaning

docker run

start a container

--rm

remove the container after it exits

-v "$PWD":/work

mount the run directory at /work

mocsi:2.0.0

the image to run

mocsi -i seb_top_const_flux_bottom_1d.ini

the command executed inside the container (-i is resolved under ini_files/)

6. Parallel run (MPI)

docker run --rm -v "$PWD":/work mocsi:2.0.0 \
    mpirun --allow-run-as-root -np 4 mocsi_mpi -i seb_top_const_flux_bottom_1d.ini
docker run --rm --mount type=bind,src=${PWD},dst=/work mocsi:2.0.0 mpirun --allow-run-as-root -np 4 mocsi_mpi -i seb_top_const_flux_bottom_1d.ini
  • -np 4 sets the number of MPI ranks. Do not exceed the number of available cores unless you add --oversubscribe.

  • --allow-run-as-root is required because the container runs as the root user, and Open MPI refuses to run as root without it.

7. Interactive shell

To run several commands or inspect the container:

docker run --rm -it -v "$PWD":/work mocsi:2.0.0 bash

-it allocates an interactive terminal. Inside, run mocsi -i seb_top_const_flux_bottom_1d.ini, ls, etc. Exit with exit. To confirm both binaries are present:

which mocsi mocsi_mpi

8. Running with no command

docker run --rm mocsi:2.0.0

prints a short usage banner and exits. MoCSI requires an input config, so there is no default simulation; this is expected behavior, not an error.

9. Distributing the image without a registry

The image can be transferred as a tarball:

docker save mocsi:2.0.0 | gzip > mocsi-2.0.0-docker.tar.gz   # export
docker load < mocsi-2.0.0-docker.tar.gz                      # import on another machine

Troubleshooting

Symptom

Cause and fix

Cannot connect to the Docker daemon

The daemon is not running (start Docker Desktop), or on Linux the command needs sudo or membership in the docker group (Step 1).

docker: invalid reference format

Windows/PowerShell quoting of the -v mount. Use a single quoted spec "${PWD}:/work", or the --mount type=bind,src=${PWD},dst=/work form (Step 5).

... .ini: No such file or directory or ini_files/default.ini not found

The run directory mounted at /work does not contain an ini_files/ subdirectory, or the -i value was prefixed with ini_files/. Pass the bare file name and mount a directory that has ini_files/ at its root (Steps 3–4).

Edits or outputs landing in the cloned repository

The source checkout was mounted instead of a separate run directory. Copy an example to its own directory and mount that (Step 3).

Output files are owned by root

Files created inside the container are owned by root. Change ownership afterwards with sudo chown -R "$USER" ., or add --user "$(id -u):$(id -g)" to the docker run command.

There are not enough slots available... (mpirun)

-np exceeds the available cores. Lower -np, or add --oversubscribe after --allow-run-as-root.

See also

  • Installation — compiling MoCSI locally, with the optional VTK / CSPICE / MPI features.

  • Quickstart — writing a run.ini and reading the output.