LaWalletdocs
Deploy

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.

TagMeaning
masize/lawallet-nwc:latestMost 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 -d

The 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:

VariableDefaultNotes
LAWALLET_TAGlatestImage tag to run (pin to a release, e.g. 1.0.0)
PORT2288Host 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_DBlawalletBundled 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 -d

Without 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 volume

Run 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:latest

The 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 -d

Publishing 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.

On this page