Self-Hosted Crypto Infrastructure Monitoring: Docker Healthcheck + Service Recovery
Self-Hosted Crypto Infrastructure Monitoring: Docker Healthcheck + Service Recovery
Running your own self-hosted crypto infrastructure means you're the one accountable when something goes wrong at 2 AM — no support ticket, no status page to refresh, just you and your logs. If your AI agent's wallet daemon goes down mid-trade or during an automated DeFi rebalance, you want to know immediately and recover fast. This post walks through how WAIaaS is built for exactly that scenario: a self-hosted wallet service you can monitor, heal, and operate with full sovereignty over your keys and your server.
Why Self-Hosting Your Agent's Wallet Matters
There's a philosophical question hiding inside every "just use the hosted API" pitch: who actually controls the keys?
When your AI agent executes a token swap, approves a spend, or pays for an API call via the x402 protocol, it's signing transactions. That signing requires private key material. If a third-party service holds those keys, you've introduced custody risk, rate limit risk, and — critically for privacy-conscious operators — a full transaction history that lives on someone else's server.
The alternative is running your own wallet infrastructure. The tradeoff is real: you own the operational burden. But with modern Docker tooling, that burden is much lower than it used to be. WAIaaS ships as a self-contained Docker image with healthchecks, secret management, and a recovery model baked in. The goal of this post is to show you how those pieces fit together so your self-hosted setup stays online and recovers gracefully when it doesn't.
What WAIaaS Ships With, Out of the Box
WAIaaS is a 15-package monorepo that deploys as two Docker images: the main daemon and a push-relay service for notifications. The daemon is the one you'll spend most of your time thinking about — it's the process that holds wallet state, processes transactions through a 7-stage pipeline, and serves a REST API across 39 route modules.
For self-hosters, the relevant defaults are already sensible:
- Default port binding:
127.0.0.1:3100:3100— localhost-only by default, so you're not accidentally exposing the API to the network - Non-root process: runs as UID 1001 inside the container
- Built-in healthcheck in the Docker Compose file
- Auto-provision mode for first-run password generation
- Docker Secrets support for production credential management
Here's the full Compose file WAIaaS ships with:
services:
daemon:
image: ghcr.io/waiaas/waiaas:latest
container_name: waiaas-daemon
ports:
- "127.0.0.1:3100:3100"
volumes:
- waiaas-data:/data
environment:
- WAIAAS_DATA_DIR=/data
- WAIAAS_DAEMON_HOSTNAME=0.0.0.0
env_file:
- path: .env
required: false
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3100/health"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 3
volumes:
waiaas-data:
driver: local
A few things worth highlighting here for anyone running production homelab services:
restart: unless-stopped — Docker will automatically restart the container after crashes or host reboots. The exception is if you explicitly stop it with docker compose down, which is the right behavior: you don't want Docker fighting you when you intentionally bring the service down for maintenance.
Named volume (waiaas-data) — Wallet state, encrypted keys, and transaction history persist in a named volume independent of the container lifecycle. Running docker compose down preserves your data. You'd need docker compose down -v to actually delete it, which is a safe default that protects against accidental data loss.
Healthcheck with start_period: 10s — The daemon gets 10 seconds to initialize before Docker starts counting health failures. This prevents restart loops on slower hardware where startup takes a moment.
First-Run Setup: Auto-Provision and Recovery Keys
The most friction in self-hosted services is usually the first run. WAIaaS solves this with auto-provision mode, which generates a random master password and writes it to /data/recovery.key inside the container:
docker run -d \
--name waiaas \
-p 127.0.0.1:3100:3100 \
-v waiaas-data:/data \
-e WAIAAS_AUTO_PROVISION=true \
ghcr.io/waiaas/waiaas:latest
# Retrieve auto-generated master password
docker exec waiaas cat /data/recovery.key
This is the crypto equivalent of a router generating a random WiFi password on first boot — you get something secure immediately, and you can harden it later. The CLI workflow for this is:
npm install -g @waiaas/cli
waiaas init --auto-provision # Generates random master password → recovery.key
waiaas start # No password prompt
waiaas quickset # Creates wallets + sessions automatically
waiaas set-master # (Later) Harden password, then delete recovery.key
The set-master step is important. Once you've rotated to a password you control and stored securely (a password manager, not a plaintext file), delete recovery.key. The auto-provision key is a bootstrap mechanism, not a permanent credential.
Secrets Management for Production
For anyone running this on a VPS or home server with more than one user account, environment variables in .env files are a step up from hardcoding credentials, but Docker Secrets is the right answer for production.
WAIaaS ships a docker-compose.secrets.yml overlay specifically for this:
# Create secret files
mkdir -p secrets
echo "your-secure-password" > secrets/master_password.txt
chmod 600 secrets/master_password.txt
# Deploy with secrets overlay
docker compose -f docker-compose.yml -f docker-compose.secrets.yml up -d
The secrets overlay pattern means your actual credentials never appear in environment variables that show up in docker inspect output or process listings. This matters if you're running on shared infrastructure or if you're security-conscious about what ends up in container metadata.
Monitoring: What to Watch
The healthcheck gives Docker the signal it needs to restart unhealthy containers, but for actual observability you want more than "is the process alive." Here are the three things worth monitoring on a self-hosted WAIaaS instance:
1. The Health Endpoint
curl http://127.0.0.1:3100/health
This is what the Docker healthcheck pings. Wire this into whatever uptime monitoring you use — Uptime Kuma, Healthchecks.io, a simple cron that sends you a Telegram message. The point is that the daemon's liveness is externally observable without any special credentials.
2. Log Streaming
docker compose logs -f
WAIaaS has configurable log levels via WAIAAS_DAEMON_LOG_LEVEL. For normal operation, info is fine. When you're debugging a transaction that got stuck in the pipeline, dropping to debug gives you stage-by-stage visibility through the 7-stage transaction pipeline (validate → auth → policy → wait → execute → confirm).
For persistent log storage, pipe to a file or use Docker's logging driver:
docker compose logs -f >> /var/log/waiaas/daemon.log 2>&1 &
3. Incoming Transaction Monitoring
WAIaaS has built-in incoming transaction monitoring with real-time notifications for deposits. This means you don't need a separate indexer watching your wallet addresses — the daemon handles it. Pair this with the notification setup CLI command (waiaas notification setup) and you'll get alerts when funds arrive, not just when your agent sends them.
Service Recovery: What Happens When Things Go Wrong
Let's walk through the failure scenarios you actually care about:
Container Crash
restart: unless-stopped handles this automatically. Docker detects the container exit, waits briefly, and restarts it. The named volume means wallet state is intact. The daemon reinitializes, the healthcheck passes, and your AI agent's next API call succeeds. You'll see the restart in docker compose logs and in docker ps output (the "Restarts" column).
Host Reboot
Same story — Docker's restart policy fires on daemon startup. If you're on a system where Docker starts automatically (most Linux distros with systemctl enable docker), WAIaaS comes back up without manual intervention.
Stuck Transaction in the Pipeline
This is the more interesting failure mode. A transaction can get stuck in the DELAY or APPROVAL tier if it's waiting for human approval that never comes, or if the gas condition stage (which checks that gas price meets your threshold before executing) is holding a transaction while gas is elevated.
The CLI gives you visibility here:
waiaas status # Daemon status
From the API side, you can check pending transactions directly:
curl http://127.0.0.1:3100/v1/transactions \
-H "Authorization: Bearer wai_sess_<token>"
For transactions in the APPROVAL tier, the owner approval flow uses WalletConnect or your configured signing channel — push relay or Telegram — so you can approve from your phone without being at your server.
Policy Denial Loops
If your AI agent is getting transactions denied repeatedly, you'll see error responses like:
{
"error": {
"code": "POLICY_DENIED",
"message": "Transaction denied by SPENDING_LIMIT policy",
"domain": "POLICY",
"retryable": false
}
}
The retryable: false flag tells a well-behaved agent not to hammer the endpoint. The fix is either adjusting the policy (via masterAuth) or using the dry-run API to understand exactly what the policy engine sees before making changes:
curl -X POST http://127.0.0.1:3100/v1/transactions/send \
-H "Content-Type: application/json" \
-H "Authorization: Bearer wai_sess_<token>" \
-d '{
"type": "TRANSFER",
"to": "recipient-address",
"amount": "0.1",
"dryRun": true
}'
Dry-run runs the full pipeline including policy evaluation, without submitting the transaction on-chain. It's the fastest way to understand why something is being blocked.
Backup and Restore
The CLI ships with backup create, backup inspect, and backup list commands — 3 of the 20 CLI commands in the WAIaaS CLI. For a self-hosted setup, a sensible backup schedule is:
waiaas backup createbefore any configuration changes- Automated daily backup to a location outside the Docker volume (external drive, encrypted remote storage)
- Periodic
waiaas backup inspectto verify backup integrity
The restore path is waiaas restore, which means you can recover from a corrupted volume without losing wallet state — as long as your backups are current.
RPC Endpoints: The Other Dependency You Control
One thing that often gets overlooked in self-hosted crypto infrastructure: even if you control the wallet daemon, you're still dependent on RPC endpoints for reading chain state and submitting transactions. WAIaaS lets you configure your own:
WAIAAS_RPC_SOLANA_MAINNET=<url> # Solana mainnet RPC endpoint
WAIAAS_RPC_EVM_ETHEREUM_MAINNET=<url> # Ethereum mainnet RPC endpoint
For full sovereignty, point these at your own node, a private RPC provider, or a self-hosted RPC proxy. WAIaaS supports 18 networks across EVM and Solana chain types, so you can configure custom RPC endpoints per-network as needed.
Quick Start: Self-Hosted WAIaaS in Five Minutes
Here's the minimal path to a running, monitored instance:
# 1. Clone and start
git clone https://github.com/waiaas/WAIaaS.git
cd WAIaaS
docker compose up -d
# 2. Check it's healthy
curl http://127.0.0.1:3100/health
# 3. Follow logs
docker compose logs -f
Then, install the CLI and run quickset to create wallets and sessions:
npm install -g @waiaas/cli
waiaas quickset --mode mainnet
For MCP integration with Claude Desktop (so your AI agent can actually use the wallet):
waiaas mcp setup --all
That registers all your wallets with Claude Desktop automatically, writing the configuration JSON you'd otherwise have to craft by hand.
What's Next
The monitoring and recovery patterns here are the operational foundation. Once your instance is stable, the natural next step is tightening your policy configuration — understanding the 21 policy types, setting spending limits, and configuring the 4 security tiers so your AI agent operates within the boundaries you've defined without requiring constant approval. The OpenAPI spec at http://127.0.0.1:3100/reference gives you an interactive UI to explore every endpoint, which is useful when you're building custom monitoring scripts or integrating WAIaaS into a broader homelab automation stack.
The full source, Dockerfiles, and documentation are at https://github.com/waiaas/WAIaaS. If you want to understand the project before deploying anything, the official site at https://waiaas.ai has the overview. Your keys, your server, your rules — that's the point.