Deployment & Installation
What this page covers
How to install the Stigmem reference node. Docker Compose is the supported deployment path in v0.9.0a1 for both local development and single-host production. For development against source, see Running without Docker.
Audience: node operators installing Stigmem for the first time, or migrating an existing bare-metal install to Docker.
For the narrative Docker Compose runbook, see Operating Stigmem โ Deploy runbooks.
Fly.io, Helm/Kubernetes, systemd, PaaS, and Grafana recipes have been moved to experimental/deploy-*/ per ADR-002. They remain available as starting points but are unsupported until they pass the ADR-008 reintroduction gates. See Features โ Deployment for the full disposition.
Container image tags โ which one should I pull?โ
The reference node image is published to GHCR at ghcr.io/eidetic-labs/stigmem-node. Several tag flavours are published in parallel.
:0.9.0aN / :0.9.0bN / :1.0.0rcN / :1.0.0:0.9.0-alpha.N / :0.9.0-beta.N / :1.0.0-rc.N:latest:edge:<short-sha>@sha256:<digest>Quick rule of thumb
- Trying things out โ
:latest - Controlled internal workload โ
:0.9.0aN(your current release) - Auditable deployment โ
@sha256:<digest>of the version tag you intend to run
:latest resolves to todaydocker pull ghcr.io/eidetic-labs/stigmem-node:latest
docker inspect --format '{{.RepoDigests}}' ghcr.io/eidetic-labs/stigmem-node:latest
The printed digest is what's actually running. Pin to that digest in your Compose / Helm chart for a tamper-evident production deployment.
Image retentionโ
Retained forever
:latest; all version tags (:0.9.0aN, :0.9.0bN, :1.0.0rcN, :1.0.0); :edge.
Retained 90 days
Short-SHA tags and their orphan Sigstore signature artefacts.
Operationally enforced by .github/workflows/ghcr-retention.yml.
Prerequisitesโ
No Python or Node.js installation is required for the Docker path.
One-click Docker Compose installโ
git clone https://github.com/eidetic-labs/stigmem
cd stigmem
docker compose up --build -d
This builds the reference node image once and starts node-a and node-b:
node-a/healthz ยท /docs ยท /.well-known/stigmemnode-b/healthz ยท /docs ยท /.well-known/stigmemVerify both are healthy:
curl -s http://localhost:8765/healthz # โ {"status":"ok"}
curl -s http://localhost:8766/healthz # โ {"status":"ok"}
Then follow the Quickstart to complete the federation handshake and assert your first fact.
Persist your keypairsโ
By default, each node auto-generates an Ed25519 keypair on first start and stores it in node_meta. To survive container recreation, supply your own:
python3 -c "
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
import base64, os
priv = Ed25519PrivateKey.generate()
priv_bytes = priv.private_bytes_raw()
pub_bytes = priv.public_key().public_bytes_raw()
print('STIGMEM_FEDERATION_PRIVKEY=' + base64.urlsafe_b64encode(priv_bytes).decode())
print('STIGMEM_FEDERATION_PUBKEY=' + base64.urlsafe_b64encode(pub_bytes).decode())
"
Add those two variables to the environment: block of your docker-compose.yml.
Stop and clean upโ
docker compose down # stop containers; preserve data volumes
docker compose down -v # stop and delete all data
Multi-node topology (soak / staging)โ
For 4-node full-mesh federation with shorter pull intervals:
# Generate keypairs for all four nodes
cd infra && python soak/keys.py > soak/.env
# Start the cluster
docker compose -f infra/docker-compose.soak.yml --env-file infra/soak/.env up --build -d
Nodes run on ports 8765โ8768. See the 4-node federation guide for peer wiring, backpressure, and failure injection.
Environment variable referenceโ
Coreโ
STIGMEM_DB_PATHSTIGMEM_HOSTSTIGMEM_PORTSTIGMEM_NODE_URLPeerDeclaration payloads.STIGMEM_LOG_LEVELSTIGMEM_AUTH_REQUIREDfalse only for single-operator / local-only installs.Federationโ
STIGMEM_FEDERATION_ENABLEDSTIGMEM_FEDERATION_PUBKEYSTIGMEM_FEDERATION_PRIVKEYSTIGMEM_FEDERATION_PULL_INTERVAL_SSTIGMEM_FEDERATION_PUSH_ENABLEDSTIGMEM_FEDERATION_NONCE_WINDOW_SSTIGMEM_FEDERATION_ALLOW_TEAMteam-scoped facts to cross federation boundaries. Audit-logged.Decay, Attestation, OIDC, Performanceโ
STIGMEM_DECAY_TTL_SECONDSttl_seconds.STIGMEM_DECAY_MIN_CONFIDENCESTIGMEM_ATTESTATION_REQUIREDPOST /v1/facts. Enable for multi-tenant or public nodes.STIGMEM_SOURCE_ATTESTATION_MODESTIGMEM_OIDC_ENABLEDSTIGMEM_OIDC_ISSUER_URLSTIGMEM_OIDC_AUDIENCEaud claim.STIGMEM_OIDC_TOKEN_TTL_HOURSSTIGMEM_OIDC_ALLOWED_DOMAINSSTIGMEM_ASYNC_JOB_THRESHOLD202 Accepted.Upgradeโ
Upgrading a Docker Compose installโ
git pull
docker compose up --build -d
Data volumes persist across rebuilds. Database migrations run automatically on startup โ there is no manual migration step.
Upgrading from bare-metal to Docker Composeโ
- Stop the existing service. If running as a macOS LaunchAgent:
bash scripts/service-uninstall.sh. If running manually, stop the process (Ctrl-C or kill the PID). - Locate your database. By default the bare-metal node writes to
data/stigmem.db(relative to the repo root).ls -lh data/stigmem.db. If you setSTIGMEM_DB_PATH, use that path instead. - Create a Docker volume and copy data in (see snippet below).
- Start Docker Compose.
docker compose up --build -d. Verify node-a picked up the data:curl -s 'http://localhost:8765/v1/facts?limit=5' | jq .facts - (Optional) Restore your keypair. If you had a stable
STIGMEM_FEDERATION_PUBKEY/PRIVKEY, add the same values todocker-compose.ymlso existing peers recognize the node.
# Create the named volumes Docker Compose expects
docker volume create stigmem__node-a-data
docker volume create stigmem__node-b-data
# Copy your existing database into node-a's volume
docker run --rm \
-v "$(pwd)/data/stigmem.db:/src/stigmem.db:ro" \
-v "stigmem__node-a-data:/data" \
busybox cp /src/stigmem.db /data/stigmem.db
Docker Compose prefixes volume names with the project name (derived from the directory name). If your repo directory is not named stigmem, replace stigmem__ with <directory-name>_.
Running without Dockerโ
For development against the source directly:
cd stigmem/node
uv sync # install dependencies
uv run python -m stigmem_node # starts on http://localhost:8765
Interactive Swagger UI: http://localhost:8765/docs.
For macOS persistent service (LaunchAgent, no Docker), see Installation.