The admin password is generated and logged on first start and the nsec is set from the admin UI; ADMIN_PASSWORD/NSEC in .env are only a legacy seed. Update the README, quickstart, configuration, and deployment docs to match, and drop the unused ADMIN_KEY environment variable.
6.0 KiB
Deployment
Production deployment guide for Routstr Provider nodes.
All-in-One Docker Image (Preferred)
The easiest way to deploy Routstr is using the all-in-one Docker image from Docker Hub, which includes both the FastAPI backend and the Next.js admin dashboard in a single container.
Quick Start
docker run -d \
--name routstr \
-p 8000:8000 \
-v routstr-data:/app/data \
-e DATABASE_URL="sqlite:////app/data/routstr.db" \
9qeklajc/routstr:latest
Access your node:
- API & Admin Dashboard: http://localhost:8000
Docker Compose Setup
Create docker-compose.yml:
version: '3.8'
services:
routstr:
image: 9qeklajc/routstr:latest
container_name: routstr
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- routstr-data:/app/data
environment:
DATABASE_URL: "sqlite:////app/data/routstr.db"
LOG_LEVEL: "info"
volumes:
routstr-data:
Start it:
docker compose up -d
Docker Compose (Recommended)
For production, use Docker Compose with persistent storage and optional Tor support.
Use the included compose.yml for a flexible setup that handles both the UI and the node execution. This is useful for development or when you want to manage Tor as a separate service.
docker compose up -d
This will:
- Build the UI: Compiles the frontend and copies it to a shared volume.
- Start Routstr: Runs the Python node, mounting the built UI.
- Start Tor: Provides anonymous access via a
.onionaddress.
With Tor (Anonymous Access)
Add Tor to serve your node as a hidden service—no port forwarding needed.
services:
routstr:
image: ghcr.io/routstr/proxy:latest
container_name: routstr
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- ./data:/app/data
- ./logs:/app/logs
environment:
- TOR_PROXY_URL=socks5://tor:9050
# Keep the database (and the key file generated beside it) on the volume.
- DATABASE_URL=sqlite:////app/data/routstr.db
depends_on:
- tor
tor:
image: ghcr.io/hundehausen/tor-hidden-service:latest
container_name: tor
restart: unless-stopped
volumes:
- ./tor-data:/var/lib/tor
environment:
- HS_ROUTER=routstr:8000:80
After starting, find your .onion address:
docker exec tor cat /var/lib/tor/hidden_service/hostname
See Tor Support for details.
Pre-Configuration (Optional)
While everything can be configured via the dashboard, you can pre-configure settings with environment variables for automated deployments.
Using Environment Variables
services:
routstr:
image: ghcr.io/routstr/proxy:latest
environment:
# Pre-configure upstream (optional)
- UPSTREAM_BASE_URL=https://api.openai.com/v1
- UPSTREAM_API_KEY=sk-proj-...
# The admin password is generated and logged once on first start; set
# ADMIN_PASSWORD here only as a legacy seed for an existing deployment.
# Node identity
- NAME=My Provider Node
- DESCRIPTION=Fast GPT-4 access via Lightning
# Lightning withdrawals
- RECEIVE_LN_ADDRESS=me@walletofsatoshi.com
# Keep the database (and the key file generated beside it) on the volume.
- DATABASE_URL=sqlite:////app/data/routstr.db
volumes:
- ./data:/app/data
Using an .env File
services:
routstr:
image: ghcr.io/routstr/proxy:latest
env_file:
- .env
volumes:
- ./data:/app/data
Example .env:
UPSTREAM_BASE_URL=https://api.openai.com/v1
UPSTREAM_API_KEY=sk-proj-...
# Keep the database (and the key file generated beside it) on the mounted volume.
DATABASE_URL=sqlite:////app/data/routstr.db
# Encrypts node secrets at rest. Optional — if unset, a key is generated next to
# your database (on the same volume) and its file is named once for backup. Set
# it explicitly to manage the key yourself.
ROUTSTR_SECRET_KEY=
NAME=My Provider Node
RECEIVE_LN_ADDRESS=me@walletofsatoshi.com
!!! note "Secret key persistence"
If you leave ROUTSTR_SECRET_KEY unset, the node generates one and stores it
as routstr_secret.key next to your database, so it persists on the same
volume as your data — just include that volume in your backups. For stronger
isolation (keeping the key off the data volume), set ROUTSTR_SECRET_KEY from
a secrets manager instead.
See Configuration for all available options.
Persistence
Point DATABASE_URL inside /app/data (as the examples above do) so everything
Routstr persists lands on the mounted volume:
| Path | Contents |
|---|---|
routstr.db |
SQLite database (settings, API keys, sessions) |
routstr_secret.key |
Auto-generated master key, written beside the database when ROUTSTR_SECRET_KEY is unset |
.wallet/ |
Cashu wallet data (your Bitcoin!) |
!!! warning "Back Up Your Data"
The ./data volume contains your wallet. Losing it means losing funds. Back up regularly.
Reverse Proxy (Optional)
For custom domains and SSL, use a reverse proxy like Caddy or nginx.
Caddy Example
api.yournode.com {
reverse_proxy localhost:8000
}
nginx Example
server {
listen 443 ssl;
server_name api.yournode.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Updates
Pull the latest image and restart:
docker compose pull
docker compose up -d
Building from Source
Using Docker Compose
The easiest way to build everything from source:
docker compose build
Individual Components
If you prefer building the node only (requires manual UI build first):
docker build -t routstr-node .