Docker Deployment
Run LaWallet NWC from the prebuilt multi-arch image, or build it yourself.
The web app is published to Docker Hub as a multi-architecture image —
masize/lawallet-nwc — built
for both linux/amd64 and linux/arm64. The same tag runs natively on Intel/AMD
servers and on ARM (Apple Silicon, AWS Graviton, Raspberry Pi); Docker pulls the
variant that matches your host automatically.
| Tag | Meaning |
|---|---|
masize/lawallet-nwc:latest | Most recent published build |
masize/lawallet-nwc:<version> | Pinned release (e.g. 1.0.0) |
Run from the published image
The quickest path — pull and run, no build, no repo clone.
docker-compose.hub.yml contains the published web image, Postgres, and an
optional NWC listener profile:
# Grab the compose file and safe environment generator
curl -O https://raw.githubusercontent.com/lawalletio/lawallet-nwc/main/docker-compose.hub.yml
curl -O https://raw.githubusercontent.com/lawalletio/lawallet-nwc/main/scripts/generate-deployment-env.sh
chmod +x generate-deployment-env.sh
# Generate every required secret, enable the listener, and start
./generate-deployment-env.sh --mode compose --output .env
docker compose -f docker-compose.hub.yml up -dThe web container waits for Postgres, applies pending Prisma migrations on
startup (prisma migrate deploy), then serves on port 2288.
Configuration
The generator writes the recommended variables to .env. See
Environment Variables for every generated value,
cloud-mode output, placement, backups, and rotation.
Common Compose overrides:
| Variable | Default | Notes |
|---|---|---|
LAWALLET_TAG | latest | Image tag to run (pin to a release, e.g. 1.0.0) |
PORT | 2288 | Host port the app is published on |
JWT_SECRET | (insecure placeholder) | Set this — must be ≥ 32 characters |
LISTENER_URL | (unset) | Set to http://listener:4100 when enabling the bundled listener profile |
LISTENER_AUTH_SECRET | (unset) | Operator-generated shared secret for the optional listener, ≥ 32 characters |
NWC_VAULT_SECRET | (unset) | Dedicated ≥32-character key shared by web/listener; required for stored NWC RemoteWallets or proxy settlement |
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB | lawallet | Bundled Postgres credentials |
Postgres data persists in the lawallet_hub_pgdata named volume.
Persist the generated .env in the operator's encrypted backup. The NIP-57
receipt signer is an nsec entered in Admin Settings; it is encrypted with the
vault key but is not itself an environment variable.
The generated file contains COMPOSE_PROFILES=listener, so normal Compose
commands include the private listener automatically:
docker compose -f docker-compose.hub.yml up -dWithout that profile and pairing configuration, card payments use direct NWC.
Verify it's running
curl http://localhost:2288/api/health
# {"status":"ok","service":"web","database":"up"}Then open http://localhost:2288 — first launch walks you through claiming the root admin with your Nostr key.
docker compose -f docker-compose.hub.yml logs -f web # follow logs
docker compose -f docker-compose.hub.yml down # stop + remove
docker compose -f docker-compose.hub.yml down -v # ... also wipe the DB volumeRun a single container
If you already have a Postgres instance, run just the web container:
docker run -d --name lawallet-web -p 2288:2288 \
-e DATABASE_URL="postgresql://user:pass@host:5432/lawallet" \
-e JWT_SECRET="$(openssl rand -hex 32)" \
-e NWC_VAULT_SECRET="$(openssl rand -hex 32)" \
masize/lawallet-nwc:latestThe image listens on 0.0.0.0:2288 by default; override with -e PORT=….
Build from source
The repo's default docker-compose.yml builds the image locally instead of
pulling it — useful when you're hacking on the app:
git clone https://github.com/lawalletio/lawallet-nwc
cd lawallet-nwc
pnpm deploy:env
docker compose up -dPublishing the image
Maintainers building and pushing new multi-arch images should follow the
Docker publishing guide,
which covers the Buildx multi-platform builder, tagging, and the automated
docker-publish GitHub Actions workflow.