Repeatable deployment after a total docker nuke
This documents whether wiping all Docker state and re-deploying reproduces a working
verifiably system, what you must supply, and how to reproduce the demo data behind the
screenshots. It covers a public VPS/EC2 (subdomain + TLS) and localhost (legacy host:port).
TL;DR โ what a nuke + ./deploy.sh up all reproduces
A "total docker nuke" wipes everything:
docker rm -f $(docker ps -aq) 2>/dev/null
docker rmi -f $(docker images -aq) 2>/dev/null
docker volume rm $(docker volume ls -q) 2>/dev/null
docker network rm $(docker network ls -q --filter type=custom) 2>/dev/null
docker system prune -a --volumes -f
After that, git clone โ edit .env โ ./deploy.sh up all reconstructs all surfaces and
base plumbing but not the demo data:
| Reproduced by deploy (code/scripts) | NOT reproduced (runtime state in wiped volumes) |
|---|---|
Every UI surface (issuer/holder/verifier, registry consoles, /admin/esignet, identity.registry/admin.registry) |
Enrolled National ID registry rows (certify.identity_registry) |
IdP base users: Keycloak holder/issuer/admin, WSO2 admin |
Provisioned claims (certify.vc_subject) |
eSignet wallet-demo-client, one mock identity 8267411072/PIN 111111 |
UI-built schemas (Business Registration / Director / Testa* / Fresh*) |
Base VerifiablePersonCredential catalog entry, 200 mock citizens |
Issued/revoked ledger + AUTHORISED/DENIED verdicts |
walt.id / CREDEBL DIDs, all host-coupled config (regenerated from .env) |
The narrowed eSignet login-factor config; demo IdP users adamk/adamw |
So the application comes back identically; the demo dataset (identities, schemas,
provisioned claims, and therefore the AUTHORISED/DENIED verdicts) is created by the e2e
harness under e2e/demo/ โ see "Reproduce the demo" below.
What you must supply for a fresh host
Copy .env.example โ .env and set:
- Host + domain (subdomain mode):
VERIFIABLY_PUBLIC_HOST(IPv4),PUBLIC_HOST,
VERIFIABLY_PUBLIC_DOMAIN,VERIFIABLY_HOSTS_PATTERN=https://%s.<domain>,
VERIFIABLY_LE_EMAIL. (./deploy.sh setupwrites host/domain/LE for you; it does NOT
write the secrets below โ set those by hand and don't re-run the wizard after, it
rewrites.env.) - Secrets (now listed as concrete lines in
.env.example):VERIFIABLY_API_KEYS
(change the demo secret),SMTP_*(only if you want email-OTP holder activation),
VERIFIABLY_REGISTRIES(optional). Demo defaults elsewhere are safe for a demo, rotate
for production (WALLET_ENCRYPTION_KEY, DB passwords, admin passwords). - DNS (subdomain mode, operator's manual step): wildcard
*.<domain>and
*.registry.<domain>โ the host IP (the two-labelidentity.registry.<domain>/
admin.registry.<domain>need the second wildcard). Open ports 80 + 443 for Let's Encrypt.
Then ./deploy.sh up all (or make up-all).
localhost / legacy mode
Leave VERIFIABLY_HOSTS_PATTERN= empty. URLs become http://<host>:<port>, the main Caddy
binds :80, and Let's Encrypt is skipped โ no public DNS needed. ./deploy.sh up all works
on localhost. (The walt.id service confs now render http://<host>:<port> in legacy mode, so
this path is unblocked.)
Deployment granularity
- Whole stack:
./deploy.sh up all - Per DPG:
./deploy.sh up waltid | inji | credebl - Teardown:
./deploy.sh down <scenario>; wipe volumes:./deploy.sh reset - A Makefile wraps these (
make up-all,make waltid-up,make inji-up,make credebl-up,
make nuke,make reset). Seemake help.
Reproduce the demo (identities, schemas, verdicts)
The demo data is created by the committed e2e harness (e2e/demo/), run headless against a
running deploy. Prerequisites: the stack is up (up all), VERIFIABLY_API_KEYS is set, and
the Playwright image is available. Each script's header documents its holder UIN/PINs.
# from a host with docker + the running stack:
docker run --rm --network host \
-v "$PWD/e2e/demo":/pv -v /tmp/e2e-out:/root/e2e-out \
-e BASE=https://verifiably.<domain> \
mcr.microsoft.com/playwright:v1.55.0-noble \
node /pv/demo-inji-director.mjs # Inji auth-code delegated pair โ AUTHORISED โ revoke โ DENIED
# demo-director-full.mjs = the walt.id delegated pair (issuer Keycloak, holder WSO2)
These recreate the enrolled identities, the Business Registration + Company Director schemas,
the provisioned claims, and drive claim โ present โ revoke to reproduce the AUTHORISED then
DENIED verdicts shown in the PR screenshots.
Known re-deploy gotchas (handled)
- walt.id service confs render host-correctly in both subdomain and legacy mode.
- Hairpin sidecars (
deploy/compose/credebl/jwks-hairpin.sh,
deploy/compose/verifier-status-hairpin.sh) derive their alias fromVERIFIABLY_PUBLIC_DOMAIN
(no hardcoded host); they no-op in legacy mode. Run them afterupin subdomain mode if you
use CREDEBL issuance or the walt.id verifier "Status" policy. - Auth-code scope files (
inji/certify/certify-postgres-dataprovider.properties,
inji/esignet/credential-scopes.properties): the committed baseline advertises only the
base scope, matching a fresh certify volume. Do NOT commit the runtime-accumulated scopes a
running box adds (schemas re-add their own scopes when rebuilt). If a box's working tree has
drifted and you wipe the certify volume, restore the baseline first:
scripts/reset-authcode-catalog.sh --yes. - Don't commit deploy-generated config (
Caddyfile.public,backends*.json,
wso2-deployment.toml, the rendered*-service.conf) โ all regenerate from.envon everyup.