This document describes production-ready deployment flows for SIGNIA, including:
- Local development
- Docker Compose (single-host)
- Kubernetes (multi-service)
- Terraform (cloud infrastructure scaffolding)
- Solana program deployment (Anchor)
- Operational checklists (secrets, migrations, upgrades, rollback)
This guide assumes the repository layout described in
README.md. All paths are relative to repo root unless stated otherwise.
- Architecture summary
- Services and ports
- Environment variables
- Build matrix
- Local deployment (no Docker)
- Docker Compose deployment
- Kubernetes deployment
- Terraform deployment
- Solana program deployment (Anchor)
- Database migrations
- Object store configuration
- Auth & rate limiting
- Observability
- Upgrade strategy
- Rollback strategy
- Production checklist
- Troubleshooting
SIGNIA is deployed as a set of cooperating components:
- signia-api (Rust HTTP API): compile/verify/artifacts/plugins/registry routes.
- signia-store (Rust library): persistence + object store + caching used by the API.
- signia-registry (Solana program): on-chain registry of schema hashes and version pointers.
- console/web (Next.js): user-facing web console.
- console/interface (Node service): “Interface” assistant over docs/schemas/examples (optional).
A typical production deployment is:
Users -> Console (Next.js) -> signia-api -> store (sqlite + fs/s3)
|
+-> Solana RPC -> signia-registry program
Default ports (can be changed via env):
signia-api:8080(HTTP)console/web:3000(HTTP)console/interface:8090(HTTP)
Docker Compose uses the same defaults unless overridden.
Common variables (names may also exist in crates/signia-api/src/config.rs):
SIGNIA_ENV:dev|staging|prodSIGNIA_LOG: log filter (e.g.info,debug,trace)SIGNIA_BIND_ADDR: e.g.0.0.0.0:8080SIGNIA_PUBLIC_BASE_URL: e.g.https://api.signialab.orgSIGNIA_DB_URL: e.g.sqlite:///var/lib/signia/signia.dbSIGNIA_OBJECT_STORE:fs|s3SIGNIA_OBJECT_ROOT: e.g./var/lib/signia/objects(FS mode)SIGNIA_S3_BUCKET: bucket name (S3 mode)SIGNIA_S3_REGION: e.g.us-east-1SIGNIA_S3_ENDPOINT: optional (S3-compatible providers)SIGNIA_S3_ACCESS_KEY_ID: secretSIGNIA_S3_SECRET_ACCESS_KEY: secretSIGNIA_AUTH_MODE:none|bearer|hmac(if implemented)SIGNIA_AUTH_BEARER_TOKENS: comma-separated list (for simple bearer mode)SIGNIA_RATE_LIMIT_RPS: requests per second per key/IPSIGNIA_RATE_LIMIT_BURST: burst capacitySIGNIA_SOLANA_RPC_URL: e.g.https://api.devnet.solana.comSIGNIA_SOLANA_COMMITMENT:processed|confirmed|finalizedSIGNIA_KEYPAIR_PATH: server keypair for registry publishing (optional; not required for read-only)SIGNIA_REGISTRY_PROGRAM_ID: program id ofsignia-registry(devnet/mainnet)
NEXT_PUBLIC_SIGNIA_API_URL: e.g.https://api.signialab.orgNEXT_PUBLIC_SOLANA_RPC_URL: optional (for client-side reads)NEXT_PUBLIC_REGISTRY_PROGRAM_ID: optional (for client-side registry reads)
SIGNIA_INTERFACE_BIND_ADDR: e.g.0.0.0.0:8090SIGNIA_INTERFACE_DOCS_ROOT: e.g../docsSIGNIA_INTERFACE_SCHEMA_ROOT: e.g../schemasSIGNIA_INTERFACE_EXAMPLES_ROOT: e.g../examplesSIGNIA_INTERFACE_MODEL_PROVIDER:openai|anthropic|local(example)SIGNIA_INTERFACE_MODEL_NAME: model id/nameSIGNIA_INTERFACE_API_KEY: secret token for model providerSIGNIA_INTERFACE_STYLE:concise|technical(example)
Use
.env.exampleas the base template, then populate secrets via your platform (K8s secrets, CI secrets, or secret manager).
- Build:
cargo build --release --locked - Workspace: can build specific crates (api/cli) for faster CI.
- Install:
pnpm install --frozen-lockfile - Build:
console/web:pnpm buildconsole/interface:pnpm build(if present)sdk/ts:pnpm build(optional for releases)
./scripts/bootstrap.shcargo build --release --lockedexport SIGNIA_ENV=dev
export SIGNIA_BIND_ADDR=0.0.0.0:8080
export SIGNIA_DB_URL=sqlite:///tmp/signia.db
export SIGNIA_OBJECT_STORE=fs
export SIGNIA_OBJECT_ROOT=/tmp/signia-objects
export SIGNIA_SOLANA_RPC_URL=https://api.devnet.solana.com
cargo run -p signia-apicd console/web
pnpm install
export NEXT_PUBLIC_SIGNIA_API_URL=http://localhost:8080
pnpm devcd console/interface
pnpm install
pnpm devHealth checks:
- API:
GET /v1/health - Console: load
http://localhost:3000
docker-compose.ymlinfra/docker/api.Dockerfileinfra/docker/console.Dockerfileinfra/docker/interface.Dockerfileinfra/docker/runtime/entrypoint.shinfra/docker/runtime/healthcheck.sh
Create .env from .env.example:
cp .env.example .envFill values:
- database path / S3 credentials
- public API URL
- Solana RPC URL and program id
docker compose up -d --buildcurl -fsS http://localhost:8080/v1/healthdocker compose logs -f api
docker compose logs -f console
docker compose logs -f interfacedocker compose down -vThis repo includes sample manifests under infra/k8s/:
namespace.yamlapi-deployment.yamlconsole-deployment.yamlinterface-deployment.yamlingress.yaml
kubectl apply -f infra/k8s/namespace.yamlRecommended: store secrets in a secret manager (AWS SM / GCP SM / Vault) and sync to K8s.
At minimum, create a secret for:
- S3 credentials (if used)
- model provider key (if interface enabled)
- API auth tokens (if enabled)
Example (replace values):
kubectl -n signia create secret generic signia-secrets --from-literal=SIGNIA_S3_ACCESS_KEY_ID=REPLACE_ME --from-literal=SIGNIA_S3_SECRET_ACCESS_KEY=REPLACE_ME --from-literal=SIGNIA_INTERFACE_API_KEY=REPLACE_MEkubectl apply -f infra/k8s/api-deployment.yaml
kubectl apply -f infra/k8s/console-deployment.yaml
kubectl apply -f infra/k8s/interface-deployment.yaml
kubectl apply -f infra/k8s/ingress.yamlkubectl -n signia get pods
kubectl -n signia get svc
kubectl -n signia describe deploy signia-apiUpdate infra/k8s/ingress.yaml for:
- hostnames:
api.signialab.org,signialab.org - TLS secrets (cert-manager recommended)
infra/terraform/ provides a scaffold for:
- networking
- storage (object store + optional db)
- service deployment wiring
- Initialize:
cd infra/terraform/environments/prod terraform init - Plan:
terraform plan
- Apply:
terraform apply
Important: terraform modules in this repo are templates. Customize them to your provider:
- AWS: S3 + EKS + ALB Ingress
- GCP: GCS + GKE + HTTP LB
- DigitalOcean: Spaces + DOKS
- Fly.io / Render / Railway: use Docker deployment instead
Program: programs/signia-registry
- Solana CLI matching your target cluster
- Anchor (via
cargo install --git https://github.com/coral-xyz/anchor avm --lockedandavm install latest)
Devnet:
solana config set --url https://api.devnet.solana.com
solana airdrop 2cd programs/signia-registry
anchor buildanchor deploy --provider.cluster devnetRecord:
- program id
- IDL output (Anchor generates idl artifacts)
anchor testSet:
SIGNIA_REGISTRY_PROGRAM_IDSIGNIA_SOLANA_RPC_URL
signia-store uses SQLite by default and includes migrations:
crates/signia-store/src/kv/migrations/*.sql
Recommended approach:
- Run migrations at startup (idempotent)
- Keep schema changes backwards compatible when possible
- For breaking changes, plan a maintenance window or dual-write strategy
If your signia-store implementation supports an explicit migration command, run it during deploy before traffic cutover.
SIGNIA_OBJECT_STORE=fsSIGNIA_OBJECT_ROOT=/var/lib/signia/objects
Ensure:
- the directory exists
- correct permissions for the runtime user
- backup strategy (rsync/snapshots)
SIGNIA_OBJECT_STORE=s3SIGNIA_S3_BUCKET=...SIGNIA_S3_REGION=...- credentials in secrets
Ensure:
- bucket versioning enabled (recommended)
- SSE encryption enabled (recommended)
- lifecycle rules for cold storage (optional)
In production, do not leave the API open unless intended.
Common patterns:
- simple bearer token (internal tools)
- HMAC signature per request (integrations)
- gateway auth (Cloudflare / API Gateway / Ingress auth)
Set:
SIGNIA_AUTH_MODE=bearerSIGNIA_AUTH_BEARER_TOKENS=...
Set:
SIGNIA_RATE_LIMIT_RPSSIGNIA_RATE_LIMIT_BURST
Also consider upstream rate limiting at the edge (Ingress / CDN / WAF).
Set:
SIGNIA_LOG=info(prod default)SIGNIA_LOG=debug(short-term debugging)
If supported by crates/signia-api/src/telemetry.rs:
- OpenTelemetry export to Tempo/Jaeger
- Prometheus metrics endpoint
In K8s, expose metrics as a Service and scrape via Prometheus Operator.
- API:
/v1/health - Docker: use
infra/docker/runtime/healthcheck.sh - K8s: use readiness/liveness probes
- Prefer rolling updates (K8s Deployment)
- Keep API responses backwards compatible when possible
- Version all endpoints under
/v1/*and introduce/v2/*for breaking changes
- Migrations must be forward compatible with old binaries during a rolling deploy
- If not possible, do a two-phase deploy (maintenance window)
- Can be deployed independently as long as it points to a compatible API version
- Optional component; deploy independently
- Keep retriever/index formats versioned
- Keep the previous container image available
- Keep
VERSIONtags for releases - For DB migrations, avoid irreversible migrations without a rollback plan
- For on-chain changes, prefer version pointers rather than hard deletes
If an upgrade fails:
- Roll back API/console images
- Restore DB snapshot (if needed)
- Repoint DNS/Ingress to stable versions
- No secrets committed (scan repo; rotate keys)
- CI permissions minimized (workflows reviewed)
- Dependabot enabled
- CodeQL enabled (or explicitly disabled)
- API auth enabled (unless intentionally public)
- Rate limiting enabled at API and edge
- CORS restricted to the console domain(s)
- Health checks passing
- Logs shipped to a central system
- Backups configured (db + object store)
- Resource limits set (CPU/memory)
- Alerting on error rates and latency
- Program id recorded and monitored
- RPC provider configured (rate limits, failover)
- Commitment level chosen
- Key management strategy for publishing (HSM/secret manager)
- Verify DB path is writable
- Verify object store credentials / directory permissions
- Verify env vars are present
- Check logs:
SIGNIA_LOG=debug
- Ensure
NEXT_PUBLIC_SIGNIA_API_URLis correct - Verify CORS in API and Ingress
- Verify API is reachable from the browser network
- Ensure pnpm is installed in workflows (corepack/pnpm-action)
- Ensure Rust builds are pinned and use
--locked - Verify
permissions.security-events: writefor CodeQL
- Verify
SIGNIA_KEYPAIR_PATH - Verify RPC URL and cluster config
- Verify program id is correct for the cluster
- This repository includes Docker/K8s/Terraform scaffolding under
infra/. - For a minimal production deployment, Docker Compose is the simplest stable baseline.
- For a scalable deployment, use K8s with an external object store (S3) and centralized logging.