One-Command Deployment: Self-Host Your AI Wallet with GHCR A developer introduced WAIaaS, an open-source, self-hosted Wallet-as-a-Service for AI agents, deployable with a single Docker command. The service, published on GitHub Container Registry, allows teams to manage their own private keys and infrastructure, addressing security and data residency concerns for production workloads. The default configuration includes health checks, persistent data volumes, and non-root process execution. Would you trust a third party with your AI agent's private keys? If that question makes you uncomfortable, you're already thinking about self-hosting your wallet infrastructure — and WAIaaS makes it genuinely practical with a single Docker command. This post walks through how to get a fully self-hosted Wallet-as-a-Service running on your own server, with your own keys, under your own rules. The rise of autonomous AI agents changes the stakes around custody. When a human manages a wallet, they can pause, verify, and think before signing. An AI agent operates continuously, potentially making hundreds of transactions — so the infrastructure holding those keys becomes critically important. Hosted wallet services make a trade-off: you get convenience in exchange for trusting someone else's server, someone else's rate limits, and someone else's uptime SLA. For many teams building experimental agents, that's fine. But for anyone running production workloads, handling real funds, or operating in environments with strict data residency requirements, the calculus shifts. Self-hosting gives you: WAIaaS is built specifically for this use case: a self-hosted, open-source Wallet-as-a-Service designed for AI agents, deployable in one command. The Docker image is published to GitHub Container Registry GHCR at ghcr.io/minhoyoo-iotrust/waiaas:latest . The fastest path to a running instance is: git clone https://github.com/minhoyoo-iotrust/WAIaaS.git cd WAIaaS docker compose up -d That's it. The daemon starts on port 3100 , bound to 127.0.0.1 by default — so it's only accessible from localhost until you explicitly expose it. This is a deliberate choice: the default posture is private. If you don't want to clone the repo and just want to run the image directly, the auto-provision flag handles first-run setup without any interactive prompts: docker run -d \ --name waiaas \ -p 127.0.0.1:3100:3100 \ -v waiaas-data:/data \ -e WAIAAS AUTO PROVISION=true \ ghcr.io/minhoyoo-iotrust/waiaas:latest Retrieve auto-generated master password docker exec waiaas cat /data/recovery.key WAIAAS AUTO PROVISION=true tells the entrypoint to generate a random master password on first start and write it to /data/recovery.key . You retrieve it once, store it securely, and the daemon is ready. No wizard, no web UI required at setup time. For anything beyond a quick experiment, you'll want to use the Compose file. Here's what the default configuration looks like: services: daemon: image: ghcr.io/minhoyoo-iotrust/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 noting for the self-hoster audience: Healthcheck is built in. The compose file includes a curl-based healthcheck out of the box. Your orchestrator or monitoring stack can rely on this without any extra configuration. Named volume for persistence. Wallet data, session tokens, and configuration live in the waiaas-data named volume. docker compose down preserves this volume. You need docker compose down -v to actually delete your data — which means accidental container restarts don't lose anything. Non-root process. The daemon runs as UID 1001 inside the container, not as root. This matters for security-conscious deployments where host filesystem permissions are locked down. restart: unless-stopped means the daemon comes back after a server reboot automatically, which is what you want for a persistent agent backend. Putting secrets in environment variables is convenient but leaves them visible in docker inspect output and process listings. For production deployments, WAIaaS ships with a Docker Secrets overlay: 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 docker-compose.secrets.yml overlay file maps the secret into the container via Docker's secrets mechanism rather than environment variables. The entrypoint script knows how to read from Docker Secrets automatically — this is one of the features the entrypoint explicitly supports alongside auto-provision. Self-hosters typically want to tune a few things out of the box: WAIAAS AUTO PROVISION=true Auto-generate master password on first start WAIAAS DAEMON PORT=3100 Listening port WAIAAS DAEMON HOSTNAME=0.0.0.0 Bind address use 127.0.0.1 for localhost-only WAIAAS DAEMON LOG LEVEL=info Log level: trace/debug/info/warn/error WAIAAS DATA DIR=/data Data directory WAIAAS RPC SOLANA MAINNET=