# 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] ``` ## 1. Install Docker ::::{tab-set} :::{tab-item} Linux ```bash 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: ```bash sudo usermod -aG docker "$USER" ``` ::: :::{tab-item} macOS Install Docker Desktop from and start it (the whale icon in the menu bar must be running). ::: :::{tab-item} Windows Install Docker Desktop from 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: ```bash 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. ```bash 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: ```bash 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`: ```bash 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`: ```bash 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: ```bash 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. ::::{tab-set} :::{tab-item} Linux / macOS ```bash 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 ``` ::: :::{tab-item} Windows (PowerShell) ```powershell 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//` 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): ::::{tab-set} :::{tab-item} Linux / macOS ```bash docker run --rm -v "$PWD":/work mocsi:2.0.0 mocsi -i seb_top_const_flux_bottom_1d.ini ``` ::: :::{tab-item} Windows (PowerShell) Use the explicit `--mount` form. It names each field, so it is not affected by PowerShell quoting: ```powershell 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. ```powershell 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) ::::{tab-set} :::{tab-item} Linux / macOS ```bash 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 ``` ::: :::{tab-item} Windows (PowerShell) ```powershell 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: ```bash 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: ```bash which mocsi mocsi_mpi ``` ## 8. Running with no command ```bash 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: ```bash 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](installation_instructions.md) — compiling MoCSI locally, with the optional VTK / CSPICE / MPI features. - [Quickstart](../quick_start/quick_start.md) — writing a `run.ini` and reading the output.