archon

Archon Deployment Guide

This guide walks you through deploying an Archon node, from a minimal DID-only setup to a full Lightning-enabled stack. Each section builds on the previous one — start with the core and add layers as needed.

Table of Contents

  1. Prerequisites
  2. Core Node (DID Only)
  3. Adding Bitcoin Registries
  4. Adding Drawbridge (API Gateway + Tor)
  5. Bundled Lightning Stack (Optional)
  6. Production Hardening
  7. Port Reference
  8. Troubleshooting

1. Prerequisites

Initial Setup

git clone https://github.com/archetech/archon.git
cd archon
cp sample.env .env

Set your user/group IDs so containers run with the correct permissions:

# Add these to your .env
ARCHON_UID=$(id -u)
ARCHON_GID=$(id -g)

Generate an admin API key:

# Add to .env as ARCHON_ADMIN_API_KEY
openssl rand -hex 32

Internal service-to-service admin requests use the X-Archon-Admin-Key header. Reserve Authorization for user/session/OAuth-style flows.

Data Directories

All persistent data lives under ./data/. Create the directory and ensure it’s owned by your user:

mkdir -p data

2. Core Node (DID Only)

The base docker-compose.yml runs everything needed for DID creation, resolution, and credential management.

Disable Optional Services

Comment out the include: lines at the top of docker-compose.yml for any services you don’t need yet:

# include:
#   - docker-compose.btc-mainnet.yml
#   - docker-compose.btc-signet.yml
#   - docker-compose.lightning.yml
#   - docker-compose.drawbridge.yml

Key Environment Variables

Variable Default Description
ARCHON_ADMIN_API_KEY (empty) Required. Protects admin API routes
ARCHON_ENCRYPTED_PASSPHRASE (empty) Required. Passphrase for encrypting the wallet. Keymaster won’t start without it
ARCHON_NODE_ID mynodeID Alias for the node’s agent DID (created on first run)
ARCHON_NODE_NAME mynodeName Human-readable node name for peer discovery
ARCHON_GATEKEEPER_PORT 4224 Gatekeeper API port
ARCHON_KEYMASTER_PORT 4226 Keymaster API port
ARCHON_GATEKEEPER_CLIENT_PORT 4225 Gatekeeper client UI port
ARCHON_REACT_WALLET_PORT 4228 React wallet UI port
ARCHON_GATEKEEPER_DB redis Storage backend (redis or json)
ARCHON_GATEKEEPER_DID_PREFIX did:cid DID method prefix
ARCHON_GATEKEEPER_REGISTRIES hyperswarm Comma-separated list of registries
ARCHON_DEFAULT_REGISTRY hyperswarm Default registry for new DIDs
ARCHON_PROTOCOL /ARCHON/v0.2-reboot Hyperswarm protocol identifier

Services

Service Description
mongodb Used by satoshi mediators for Bitcoin registry state
redis Primary DID data store, cache, and pub/sub
ipfs Content-addressable storage
gatekeeper DID resolution and management API
keymaster Wallet and credential management API
hyperswarm-mediator P2P DID synchronization
cli Command-line interface container
explorer DID explorer web app
gatekeeper-client Browser UI for the Gatekeeper API
keymaster-client Browser UI for the Keymaster service
react-wallet Web wallet UI
prometheus Metrics collection
grafana Metrics dashboards

Start and Verify

docker compose up -d
docker compose logs -f gatekeeper   # watch for startup

# Verify gatekeeper is running
curl http://localhost:4224/api/v1/version

Core UIs:


3. Adding Bitcoin Registries

Bitcoin registries anchor DIDs on-chain via the Satoshi mediator. Each bundled network also includes a dedicated watch-only wallet service under services/mediators/satoshi-wallet. There are separate compose files per network:

File Network Bitcoin Node
docker-compose.btc-mainnet.yml BTC mainnet You provide — requires an external Bitcoin Core node with RPC access
docker-compose.btc-signet.yml BTC signet Bundled — runs its own bitcoin-core container
docker-compose.btc-testnet4.yml BTC testnet4 Bundled — runs its own bitcoin-core container

Enable a Registry

Uncomment the relevant include: line in docker-compose.yml:

include:
  - docker-compose.btc-mainnet.yml
  # - docker-compose.btc-signet.yml

Key Environment Variables (Mainnet)

Variable Default Description
ARCHON_BTC_HOST localhost Bitcoin RPC host
ARCHON_BTC_PORT 8332 Bitcoin RPC port
ARCHON_BTC_USER bitcoin Bitcoin RPC username
ARCHON_BTC_PASS bitcoin Bitcoin RPC password
ARCHON_BTC_WALLET archon Bitcoin wallet name
ARCHON_BTC_START_BLOCK 934000 Block height to start scanning
ARCHON_BTC_FEE_MAX 0.00010000 Maximum fee per transaction (BTC)

Signet and testnet4 have their own prefixed variables (ARCHON_SIGNET_*, ARCHON_BTC_T4_*) — see sample.env for the full list.

Update Gatekeeper Registries

Add Bitcoin registries to the gatekeeper’s registry list:

ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,BTC:mainnet

Verify

# Mainnet mediator metrics
curl http://localhost:4234/metrics

# Signet mediator metrics (if enabled)
curl http://localhost:4236/metrics

4. Adding Drawbridge (API Gateway + Tor)

Drawbridge is the L402 API gateway that enables Lightning payments for API access and Lightning zaps between DIDs. The Drawbridge compose layer also brings in Herald, Herald client, Drawbridge client, the Lightning mediator, and a Tor hidden service for privacy.

Enable Drawbridge

Uncomment in docker-compose.yml:

include:
  - docker-compose.drawbridge.yml

Lightning Backend

lightning-mediator owns Archon’s Lightning runtime integrations. Drawbridge talks to it over HTTP for L402 invoice creation and pending-invoice lifecycle, and the mediator owns the public Lightning APIs, LNBits integration, and CLN access.

Drawbridge remains the policy layer: it still owns macaroons, pricing, rate limits, and the final payment records that show which paid requests were granted. Internal admin requests between these services use X-Archon-Admin-Key.

You have two options for the mediator backend:

Option A: External CLN (Bring Your Own)

If you already run a Core Lightning node, point lightning-mediator at it:

ARCHON_LIGHTNING_MEDIATOR_CLN_REST_URL=https://your-cln-host:3001
ARCHON_LIGHTNING_MEDIATOR_CLN_RUNE=your-cln-rune-here

The rune needs permissions for invoice and listinvoices methods. Create one with:

lightning-cli createrune restrictions='[["method^invoice","method^listinvoices"]]'

You can optionally point to an external LNbits instance:

ARCHON_LIGHTNING_MEDIATOR_LNBITS_URL=http://your-lnbits:5000

Option B: Bundled CLN

Include the Lightning stack (see Section 5). Runes and secrets are auto-generated by init containers and shared with lightning-mediator via Docker volumes — no manual configuration needed.

Key Environment Variables

Variable Default Description
ARCHON_DRAWBRIDGE_PORT 4222 Drawbridge API port
ARCHON_DRAWBRIDGE_L402_ENABLED false Enable L402 payment gates
ARCHON_DRAWBRIDGE_DEFAULT_PRICE_SATS 10 Default price per API call (sats)
ARCHON_DRAWBRIDGE_INVOICE_EXPIRY 3600 Invoice expiry in seconds
ARCHON_LIGHTNING_MEDIATOR_URL http://lightning-mediator:4235 Drawbridge’s upstream Lightning mediator
ARCHON_LIGHTNING_MEDIATOR_CLN_REST_URL https://cln:3001 CLN REST endpoint used by the mediator
ARCHON_LIGHTNING_MEDIATOR_CLN_RUNE empty CLN rune used by the mediator; auto-loaded from ./data/cln-mainnet/drawbridge/rune.txt in the bundled stack
ARCHON_LIGHTNING_MEDIATOR_LNBITS_URL http://lnbits:5000 LNbits base URL used by the mediator
ARCHON_DRAWBRIDGE_PUBLIC_HOST (auto) Public Drawbridge URL used for published invoice endpoints
ARCHON_DRAWBRIDGE_RATE_LIMIT_MAX 100 Max requests per window
ARCHON_DRAWBRIDGE_RATE_LIMIT_WINDOW 60 Rate limit window in seconds
ARCHON_DRAWBRIDGE_MACAROON_SECRET (auto) L402 macaroon signing secret (auto-generated)

Auto-Generated Secrets

The Drawbridge entrypoint script handles secrets automatically:

Verify

curl http://localhost:4222/api/v1/ready

Optional UIs when Drawbridge is enabled:


5. Bundled Lightning Stack (Optional)

If you don’t have an existing CLN node, the bundled Lightning stack provides a complete setup with CLN, RTL, and LNbits.

Enable Lightning

Uncomment in docker-compose.yml:

include:
  - docker-compose.lightning.yml
  - docker-compose.drawbridge.yml

Bitcoin RPC

The CLN node needs access to a Bitcoin Core RPC. If you’re also running the BTC mainnet registry, these are the same credentials:

ARCHON_BTC_HOST=your-bitcoin-host
ARCHON_BTC_PORT=8332
ARCHON_BTC_USER=bitcoin
ARCHON_BTC_PASS=bitcoin

Key Environment Variables

Variable Default Description
ARCHON_CLN_ALIAS archon Lightning node alias (visible to peers)
ARCHON_CLN_RGB e33502 Node color (hex)
ARCHON_CLN_PORT 9736 Lightning P2P port
ARCHON_CLN_NETWORK_MODE tor Network mode: tor, hybrid, or clearnet
ARCHON_CLN_ANNOUNCE_ADDR (empty) Announce address (for clearnet/hybrid modes)
ARCHON_CLN_GOVERNANCE_MODE advisor cl-hive governance mode
ARCHON_CLN_LOG_LEVEL info CLN log level
ARCHON_RTL_PASSWORD changeme Change this. RTL web UI password
ARCHON_RTL_PORT 3002 RTL web UI port
ARCHON_LNBITS_PORT 5000 LNbits web UI port

Network Modes

Mode Description
tor Node is only reachable via Tor. Address is not publicly announced.
hybrid Reachable via both Tor and clearnet. Set ARCHON_CLN_ANNOUNCE_ADDR to your public IP/domain.
clearnet Clearnet only. Set ARCHON_CLN_ANNOUNCE_ADDR to your public IP/domain.

Init Containers

Three one-shot init containers automatically create CLN runes:

Container Purpose Rune Location
drawbridge-init Creates rune restricted to invoice/listinvoices methods ./data/cln-mainnet/drawbridge/rune.txt
rtl-init Creates unrestricted rune for RTL ./data/cln-mainnet/rtl/rune.txt
lnbits-init Creates three runes (readonly, invoice, pay) + copies TLS certs ./data/cln-mainnet/lnbits/runes.env

These run once and exit. If a rune file already exists, they skip creation. The bundled LNbits service now runs from the published image ghcr.io/archetech/lnbits:1.5.3-archetech.1.

Important: Back Up Lightning Data

The ./data/cln-mainnet/ directory contains your Lightning wallet, channels, and keys. Back this up regularly. Losing this data means losing funds.

Verify

# RTL web interface
open http://localhost:3002

# LNbits web interface
open http://localhost:5000

# Lightning mediator health
curl http://localhost:4235/ready

6. Production Hardening

Reverse Proxy

Bind services to localhost and put them behind a reverse proxy (nginx, Caddy, etc.) for HTTPS termination:

ARCHON_BIND_ADDRESS=127.0.0.1

Firewall

Only expose ports that need external access:

Port Needs Public Access?
CLN P2P (9736) Yes — for Lightning peer connections
IPFS Swarm (4001) Yes — for IPFS peer connections
Drawbridge (4222) Yes — if accepting external API requests
Gatekeeper (4224) Depends — public for DID resolution, localhost if behind proxy
All others No — bind to localhost

Backups

Back up the entire ./data/ directory regularly. Critical data:

Path Contents Priority
./data/cln-mainnet/ Lightning wallet, channels, keys Critical — loss means lost funds
./data/tor-drawbridge/ Tor hidden service keys High — loss means new .onion address
./data/mongodb/ Registry and wallet-side service state used by bundled Bitcoin mediators High
./data/redis/ Cache (reconstructible) Low

Monitoring

Prometheus scrapes metrics from all services. Grafana is pre-provisioned with dashboards:

Change the default Grafana credentials:

GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=your-secure-password

7. Port Reference

Port Service Default Env Var Binding
4224 Gatekeeper 4224 ARCHON_GATEKEEPER_PORT configurable
4225 Gatekeeper Client 4225 ARCHON_GATEKEEPER_CLIENT_PORT configurable
4226 Keymaster 4226 ARCHON_KEYMASTER_PORT configurable
4223 Drawbridge Client 4223 ARCHON_DRAWBRIDGE_CLIENT_PORT configurable
4228 React Wallet 4228 ARCHON_REACT_WALLET_PORT configurable
4222 Drawbridge 4222 ARCHON_DRAWBRIDGE_PORT public
4230 Herald 4230 ARCHON_HERALD_PORT configurable
4231 Herald Client 4231 ARCHON_HERALD_CLIENT_PORT configurable
4235 Lightning Mediator 4235 ARCHON_LIGHTNING_MEDIATOR_PORT configurable
4000 Explorer 4000 public
9736 CLN P2P 9736 ARCHON_CLN_PORT public
3001 CLN REST 3001 localhost
3002 RTL 3002 ARCHON_RTL_PORT localhost
5000 LNbits 5000 ARCHON_LNBITS_PORT localhost
4240 BTC Signet Wallet API 4240 localhost
4241 BTC Signet Wallet Metrics 4241 localhost
27017 MongoDB 27017 localhost
6379 Redis 6379 localhost
5001 IPFS API 5001 localhost
4001 IPFS Swarm 4001 public
9090 Prometheus 9090 localhost
3000 Grafana 3000 localhost
4232 Hyperswarm Metrics 4232 localhost
4234 BTC Mainnet Metrics 4234 localhost
4236 BTC Signet Metrics 4236 localhost

8. Troubleshooting

CLN Not Syncing

Check Bitcoin RPC connectivity:

docker compose logs cln-mainnet-node | grep -i error

Verify your ARCHON_BTC_HOST, ARCHON_BTC_USER, and ARCHON_BTC_PASS are correct and that the Bitcoin node is reachable from inside the Docker network.

Empty Node Address

This is expected when running in tor network mode — the node is hidden and doesn’t announce a public address. If you need a visible address, switch to hybrid or clearnet mode and set ARCHON_CLN_ANNOUNCE_ADDR.

Init Containers Failing

Rune init containers wait up to 10 minutes for CLN to be ready. Check their logs:

docker compose logs drawbridge-init
docker compose logs rtl-init
docker compose logs lnbits-init

If CLN is taking too long to start (e.g., first-time Tor setup), the init containers will time out. Restart them after CLN is running:

docker compose restart drawbridge-init

Tor Onion Not Resolving

Check that the Tor container created the hostname file:

cat ./data/tor-drawbridge/hostname

If empty or missing, restart the Tor container:

docker compose restart tor

Port Conflicts

If a service fails to start with “address already in use”, check what’s bound to that port:

ss -tlnp | grep :4224

Either stop the conflicting process or change the port via the corresponding environment variable.

Viewing Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f gatekeeper

# Last 100 lines
docker compose logs --tail=100 cln-mainnet-node