Setup
Configure your SSH keys, set up the miner, and deploy.
Generate SSH keys
Your miner needs an SSH key to reach your GPU nodes. This key grants passage to each machine.
ssh-keygen -t ed25519 -f ~/.ssh/miner_node_key -C "basilica-miner" -N ""
chmod 600 ~/.ssh/miner_node_keyDeploy to each GPU node:
ssh-copy-id -i ~/.ssh/miner_node_key.pub basilica@<node_ip>Verify:
ssh -i ~/.ssh/miner_node_key basilica@<node_ip> "hostname && nvidia-smi --query-gpu=name --format=csv,noheader"Configure the miner
Clone the Basilica repo and copy the config template:
git clone https://github.com/one-covenant/basilica.git
mkdir -p config
cp basilica/config/miner.toml.example config/miner.tomlEdit config/miner.toml with your settings:
Bittensor
[bittensor]
wallet_name = "miner_wallet"
hotkey_name = "default"
external_ip = "<your_public_ip>" # curl -4 ifconfig.me
axon_port = 50051
network = "finney" # Mainnet
netuid = 39 # Mainnet subnet
chain_endpoint = "wss://entrypoint-finney.opentensor.ai:443"Open the axon port on your firewall:
sudo ufw allow 50051/tcpDatabase
[database]
url = "sqlite:///opt/basilica/data/miner.db"
run_migrations = truesudo mkdir -p /opt/basilica/data && sudo chown $USER:$USER /opt/basilica/dataDefine your nodes
List your GPU nodes below. Every GPU category listed here must have a matching price in the bidding section.
[node_management]
nodes = [
{ host = "192.168.1.100", port = 22, username = "basilica", gpu_category = "H100", gpu_count = 8 },
{ host = "192.168.1.101", port = 22, username = "basilica", gpu_category = "A100", gpu_count = 8, extra_mount_path = "/ephemeral" },
]host must be an IPv4 address, not a hostname.
extra_mount_path is optional. Set it if your node has NVMe/SSD storage mounted at a dedicated path (e.g., /ephemeral). The storage will be made available to rental containers.
Set your prices
Price each GPU type per hour in dollars. Every category in your node list must have an entry here.
[bidding.strategy.static.static_prices]
H100 = 2.50 # $2.50/hr per GPU
A100 = 1.20 # $1.20/hr per GPUThe validator enforces a minimum bid floor (default 10% of baseline market price). Bids below this are rejected.
SSH
[ssh_session]
miner_node_key_path = "~/.ssh/miner_node_key"
default_node_username = "basilica"Choose a validator
[validator_assignment]
strategy = "highest_stake" # Recommended: auto-selects highest-stake validatorUse fixed_assignment with a validator_hotkey only for debugging.
Metrics (Optional)
[metrics]
enabled = true
[metrics.prometheus]
host = "127.0.0.1"
port = 9090Deploy
Docker Compose (Recommended)
Clone the Basilica repo and use the production compose file:
# If you haven't already cloned the repo during configuration:
git clone https://github.com/one-covenant/basilica.git
cp basilica/scripts/miner/compose.prod.yml compose.yml
docker compose up -dWatchtower handles automatic image updates. Check status:
docker compose ps
docker compose logs -f minerBuild from source
# Build
./scripts/miner/build.sh
# Run
sudo mkdir -p /opt/basilica/{data,config}
sudo cp miner.toml /opt/basilica/config/
./basilica-miner --config /opt/basilica/config/miner.tomlVerify it's working
After the miner starts, look for these messages in the logs:
Node registered: your nodes were accepted by the validatorValidator authenticated: the validator's SSH key was deployed
# Docker Compose
docker compose logs -f miner
# Binary
# check terminal output directly
# Metrics
curl http://localhost:9090/metricsTroubleshooting
Miner won't start
- Verify wallet exists:
ls ~/.bittensor/wallets/<wallet_name>/hotkeys/<hotkey_name> - Check config:
./basilica-miner --config miner.toml config validate - Ensure every GPU category in nodes has a matching price in
static_prices
Nodes not registering
- Verify SSH access:
ssh -i ~/.ssh/miner_node_key basilica@<node_ip> - Check that
external_ipis your actual public IP - Ensure axon port (50051) is open
Validator rejects bids
Your bid price may be below the minimum floor. Check logs for the required minimum and adjust static_prices.
How bans work
Validators track node misbehaviour and can temporarily ban nodes that repeatedly fail in ways that affect rentals.
A ban triggers when a node accumulates 3+ misbehaviour events within any rolling 24-hour window.
| Offences Recorded In The Last 7 Days | Ban Duration |
|---|---|
| 1 | 1 hour |
| 2 | 2 hours |
| 3 | 4 hours |
| 4 | 8 hours |
| 5+ | 24 hours |
In practice, the first ban that actually activates is usually 4 hours, because bans do not trigger until the third qualifying misbehaviour.
Misbehaviour events currently include:
- Deployment failures during rental startup
- Interrupted or halted rentals detected by validator health checks
- GPU declaration mismatches detected during full validation
Bans clear automatically. Fix the root cause (drivers, reachability, Docker) and wait for expiry.
Next Steps
- Emissions: Understand how you earn