Skip to content

Building and Testing

Everything runs through Docker; no host toolchain needed.

Building from source

docker compose build

This builds the party-line-pagerd image from the Dockerfile: a multi-stage build that compiles the Rust workspace and installs the yopass CLI, Docker CLI, and compose plugin into a minimal Debian runtime image.

The full image (all transports in one container):

docker build -f deploy/Dockerfile.full -t party-line-pager-full .

Build memory requirements

The Rust dependency tree includes several C/C++ libraries (aws-lc-sys, ring, libsqlite3-sys) that compile native code. Without limits, Cargo spawns parallel jobs per CPU core, and each C/C++ sub-build spawns its own parallel cc/cmake jobs. On machines with 16 GB of RAM or less, this can exceed available memory and the build gets OOM-killed (exit 137).

Two build args in both Dockerfiles control this:

  • CARGO_BUILD_JOBS (default 2) limits how many crates cargo compiles in parallel. The cc crate (ring, libsqlite3-sys) respects this via NUM_JOBS.
  • CMAKE_BUILD_PARALLEL_LEVEL (default 2) limits cmake's internal parallelism. aws-lc-sys uses cmake and ignores CARGO_BUILD_JOBS; without this, cmake uses all CPU cores.

Together at =2 these keep peak memory under ~8.5 GB. The cmake package is also installed in the build stage because aws-lc-sys needs it to build AWS-LC from source.

Both ring and aws-lc-rs are in the dependency tree (ring for tokio-xmpp and irc; aws-lc-rs as rustls's default provider, pulled in by matrix-sdk). Neither can be removed without dropping a chat adapter or patching upstream.

Overriding parallelism

Both values are Dockerfile ARGs with a default of 2. You can override them at build time without editing the Dockerfile:

# Local machine with 16+ GB RAM: use 4 jobs for faster builds
docker compose build \
  --build-arg CARGO_BUILD_JOBS=4 \
  --build-arg CMAKE_BUILD_PARALLEL_LEVEL=4

# Or via shell env (compose files read these from the environment)
CARGO_BUILD_JOBS=4 CMAKE_BUILD_PARALLEL_LEVEL=4 docker compose build

GitLab CI overrides both to 1 (the small runner has only 8 GB and no swap). GitHub Actions uses the default 2 with a 4 GB swapfile for linker spikes. GitLab CI runs inside docker:dind where swapon is not available; lowering to 1 is the only option there.

If your build exits with code 137, check docker stats during the next attempt. If memory peaks near 100%, lower both args to 1 or increase Docker's memory limit.

Running tests

compose/docker-compose.build-tools.yml carries a build-tools service. It builds from the same Dockerfile's build stage and keeps the cargo registry in ./.cache and build output in ./target, so repeat runs are fast and nothing root-owned lands in the checkout.

T="-f compose/docker-compose.build-tools.yml"

# Whole workspace
docker compose $T run --rm build-tools

# One crate
docker compose $T run --rm build-tools cargo test -p party-line-pager-core

Ad-hoc cargo commands

The build-tools service is a general-purpose Rust environment. Any cargo command works:

T="-f compose/docker-compose.build-tools.yml"

# Check if a specific package can be updated
docker compose $T run --rm -T build-tools \
  cargo update -p imbl-sized-chunks --dry-run

# Show future-incompatibility report (compiler deprecation warnings)
docker compose $T run --rm -T build-tools \
  cargo report future-incompatibilities --id 1

# Inspect dependency tree for a crate
docker compose $T run --rm -T build-tools \
  cargo tree -p imbl-sized-chunks

# Check what depends on a specific crate
docker compose $T run --rm -T build-tools \
  cargo tree -i imbl-sized-chunks

Note

Always use -T (no TTY) and prefer run --rm so the container is cleaned up. When calling from a script, also redirect stdin: `