This guide walks you through deploying an Archon node, from a core DID-only setup to a full registry, Drawbridge, and Lightning-enabled stack. Each section builds on the previous one — start with the core and add layers as needed.
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.
All persistent data lives under ./data/. Create the directory and ensure it’s owned by your user:
mkdir -p data
The base docker-compose.yml always includes the optional compose fragments, but their services are gated by Docker Compose profiles. Leave COMPOSE_PROFILES empty to run only the core DID services: MongoDB, Redis, IPFS, Gatekeeper, and Keymaster.
Set COMPOSE_PROFILES in .env to the comma-separated optional services you want:
# Core DID node only
COMPOSE_PROFILES=
# Example full-ish node
COMPOSE_PROFILES=hyperswarm,cli,explorer,gatekeeper-client,keymaster-client,react-wallet,observability,btc-signet
Available profiles: hyperswarm, cli, explorer, gatekeeper-client, keymaster-client, react-wallet, observability, btc-mainnet, btc-signet, btc-testnet4, lightning, drawbridge, zcash-mainnet, eth-mainnet, eth-sepolia, sol-mainnet, sol-devnet, pinning, and filecoin.
| 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 |
COMPOSE_PROFILES |
sample default | Optional Docker Compose service profiles |
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.8-beta |
Hyperswarm protocol identifier |
ARCHON_GATEKEEPER_CONFIRM_FALLBACK_URL |
(empty) | Optional Gatekeeper peer for confirm=true resolution when local data is not confirmed |
| 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 |
| zcash-mainnet-mediator | Optional transparent Zcash DID anchoring |
| zcash-mainnet-wallet | Optional transparent Zcash wallet for anchoring transactions |
| 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 |
| pinning-mediator | Optional generic IPFS pinning service backup |
COMPOSE_PROFILES= docker compose up -d
docker compose logs -f gatekeeper # watch for startup
# Verify gatekeeper is running
curl http://localhost:4224/api/v1/version
Optional UIs when their profiles are enabled:
http://localhost:4225http://localhost:4226http://localhost:4228http://localhost:4000Bitcoin 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 |
Add the relevant profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,btc-mainnet
# or
COMPOSE_PROFILES=hyperswarm,btc-signet
| 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.
Add Bitcoin registries to the gatekeeper’s registry list:
ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,BTC:mainnet
# Mainnet mediator metrics
curl http://localhost:4234/metrics
# Signet mediator metrics (if enabled)
curl http://localhost:4236/metrics
Zcash support is optional. If enabled, the Zcash registry anchors DID batches in transparent Zcash transactions via the Zcash mediator. The bundled compose layer includes both zcash-mainnet-mediator and a companion zcash-mainnet-wallet service. It expects an external Zebra node with RPC access; Zebra provides chain, address-index, and broadcast RPCs while the wallet derives transparent keys from Keymaster and signs locally.
Only transparent Zcash flows are supported in this stack. Shielded and unified-address wallet flows are intentionally out of scope for the current mediator.
Add the Zcash profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,zcash-mainnet
| Variable | Default | Description |
|---|---|---|
ARCHON_ZEC_HOST |
none | Zebra RPC host |
ARCHON_ZEC_PORT |
8232 |
Zebra RPC port |
ARCHON_ZEC_USER |
(empty) | Zebra RPC username, if configured |
ARCHON_ZEC_PASS |
(empty) | Zebra RPC password, if configured |
ARCHON_WALLET_ZEC_FALLBACK_FEE_ZAT_KB |
10000 |
Wallet fallback fee in zatoshis per KB |
ARCHON_ZEC_CHAIN |
ZEC:mainnet |
Gatekeeper registry name |
ARCHON_ZEC_NETWORK |
mainnet |
Zcash network name |
ARCHON_ZEC_START_BLOCK |
3339235 |
Block height to start scanning |
ARCHON_ZEC_IMPORT_INTERVAL |
1 |
Minutes between import scans; 0 disables importing |
ARCHON_ZEC_EXPORT_INTERVAL |
1 |
Minutes between export attempts; 0 makes the mediator read-only |
ARCHON_ZEC_FEE_BLOCK_TARGET |
1 |
Fee target used for local/oracle fee selection |
ARCHON_ZEC_FEE_FALLBACK_ZAT_BYTE |
10 |
Mediator fallback fee in zatoshis per virtual byte |
ARCHON_ZEC_FEE_MAX |
0.00010000 |
Maximum fee budget in ZEC |
ARCHON_ZEC_FEE_ORACLE_URL |
(empty) | Optional external fee oracle |
ARCHON_ZEC_RBF_ENABLED |
false |
Config parity flag; fee bumping is not supported yet |
ARCHON_ZEC_REIMPORT |
true |
Reprocess discovered batches on startup |
ARCHON_ZEC_DB |
json |
Mediator state backend: json, sqlite, mongodb, or redis |
# Zcash mediator metrics
curl http://localhost:4238/metrics
# Zcash wallet metrics
curl http://localhost:4251/metrics
Grafana includes chain mediator dashboards, including Zcash Mediator (ZEC:mainnet), when the observability stack is enabled.
If you do not enable the zcash-mainnet profile, you can still delegate confirmed Zcash resolution to another Gatekeeper node that does track ZEC:mainnet:
ARCHON_GATEKEEPER_CONFIRM_FALLBACK_URL=https://gatekeeper.example.com
This fallback is only used for confirm=true requests when the local node can resolve a DID but cannot confirm it locally. It does not import Zcash events, run a wallet, or make this node able to anchor new Zcash operations.
Ethereum support is optional. If enabled, the Ethereum registry anchors DID batches by submitting transactions to a canonical ArchonRegistry smart contract and importing its ArchonBatch events. The bundled compose layers include mainnet (eth-mainnet-mediator plus eth-mainnet-wallet) and Sepolia (eth-sepolia-mediator plus eth-sepolia-wallet) variants. The wallet derives an EVM account from the Keymaster mnemonic and signs transactions; the mediator scans logs and imports batches.
Mainnet uses the canonical ETH:mainnet contract. Sepolia is intended for testing. Future production L2 deployments should use a canonical contract on the chosen chain, with L2s such as Base, Optimism, or Arbitrum preferred when low anchoring cost matters.
Ethereum mediators record Gatekeeper block checkpoints for the configured start block, every 10th confirmed block, and every block that contains an ArchonBatch event. This keeps timestamp bounds tight without storing every empty Ethereum block in Gatekeeper.
Add the Ethereum mainnet profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,eth-mainnet
Add the registry to Gatekeeper:
ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,ETH:mainnet
For test deployments, use the Sepolia profile instead:
COMPOSE_PROFILES=hyperswarm,eth-sepolia
Add the registry to Gatekeeper:
ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,ETH:sepolia
| Variable | Default | Description |
|---|---|---|
ARCHON_ETH_RPC_URL |
none | Ethereum JSON-RPC endpoint |
ARCHON_ETH_CONTRACT |
none | Canonical ArchonRegistry contract address |
ARCHON_ETH_CHAIN |
ETH:mainnet |
Gatekeeper registry name |
ARCHON_ETH_NETWORK |
mainnet |
Ethereum network name |
ARCHON_ETH_CHAIN_ID |
1 |
EVM chain ID |
ARCHON_ETH_START_BLOCK |
0 |
Block height to start scanning |
ARCHON_ETH_CONFIRMATIONS |
12 |
Confirmations before logs are imported |
ARCHON_ETH_LOG_CHUNK_SIZE |
2000 |
Blocks per eth_getLogs request |
ARCHON_ETH_IMPORT_INTERVAL |
1 |
Minutes between import scans; 0 disables importing |
ARCHON_ETH_EXPORT_INTERVAL |
1 |
Minutes between export attempts; 0 makes the mediator read-only |
ARCHON_ETH_REIMPORT |
true |
Reprocess discovered batches on startup |
ARCHON_ETH_DB |
json |
Mediator state backend: json, sqlite, mongodb, or redis |
ARCHON_WALLET_ETH_DERIVATION_PATH |
m/44'/60'/0'/0/0 |
EVM account derivation path |
# Ethereum mainnet mediator metrics
curl http://localhost:4246/metrics
# Ethereum mainnet wallet metrics
curl http://localhost:4255/metrics
# Ethereum Sepolia mediator metrics
curl http://localhost:4239/metrics
# Ethereum Sepolia wallet metrics
curl http://localhost:4253/metrics
The reference Solidity contract lives at services/mediators/ethereum/contracts/ArchonRegistry.sol.
Solana support is optional. If enabled, the Solana registry anchors DID batches by submitting Solana Memo transactions with an Archon-specific payload and importing matching memos back into Gatekeeper. The bundled compose layers include mainnet (sol-mainnet-mediator plus sol-mainnet-wallet) and devnet (sol-devnet-mediator plus sol-devnet-wallet) variants. The wallet derives a Solana account from the Keymaster mnemonic and signs transactions; the mediator scans an Archon registry address included in Memo transactions and imports batches.
Mainnet uses the canonical SOL:mainnet-beta memo registry. Devnet is intended for testing. Future custom Solana programs should use a distinct canonical registry decision.
Add the Solana mainnet profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,sol-mainnet
Add the registry to Gatekeeper:
ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,SOL:mainnet-beta
For test deployments, use the Devnet profile instead:
COMPOSE_PROFILES=hyperswarm,sol-devnet
Add the registry to Gatekeeper:
ARCHON_GATEKEEPER_REGISTRIES=hyperswarm,SOL:devnet
| Variable | Default | Description |
|---|---|---|
ARCHON_SOL_RPC_URL |
https://api.mainnet-beta.solana.com |
Solana JSON-RPC endpoint |
ARCHON_SOL_CHAIN |
SOL:mainnet-beta |
Gatekeeper registry name |
ARCHON_SOL_NETWORK |
mainnet-beta |
Solana network name |
ARCHON_SOL_COMMITMENT |
confirmed |
Commitment level for reads and writes |
ARCHON_SOL_MEMO_PROGRAM_ID |
Memo program | Memo program ID used for Archon anchors |
ARCHON_SOL_REGISTRY_ADDRESS |
derived | Address included in Archon memo transactions and scanned for discovery |
ARCHON_SOL_START_BLOCK |
0 |
Produced block height to start checkpointing and importing/registering |
ARCHON_SOL_SIGNATURE_PAGE_LIMIT |
100 |
Signatures per scan page |
ARCHON_SOL_SIGNATURE_PAGE_MAX |
20 |
Maximum scan pages per import loop |
ARCHON_SOL_PENDING_TX_TIMEOUT_SLOTS |
150 |
Slots to wait before re-anchoring stale pending transactions |
ARCHON_SOL_IMPORT_INTERVAL |
1 |
Minutes between import scans; 0 disables importing |
ARCHON_SOL_EXPORT_INTERVAL |
1 |
Minutes between export attempts; 0 makes the mediator read-only |
ARCHON_SOL_REIMPORT |
true |
Reprocess discovered batches on startup |
ARCHON_SOL_DB |
json |
Mediator state backend: json, sqlite, mongodb, or redis |
ARCHON_WALLET_SOL_DERIVATION_PATH |
m/44'/501'/0'/0' |
Solana account derivation path |
# Solana mainnet mediator metrics
curl http://localhost:4248/metrics
# Solana mainnet wallet metrics
curl http://localhost:4257/metrics
# Solana Devnet mediator metrics
curl http://localhost:4249/metrics
# Solana Devnet wallet metrics
curl http://localhost:4263/metrics
Archon can back up selected operation CIDs to an external IPFS pinning service through the generic pin queue. This is cheaper than per-operation Filecoin storage for small DID operations and keeps the provider separate from canonical DID registries.
Add the pinning profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,pinning
Then choose which registries Gatekeeper should copy into the pin queue:
ARCHON_GATEKEEPER_REGISTRIES_PIN=BTC:mainnet,ZEC:mainnet
Local and ephemeral operations are not pinned unless explicitly queued by Gatekeeper policy.
The mediator uses the standard IPFS Pinning Service API. Filebase and Pinata both expose compatible endpoints:
# Filebase
ARCHON_PIN_PROVIDER=filebase
ARCHON_PIN_API_URL=https://api.filebase.io/v1/ipfs
ARCHON_PIN_API_TOKEN=your-filebase-token
# Pinata
ARCHON_PIN_PROVIDER=pinata
ARCHON_PIN_API_URL=https://api.pinata.cloud/psa
ARCHON_PIN_API_TOKEN=your-pinata-jwt
If your IPFS node has known reachable multiaddrs, pass them so the provider can fetch CIDs directly:
ARCHON_PIN_ORIGINS=/ip4/203.0.113.10/tcp/4001/p2p/12D3KooW...
| Variable | Default | Description |
|---|---|---|
ARCHON_GATEKEEPER_REGISTRIES_PIN |
(empty) | Registries copied into the generic pin queue |
ARCHON_PIN_PROVIDER |
filebase |
Provider label used in logs, state, and metrics |
ARCHON_PIN_API_URL |
Filebase PSA endpoint | IPFS Pinning Service API base URL |
ARCHON_PIN_API_TOKEN |
(empty) | Bearer token for the pinning provider |
ARCHON_PIN_ORIGINS |
(empty) | Optional comma-separated multiaddrs for origin IPFS nodes where the provider can fetch CIDs |
ARCHON_PIN_IMPORT_INTERVAL |
1 |
Minutes between pin queue import attempts |
curl http://localhost:4273/metrics
The mediator leaves operations queued while a provider reports queued or pinning, and clears them only after the provider reports pinned.
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.
Add the Drawbridge profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=hyperswarm,drawbridge
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:
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
Enable the lightning profile, or enable drawbridge, which also starts the bundled Lightning dependency stack. Runes and secrets are auto-generated by init containers and shared with lightning-mediator via Docker volumes — no manual configuration needed.
| 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) |
The Drawbridge entrypoint script handles secrets automatically:
./data/drawbridge/macaroon-secret.txt./data/cln-mainnet/drawbridge/rune.txt (created by drawbridge-init container).onion address if not setcurl http://localhost:4222/api/v1/ready
Optional UIs when Drawbridge is enabled:
http://localhost:4231http://localhost:4223If you don’t have an existing CLN node, the bundled Lightning stack provides a complete setup with CLN, RTL, and LNbits.
Add the Lightning profile to COMPOSE_PROFILES:
COMPOSE_PROFILES=lightning
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
| 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 |
| 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. |
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.
The ./data/cln-mainnet/ directory contains your Lightning wallet, channels, and keys. Back this up regularly. Losing this data means losing funds.
# RTL web interface
open http://localhost:3002
# LNbits web interface
open http://localhost:5000
# Lightning mediator health
curl http://localhost:4235/ready
Bind services to localhost and put them behind a reverse proxy (nginx, Caddy, etc.) for HTTPS termination:
ARCHON_BIND_ADDRESS=127.0.0.1
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 |
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/ZEC:mainnet-mediator.json or ./data/ZEC:mainnet-mediator.db |
Zcash mediator scan/export state when using local JSON or SQLite storage | High |
./data/redis/ |
Cache (reconstructible) | Low |
Prometheus scrapes metrics from all services. Grafana is pre-provisioned with dashboards:
admin / admin)Change the default Grafana credentials:
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=your-secure-password
| 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 |
| 4227 | Keymaster Client | 4227 | ARCHON_KEYMASTER_CLIENT_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 |
| 9050 | Tor SOCKS | 9050 | ARCHON_TOR_SOCKS_PORT |
configurable |
| 38332 | BTC Signet Node RPC | 38332 | – | localhost |
| 4232 | Hyperswarm Metrics | 4232 | – | localhost |
| 4234 | BTC Mainnet Mediator Metrics | 4234 | – | localhost |
| 4236 | BTC Signet Mediator Metrics | 4236 | – | localhost |
| 4238 | Zcash Mainnet Mediator Metrics | 4238 | – | localhost |
| 4239 | Ethereum Sepolia Mediator Metrics | 4239 | – | localhost |
| 4246 | Ethereum Mainnet Mediator Metrics | 4246 | – | localhost |
| 4248 | Solana Mainnet Mediator Metrics | 4248 | – | localhost |
| 4249 | Solana Devnet Mediator Metrics | 4249 | – | localhost |
| 4240 | BTC Signet Wallet API | 4240 | – | localhost |
| 4241 | BTC Signet Wallet Metrics | 4241 | – | localhost |
| 4242 | BTC Mainnet Wallet API | 4242 | – | localhost |
| 4243 | BTC Mainnet Wallet Metrics | 4243 | – | localhost |
| 4244 | BTC Testnet4 Wallet API | 4244 | – | localhost |
| 4245 | BTC Testnet4 Wallet Metrics | 4245 | – | localhost |
| 4250 | Zcash Mainnet Wallet API | 4250 | – | localhost |
| 4251 | Zcash Mainnet Wallet Metrics | 4251 | – | localhost |
| 4252 | Ethereum Sepolia Wallet API | 4252 | – | localhost |
| 4253 | Ethereum Sepolia Wallet Metrics | 4253 | – | localhost |
| 4254 | Ethereum Mainnet Wallet API | 4254 | – | localhost |
| 4255 | Ethereum Mainnet Wallet Metrics | 4255 | – | localhost |
| 4256 | Solana Mainnet Wallet API | 4256 | – | localhost |
| 4257 | Solana Mainnet Wallet Metrics | 4257 | – | localhost |
| 4262 | Solana Devnet Wallet API | 4262 | – | localhost |
| 4263 | Solana Devnet Wallet Metrics | 4263 | – | localhost |
| 4270 | Filecoin Wallet API | 4270 | – | localhost |
| 4271 | Filecoin Mediator Metrics | 4271 | – | localhost |
| 4272 | Filecoin Wallet Metrics | 4272 | – | localhost |
| 4273 | Pinning Mediator Metrics | 4273 | – | 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 | ARCHON_GRAFANA_PORT |
configurable |
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.
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.
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
Check Zebra RPC connectivity and credentials:
docker compose logs zcash-mainnet-mediator
docker compose logs zcash-mainnet-wallet
curl http://localhost:4238/metrics
Verify ARCHON_ZEC_HOST, ARCHON_ZEC_PORT, ARCHON_ZEC_USER, and ARCHON_ZEC_PASS are correct and reachable from inside the Docker network. Also confirm ARCHON_GATEKEEPER_REGISTRIES includes ZEC:mainnet; otherwise Gatekeeper will not accept queued Zcash operations.
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
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.
# All services
docker compose logs -f
# Specific service
docker compose logs -f gatekeeper
# Last 100 lines
docker compose logs --tail=100 cln-mainnet-node