Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Build and share the Docker environment with Nix

Use Nix to build the development environment once, then distribute it as a Docker image. The machine building the image needs Nix; a machine running the image needs only Docker. This is the same environment as nix develop, with the compilers, patched QEMU, FastDyn tools, Python dependencies, and mdBook.

flowchart TD
    pins["flake.nix + flake.lock"] --> shell["nix develop<br/>Local development shell"]
    pins --> build["nix build .#devContainer"]
    build --> archive["Docker image archive"]
    archive --> local["docker load<br/>Use or share locally"]
    archive --> registry["GitHub Actions<br/>Publish to GHCR"]
    registry --> pull["docker pull<br/>No Nix installation needed"]
    local --> run["docker run<br/>Mount the FastDyn checkout"]
    pull --> run

The image targets Linux x86-64 (linux/amd64). It contains the tools; your source checkout, TOML files, models, and results come from a mounted directory. It is a development and simulation image, not a preconfigured long-running simulation service.

Build and load the image

Follow the Nix setup and install Docker Engine. From the FastDyn root:

nix build .#devContainer --out-link out/dev-container
docker load --input out/dev-container

The first command creates a link to a compressed image archive in the Nix store. The second should print Loaded image: fastdyn-dev:local. It does not publish anything. The first build can take time; later builds reuse unchanged Nix dependencies. nix/dev-container.nix derives the image from the development shell with dockerTools.streamNixShellImage, so there is no second package list or Dockerfile to maintain.

Check the loaded tools:

docker run --rm fastdyn-dev:local bash -c \
  'rumoca --version && fastdyn --help && mdbook --version'

Expect Rumoca 0.10.0, FastDyn command help, and mdBook 0.5.2.

Run against your checkout

Initialize the source submodules, then enter:

docker run --rm -it --user "$(id -u):$(id -g)" \
  --volume "$PWD:/workspace" --publish 5000:5000 --publish 3000:3000 \
  fastdyn-dev:local

The shell opens at /workspace. The user mapping keeps generated files owned by your host user. Run fastdyn-config, fastdyn, and python here just as in the other environments. Keep simulation settings in TOML; the container does not need environment variables to select a model or mission.

After creating a run configuration inside this environment, you can also run it directly from the host. For example, the first mission creates out/copter.toml:

docker run --rm --user "$(id -u):$(id -g)" \
  --volume "$PWD:/workspace" --publish 5000:5000 fastdyn-dev:local \
  fastdyn run -c out/copter.toml -o out/copter/work

Regenerate run configurations inside the container when moving from another machine or environment: generated tool and socket paths describe that runtime. Results under out/ remain on the host after --rm removes the container. Run one vehicle at a time with the supplied port assignments.

To view this book from the container:

docker run --rm -it --user "$(id -u):$(id -g)" \
  --volume "$PWD:/workspace" --publish 3000:3000 fastdyn-dev:local \
  mdbook serve docs --hostname 0.0.0.0

Open http://localhost:3000 on the host. Binding to 0.0.0.0 inside the container allows Docker’s published port to reach mdBook.

Share an archive or use GHCR

To share the built image without a registry, copy the actual archive rather than the Nix store symlink:

cp --dereference out/dev-container out/fastdyn-dev.tar.gz

On the receiving machine:

docker load --input fastdyn-dev.tar.gz

Use the docker run commands above with a checkout of the same FastDyn revision.

The publishing workflow builds and checks the image on pull requests and publishes it on pushes to main. Same-repository PRs also publish preview tags such as pr-1; fork PRs do not publish. To use the published image instead, run:

docker pull ghcr.io/jgoppert/fastdyn/dev:latest

Replace fastdyn-dev:local in the run commands with that image name. For a repeatable tutorial, use the published sha-<full-commit> tag and check out the matching commit instead of following latest. In another repository, the workflow publishes to ghcr.io/<owner>/<repository>/dev, all lowercase. The build and publication steps are automatic; Pages enablement and package visibility are the repository settings described in the contributing chapter.