190 lines
7.4 KiB
Markdown
190 lines
7.4 KiB
Markdown
# Docker and Compose
|
|
|
|
For every field, default, constraint and complete example, see the [TOML configuration reference](configuration.md)。
|
|
|
|
The image contains the validator, `rsync`, CA certificates and `/usr/bin/time`.
|
|
The root filesystem is read-only; input and configuration are read-only; output and
|
|
state mounts are writable. The application receives a subcommand and one configuration option:
|
|
`validate|daemon --config FILE`.
|
|
|
|
Build the image:
|
|
|
|
```bash
|
|
docker build -f docker/Dockerfile -t panda-rpki:v0.1.0 .
|
|
```
|
|
|
|
## Single validate run
|
|
|
|
Create a TOML whose paths are valid **inside** the container:
|
|
|
|
```toml
|
|
config-version = 1
|
|
mode = "validate"
|
|
out = "/output"
|
|
rrdp-state-dir = "/state/repository"
|
|
ccr-out = "/output/result.ccr"
|
|
|
|
[[anchors]]
|
|
id = "anchor"
|
|
tal = "/input/anchor.tal"
|
|
# ta = "/input/anchor.cer" # uncomment for fixed TA mode
|
|
```
|
|
|
|
Run the provided Compose template:
|
|
|
|
```bash
|
|
mkdir -p state output
|
|
export CONFIG_FILE="$PWD/validate.toml"
|
|
export INPUT_DIR="$PWD/input" STATE_DIR="$PWD/state" OUTPUT_DIR="$PWD/output"
|
|
export PUID="$(id -u)" PGID="$(id -g)"
|
|
docker compose -f docker/compose.yaml run --build --rm validator
|
|
```
|
|
|
|
The template mounts the TOML read-only at `/config/validate.toml` and invokes
|
|
`panda-rpki validate --config /config/validate.toml`. Host variables only select
|
|
mounts, image and container UID/GID; they are not read as validator settings.
|
|
|
|
## All five RIRs
|
|
|
|
Put the five RIR TAL files (TA certificates are optional) under `input/` and list them as named anchors in a
|
|
TOML with `/input/...` paths. Then set `CONFIG_FILE` to that file and run:
|
|
|
|
```bash
|
|
export CONFIG_FILE="$PWD/all5.toml"
|
|
export INPUT_DIR="$PWD/input" STATE_DIR="$PWD/state/all5" OUTPUT_DIR="$PWD/output/all5"
|
|
docker compose -f docker/compose.all5.yaml run --build --rm validator
|
|
```
|
|
|
|
The application still receives only `validate --config`; workers, timeouts,
|
|
logging and sync policy belong in `all5.toml`.
|
|
|
|
## Daemon
|
|
|
|
Daemon TOML paths are also container paths. `state-root` owns run directories,
|
|
protocol state and the `latest` pointer:
|
|
|
|
```toml
|
|
config-version = 1
|
|
mode = "daemon"
|
|
state-root = "/data"
|
|
interval-secs = 600
|
|
retain-runs = 10
|
|
run-timeout-secs = 1800
|
|
shutdown-grace-secs = 30
|
|
|
|
[[anchors]]
|
|
id = "anchor"
|
|
tal = "/input/anchor.tal"
|
|
# ta = "/input/anchor.cer" # uncomment for fixed TA mode
|
|
```
|
|
|
|
Run the daemon template:
|
|
|
|
```bash
|
|
mkdir -p daemon-state
|
|
export CONFIG_FILE="$PWD/daemon.toml"
|
|
export INPUT_DIR="$PWD/input" DAEMON_DIR="$PWD/daemon-state"
|
|
export PUID="$(id -u)" PGID="$(id -g)"
|
|
docker compose -f docker/compose.daemon.yaml up --build
|
|
```
|
|
|
|
For an all-RIR daemon use `docker/compose.all5-daemon.yaml` with an all-RIR
|
|
TOML. Stop the whole Compose service for an upgrade so the state-root lock and
|
|
validator child are released; do not delete `daemon-state`.
|
|
|
|
## Configuration and persistence
|
|
|
|
Run `docker compose ... run --rm validator validate --config ... --check-config`
|
|
only when the image command is overridden deliberately; the normal templates
|
|
already pass the config. Check/print never download TA files or open RocksDB.
|
|
Successful validate publication, when `publish-dir` is configured, is an
|
|
immutable `publish/runs/<id>` plus `publish/latest`; daemon publication uses its
|
|
existing `state-root/runs/run_<seq>` directory. Cache files are written beside
|
|
the protocol state as `<state>.ta-cache/`.
|
|
|
|
If a host path is not writable by the selected UID/GID, pre-create it and fix
|
|
ownership. Preserve existing state and run history when changing images. Verify
|
|
`summary.json`, `result-complete.json`, `vrps.csv`, `vaps.csv`, timing files and
|
|
the `latest` link after a deployment.
|
|
|
|
## Complete configuration examples
|
|
|
|
Copy a template before editing it; set `CONFIG_FILE` to the copy's absolute path.
|
|
These templates use automatic **TA certificate** refresh, text/info logs and
|
|
`require-complete = true`. They never download or update TAL files.
|
|
|
|
| Compose file | Complete TOML |
|
|
| --- | --- |
|
|
| `compose.yaml` | [validate.toml](../docker/examples/validate.toml) |
|
|
| `compose.all5.yaml` | [validate-all5.toml](../docker/examples/validate-all5.toml) |
|
|
| `compose.daemon.yaml` | [daemon.toml](../docker/examples/daemon.toml) |
|
|
| `compose.all5-daemon.yaml` | [daemon-all5.toml](../docker/examples/daemon-all5.toml) |
|
|
|
|
For example, from the repository root:
|
|
|
|
```bash
|
|
cp docker/examples/daemon-all5.toml daemon.toml
|
|
export CONFIG_FILE="$PWD/daemon.toml"
|
|
export INPUT_DIR="$PWD/input" DAEMON_DIR="$PWD/daemon-state"
|
|
mkdir -p "$DAEMON_DIR"
|
|
export PUID="$(id -u)" PGID="$(id -g)"
|
|
docker compose -p panda-all5 -f docker/compose.all5-daemon.yaml up -d --build
|
|
```
|
|
|
|
For single validation, `/state` is the writable mount parent. Set
|
|
`rrdp-state-dir = "/state/repository"` so both `/state/repository` and its
|
|
sibling `/state/repository.ta-cache` are persistent and writable. Existing
|
|
fixed-mode deployments with `rrdp-state-dir = "/state"` must plan a stopped
|
|
state-layout migration or mount `/state.ta-cache` separately before enabling
|
|
automatic mode. Do not silently point an existing database at an empty path.
|
|
Daemon needs no such migration: `/data/state` and `/data/state.ta-cache` already
|
|
share the writable `/data` mount.
|
|
|
|
## Graceful stop, edit and reload
|
|
|
|
Use the same project name, Compose file and environment file on every command.
|
|
The following assumes the `panda-all5` project created above:
|
|
|
|
```bash
|
|
dc() { docker compose -p panda-all5 -f docker/compose.all5-daemon.yaml "$@"; }
|
|
dc stop --timeout 40 validator
|
|
dc ps -a
|
|
cp -a "$CONFIG_FILE" "$CONFIG_FILE.bak.$(date -u +%Y%m%dT%H%M%SZ)"
|
|
```
|
|
|
|
Edit the existing top-level field to `log-format = "text"`. To enable automatic
|
|
TA refresh, remove each desired anchor's `ta` field; keep its `id` and `tal`.
|
|
`ta-refresh-policy = "allow-valid-cache"` allows a revalidated cache fallback
|
|
and marks that run partial; `"require-fresh"` rejects the fallback. Missing or
|
|
invalid cache cannot satisfy the first automatic run if all downloads fail.
|
|
|
|
Check the changed file and recreate the service:
|
|
|
|
```bash
|
|
dc run --rm --no-deps validator daemon --config /config/daemon.toml --check-config
|
|
dc run --rm --no-deps validator daemon --config /config/daemon.toml --print-config
|
|
# Continue only after Configuration valid. and the expected effective settings.
|
|
dc up -d --no-build --force-recreate validator
|
|
dc logs --since 2m validator
|
|
```
|
|
|
|
Recreation is intentional: editors and `sed -i` can replace the host file's
|
|
inode, while an existing single-file bind mount may retain the old file.
|
|
`start` or `restart` alone is not the documented configuration reload procedure.
|
|
Recreation retains bind-mounted state and run history.
|
|
|
|
SIGTERM prevents further cycles and allows the active child up to
|
|
`shutdown-grace-secs` (30 here) to finish. If it does not finish, the controller
|
|
sends TERM, then KILL after another 2 seconds. Docker's 40-second timeout leaves
|
|
room for controller cleanup. It is not an unlimited wait for the current cycle.
|
|
To avoid interrupting a long cycle, stop during the daemon's sleeping interval.
|
|
`exited` confirms the container stopped; exit 3 means the controller recorded
|
|
partial runs under `require-complete`, and does not mean stop failed. Inspect
|
|
lifecycle logs to establish whether the last child finished or was interrupted.
|
|
|
|
The controller logs are in `docker compose logs`; child diagnostics are in
|
|
`data/runs/run_XXXXXX/validator.log` on the host. Existing logs keep their original
|
|
format. JSON summary/metadata files remain JSON even with text diagnostics.
|
|
`latest` exists only after a complete success; partial runs do not create or
|
|
replace it, including the first run after upgrading an old state root.
|