Production-ready Docker image for cl-hive Lightning nodes with Tor, WireGuard, and full plugin stack.
- Core Lightning v25+ with all plugins
- Ride The Lightning web interface for node management
- Tor hidden service for privacy
- WireGuard VPN support (optional)
- cl-revenue-ops for fee optimization
- cl-hive for fleet coordination
- CLBOSS - Automated channel management (ksedgwic fork with clboss-unmanage)
- Sling - Rebalancing engine (required by cl-revenue-ops)
- c-lightning-REST - REST API for RTL web interface
- cl-revenue-ops - Fee optimization and profitability tracking
- cl-hive - Fleet coordination and swarm intelligence
- Interactive setup wizard
- Docker secrets management
- Resource limits and reservations
- Security hardening (no-new-privileges, cap_drop)
- Graceful shutdown with HTLC draining
- Automated encrypted backups
- Upgrade/rollback with health checks
- Operational runbooks
- Structured logging
No compilation required. Uses pre-built images from GitHub Container Registry.
cd docker
# Copy and edit environment file
cp .env.example .env
nano .env # Configure Bitcoin RPC, alias, etc.
# Pull and start (no build needed!)
docker-compose pull
docker-compose up -d
# Monitor startup
docker-compose logs -fUpgrade with pre-built images:
docker-compose pull
docker-compose up -dFor developers or when you need custom modifications.
cd docker
# Copy environment and build config
cp .env.example .env
cp docker-compose.build.yml docker-compose.override.yml
nano .env
# Clone cl-revenue-ops (required for build)
git clone https://github.com/lightning-goats/cl_revenue_ops.git ../../cl_revenue_ops
# Build and start
docker-compose up -d --buildHot upgrades (no rebuild):
./scripts/hot-upgrade.shcd docker
# Run the interactive setup wizard
./setup.sh
# This will:
# - Configure Bitcoin RPC connection
# - Set up network and node identity
# - Configure Tor and optional WireGuard
# - Set resource limits
# - Create secrets directory
# - Generate .env and docker-compose.override.yml
# Validate configuration
./scripts/validate-config.sh
# Start the node
docker-compose up -d
# Monitor startup
docker-compose logs -f- Bitcoin Core is synced and RPC accessible
- Adequate disk space (10GB+ recommended)
- Adequate memory (4GB+ recommended)
- Firewall configured (port 9736 for Lightning, 3000 for RTL)
- RTL password changed from default
- Backup strategy planned
For production, use Docker secrets instead of environment variables:
# Create secrets directory
mkdir -p secrets
chmod 700 secrets
# Create secret files
echo "your_bitcoin_rpc_password" > secrets/bitcoin_rpc_password
chmod 600 secrets/bitcoin_rpc_password
# Use production compose file
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -dConfigure in .env or docker-compose.override.yml:
# .env
CPU_LIMIT=4
CPU_RESERVATION=2
MEMORY_LIMIT=8G
MEMORY_RESERVATION=4G# Set backup location and encryption
BACKUP_LOCATION=/backups
BACKUP_ENCRYPTION=true
BACKUP_RETENTION=30 # days
# Run first backup
./scripts/backup.sh
# Verify backup
./scripts/backup.sh --verify| Variable | Default | Description |
|---|---|---|
BITCOIN_RPCHOST |
host.docker.internal |
Bitcoin RPC host |
BITCOIN_RPCPORT |
8332 |
Bitcoin RPC port |
BITCOIN_RPCUSER |
- | Bitcoin RPC username (required) |
BITCOIN_RPCPASSWORD |
- | Bitcoin RPC password (or use secret) |
NETWORK |
bitcoin |
Network: bitcoin, testnet, signet, regtest |
ALIAS |
cl-hive-node |
Node alias |
RGB |
e33502 |
Node color (hex) |
| Variable | Default | Description |
|---|---|---|
LIGHTNING_PORT |
9736 |
Lightning P2P port |
NETWORK_MODE |
tor |
Network mode: tor, clearnet, or hybrid |
ANNOUNCE_ADDR |
- | Public address (required for clearnet/hybrid) |
WIREGUARD_ENABLED |
false |
Enable WireGuard VPN |
TRUSTEDCOIN_ENABLED |
false |
Use trustedcoin instead of bcli (see below) |
Network Modes:
- tor - Tor-only, anonymous, no clearnet exposure (default)
- clearnet - Direct connections only, requires
ANNOUNCE_ADDR - hybrid - Both Tor hidden service and clearnet
| Variable | Default | Description |
|---|---|---|
RTL_ENABLED |
true |
Enable RTL web interface |
RTL_PASSWORD |
changeme |
RTL web interface password (change this!) |
RTL_PORT |
3000 |
RTL web interface port |
COMPOSE_PROFILES |
rtl |
Set to rtl to start RTL (auto-set when RTL_ENABLED=true) |
| Variable | Default | Description |
|---|---|---|
CPU_LIMIT |
4 |
Maximum CPU cores |
CPU_RESERVATION |
2 |
Reserved CPU cores |
MEMORY_LIMIT |
8G |
Maximum memory |
MEMORY_RESERVATION |
4G |
Reserved memory |
| Variable | Description |
|---|---|
WG_PRIVATE_KEY |
Your WireGuard private key |
WG_ADDRESS |
Your VPN IP address (e.g., 10.8.0.2/24) |
WG_PEER_PUBLIC_KEY |
VPN server's public key |
WG_PEER_ENDPOINT |
VPN server endpoint (host:port) |
WG_DNS |
DNS server on VPN (optional) |
| Variable | Default | Description |
|---|---|---|
BACKUP_LOCATION |
/backups |
Backup destination |
BACKUP_RETENTION |
30 |
Days to keep backups |
BACKUP_ENCRYPTION |
true |
Enable GPG encryption |
GPG_KEY_ID |
auto | GPG key for encryption |
| Path | Description |
|---|---|
/data/lightning |
Lightning node data (persistent) |
/backups |
Backup storage |
/etc/wireguard |
WireGuard configuration |
/etc/lightning/custom |
Custom configuration files |
RTL provides a web-based UI for managing your Lightning node.
# RTL is enabled by default when using setup.sh
# Or enable manually by setting in .env:
RTL_ENABLED=true
COMPOSE_PROFILES=rtl
# Start with RTL profile (if not set in .env)
docker-compose --profile rtl up -d
# Access RTL at http://localhost:3000 (or your configured RTL_PORT)
# Default password is set in RTL_PASSWORD (change from 'changeme'!)
# View RTL logs
docker-compose logs -f rtl
# Restart RTL
docker-compose restart rtl
# Disable RTL by removing COMPOSE_PROFILES from .env or:
docker-compose stop rtl# View logs
docker-compose logs -f
# Check node info
docker-compose exec cln lightning-cli getinfo
# Check hive status
docker-compose exec cln lightning-cli hive-status
# Check revenue operations
docker-compose exec cln lightning-cli revenue-status# Create backup
./scripts/backup.sh
# Backup hsm_secret only (fastest, most critical)
./scripts/backup.sh --hsm-only
# Verify backup
./scripts/backup.sh --verify
# List available backups
./scripts/restore.sh --list
# Restore from backup
./scripts/restore.sh /backups/backup_20240101_120000There are three upgrade methods depending on your deployment:
For deployments using pre-built images from GHCR. Fastest and safest.
# Backup first (always!)
./scripts/backup.sh
# Pull new image and restart
docker-compose pull
docker-compose up -d
# Verify
docker-compose exec cln lightning-cli getinfo
docker-compose exec cln lightning-cli hive-statusUpgrade to specific version:
# Edit .env to set version
CL_HIVE_VERSION=2.3.0
# Or override directly
CL_HIVE_VERSION=2.3.0 docker-compose pull
docker-compose up -dUpdates cl-hive and cl-revenue-ops without rebuilding the Docker image. Only works if plugins are mounted from host.
# Check for available updates
./scripts/hot-upgrade.sh --check
# Upgrade all plugins (pulls git changes and restarts lightningd)
./scripts/hot-upgrade.sh
# Upgrade only cl-hive
./scripts/hot-upgrade.sh hive
# Upgrade only cl-revenue-ops
./scripts/hot-upgrade.sh revenueHow it works:
- cl-hive is mounted from the host, so
git pullupdates it immediately - Restarts lightningd via supervisorctl to load new plugin code
- No image rebuild required
Rebuilds the Docker image. Use when upgrading Core Lightning, system packages, or after major changes.
# Preview upgrade
./scripts/upgrade.sh --dry-run
# Perform upgrade (with automatic backup and rollback)
./scripts/upgrade.sh
# Upgrade to specific version
./scripts/upgrade.sh --version v1.2.0
# Manual rollback if needed
./scripts/rollback.sh --latestSee UPGRADE.md for detailed upgrade procedures.
# Recommended: Use pre-stop script
docker-compose exec cln /usr/local/bin/pre-stop.sh
# Then stop
docker-compose stopTor is enabled by default. The hidden service address is created on first start.
docker-compose exec cln cat /var/lib/tor/cln-service/hostnameTo use clearnet instead of Tor, set in .env:
# Clearnet only (no Tor)
NETWORK_MODE=clearnet
ANNOUNCE_ADDR=your.public.ip:9736
# Or hybrid (both Tor and clearnet)
NETWORK_MODE=hybrid
ANNOUNCE_ADDR=your.public.ip:9736WireGuard VPN allows secure connection to your bitcoind backend.
- Get VPN credentials from your administrator
- Run
./setup.shand follow WireGuard prompts - Or configure manually in
.env:
WIREGUARD_ENABLED=true
WG_PRIVATE_KEY=your_generated_private_key
WG_ADDRESS=10.8.0.2/24
WG_PEER_PUBLIC_KEY=server_public_key_here
WG_PEER_ENDPOINT=vpn.example.com:51820
BITCOIN_RPCHOST=10.8.0.1 # Bitcoin via VPNTrustedcoin is an alternative Bitcoin backend that can replace the default bcli plugin. It uses block explorers (mempool.space, blockstream.info, etc.) to get blockchain data.
- VPS deployments without local bitcoind - run a Lightning node without a full Bitcoin node
- Lightweight setups - reduce resource requirements
- Redundancy - hybrid mode provides explorer fallback if bitcoind fails
Perfect for VPS deployments where you don't want to run Bitcoin Core:
# .env configuration
TRUSTEDCOIN_ENABLED=true
# Leave Bitcoin RPC settings empty or commented out:
# BITCOIN_RPCUSER=
# BITCOIN_RPCPASSWORD=In this mode, trustedcoin fetches all blockchain data from public explorers. No bitcoind needed.
Best reliability for production - uses your bitcoind as primary, falls back to explorers if bitcoind is unavailable:
# .env configuration
TRUSTEDCOIN_ENABLED=true
# Configure Bitcoin RPC as normal:
BITCOIN_RPCHOST=host.docker.internal
BITCOIN_RPCPORT=8332
BITCOIN_RPCUSER=your_rpc_username
BITCOIN_RPCPASSWORD=your_rpc_passwordHybrid mode gives you the best of both worlds:
- Primary: Fast, trusted data from your own bitcoind
- Fallback: Explorer queries if bitcoind goes down
| Mode | Trust Model | Recommendation |
|---|---|---|
| bcli (default) | Trust only your bitcoind | Most secure, requires bitcoind |
| Hybrid | Primarily your bitcoind, explorers as fallback | Good balance of security and reliability |
| Explorer-only | Trust third-party explorers | Convenient but less secure |
Explorer-only mode security notes:
- You're trusting multiple public block explorers to provide accurate data
- Explorers could theoretically lie about transaction confirmations
- For high-value nodes, hybrid or bcli mode is recommended
- Acceptable risk for testing, low-value nodes, or when bitcoind isn't available
# Check if trustedcoin is loaded
docker-compose exec cln lightning-cli plugin list | grep trustedcoin
# Check current block height (should match network)
docker-compose exec cln lightning-cli getinfo | jq '.blockheight'
# View trustedcoin logs
docker-compose logs cln | grep -i trustedcoindocker-compose exec cln lightning-cli hive-genesis "my-hive-name"docker-compose exec cln lightning-cli hive-invite 24 # 24 hour validitydocker-compose exec cln lightning-cli hive-join "HIVE1-INVITE-..."docker-compose exec cln lightning-cli hive-membersFor production monitoring, configure Fluent Bit to ship logs to your preferred destination:
# Configure logging
cp logging/fluent-bit.conf.example logging/fluent-bit.conf
# Edit for your Elasticsearch/Loki/etc
# Run Fluent Bit
docker run -d --name fluent-bit \
-v ./logging:/fluent-bit/etc:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
fluent/fluent-bit:latest# Quick health check
docker-compose exec cln lightning-cli getinfo && \
docker-compose exec cln lightning-cli hive-status && \
docker-compose exec cln lightning-cli revenue-status
# Validate configuration
./scripts/validate-config.shCommon cause: Missing rpcallowip in Bitcoin config
Docker containers use a bridge network (typically 172.17.0.0/16 or 172.20.0.0/16). Your Bitcoin Core must allow connections from this network:
# Add to your bitcoin.conf
rpcallowip=172.16.0.0/12 # Covers all Docker networks
# Or more restrictive (check your Docker network)
docker network inspect docker_lightning-network | grep Subnet
rpcallowip=172.20.0.0/16 # Use the subnet shown
# Restart Bitcoin Core after changesSee runbooks/bitcoin-rpc-recovery.md for more details
If the Docker build fails downloading bitcoin-cli from bitcoincore.org (timeout), or lightningd fails with "bitcoin-cli exec failed":
# Copy bitcoin-cli from your host
cp /usr/local/bin/bitcoin-cli docker/bitcoin-cli
# Uncomment the mount in docker-compose.yml:
# - ./bitcoin-cli:/usr/local/bin/bitcoin-cli:ro
# Restart
docker-compose up -dTor Hidden Service Not Created
See runbooks/bridge-circuit-breaker.md
See runbooks/database-corruption.md
See runbooks/emergency-shutdown.md
-
Secrets Management
- Use
secrets/directory for sensitive values - Never commit secrets to version control
- Secrets directory has 700 permissions
- Use
-
Backup Security
- Enable GPG encryption for backups
- Store hsm_secret backup separately and securely
- Test restore procedures regularly
-
Network Security
- Use Tor for privacy
- Use WireGuard for secure Bitcoin RPC connection
- Firewall: only expose necessary ports
-
Container Security
NET_ADMINandNET_RAWcapabilities for Tor/WireGuard- Resource limits prevent DoS
- Processes run as root inside container (required for network config)
-
Updates
- Keep image updated for security fixes
- Use
./scripts/upgrade.shfor safe upgrades - Monitor security advisories
docker/
├── docker-compose.yml # Base compose configuration
├── docker-compose.prod.yml # Production overlay with secrets
├── docker-compose.override.yml # Generated by setup.sh
├── Dockerfile # Image build
├── docker-entrypoint.sh # Container entrypoint
├── supervisord.conf # Process management
├── .env.example # Environment template
├── .env # Your configuration
├── setup.sh # Interactive setup wizard
├── UPGRADE.md # Upgrade procedures
├── secrets/ # Docker secrets (gitignored)
│ └── .gitkeep
├── scripts/
│ ├── backup.sh # Automated backups
│ ├── restore.sh # Restore from backup
│ ├── upgrade.sh # Full image upgrades
│ ├── hot-upgrade.sh # Quick plugin updates (no rebuild)
│ ├── rollback.sh # Rollback to backup
│ ├── pre-stop.sh # Graceful shutdown
│ └── validate-config.sh # Configuration validation
├── logging/
│ ├── fluent-bit.conf # Log shipper config
│ └── parsers.conf # Log parsers
└── runbooks/
├── emergency-shutdown.md
├── bitcoin-rpc-recovery.md
├── tor-recovery.md
├── channel-force-close.md
├── bridge-circuit-breaker.md
└── database-corruption.md
Pre-built multi-architecture images are available on GitHub Container Registry:
# Pull latest stable release
docker pull ghcr.io/lightning-goats/cl-hive-node:latest
# Pull specific version
docker pull ghcr.io/lightning-goats/cl-hive-node:2.2.1
# Available architectures:
# - linux/amd64 (x86_64)
# - linux/arm64 (Apple Silicon, Raspberry Pi 4+)Advantages of pre-built images:
- No compilation required (faster startup)
- Tested and verified before release
- Consistent across all deployments
- Easy upgrades:
docker-compose pull && docker-compose up -d
For developers or custom modifications:
# Prerequisites: Clone cl-revenue-ops next to cl-hive
git clone https://github.com/lightning-goats/cl_revenue_ops.git ../cl_revenue_ops
# Use the build override
cp docker-compose.build.yml docker-compose.override.yml
# Build
docker-compose build
# Or build directly
docker build -t cl-hive-node:local -f docker/Dockerfile ..| Component | Version | Required |
|---|---|---|
| Ubuntu | 24.04 | Yes |
| Core Lightning | v25.12.1 | Yes |
| CLBOSS | latest (ksedgwic fork) | Yes |
| Sling | v4.1.3 | Yes |
| Trustedcoin | v0.8.6 | Optional |
| c-lightning-REST | v0.10.7 | Yes |
| cl-revenue-ops | latest (from GitHub) | Yes |
| cl-hive | bundled | Yes |
| Tor | 0.4.8.x | Yes |
| WireGuard | 1.0.x | Optional |
| Python | 3.12 | Yes |
| Ride The Lightning | 0.15.2 | Yes |
- Documentation: See the
runbooks/directory for operational procedures - Issues: Report bugs at https://github.com/lightning-goats/cl-hive/issues
- Upgrades: See UPGRADE.md for version-specific notes