Skip to Content
DocsGuidesSelf-Host Your Own Happy Server

Self-Host Your Own Happy Server

Run your own relay server in minutes. Keep complete control over your Claude Code mobile setup.

Why Run Your Own Server?

When you self-host the Happy Server, you get:

  • Total privacy - Your encrypted data stays on your hardware
  • No limits - Set your own rate limits and storage
  • Team control - Run one server for your whole team
  • Zero dependencies - Never worry about a service shutting down

The entire server is only 1,293 lines of typescript. You can read it yourself to verify it just forwards encrypted messages.

Quick Start

Step 1: Clone and Build

# Get the code git clone https://github.com/slopus/happy-server cd happy-server # Build with Docker docker build -t happy-server:latest .

Step 2: Run the Server

docker run -d \ --name happy-server \ -p 3000:3000 \ -e NODE_ENV=production \ -e DATABASE_URL="postgresql://postgres:postgres@localhost:5432/happy-server" \ -e REDIS_URL="redis://localhost:6379" \ -e SEED="your-seed-for-token-generation" \ -e PORT=3005 \ --restart unless-stopped \ happy-server:latest

Important: Replace the environment variable values with your actual configuration:

  • DATABASE_URL: Your PostgreSQL connection string
  • REDIS_URL: Your Redis connection string
  • SEED: A secure random seed for token generation
  • PORT: The port the application listens on (3005)

Step 3: Configure Your Devices

On your phone:

  1. Open Happy app
  2. Go to Settings
  3. Set “Relay Server URL” to http://your-server:3000
  4. Save

On your computer:

export HANDY_SERVER_URL="http://your-server:3000" # Configure your CLI to use your server

That’s it! Your Happy setup now runs through your own server.

Production Setup with HTTPS

For real use, you want HTTPS. Here’s the easiest way with Caddy:

# Install Caddy (auto-manages SSL certificates) sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy # Configure reverse proxy sudo tee /etc/caddy/Caddyfile <<EOF your-domain.com { reverse_proxy localhost:3000 } EOF # Start Caddy sudo systemctl restart caddy

Now use https://your-domain.com in your Happy Coder settings.

Docker Compose Setup

For easier management, use Docker Compose:

# docker-compose.yml version: '3.8' services: happy-server: image: happy-server:latest ports: - "3000:3000" restart: unless-stopped environment: - NODE_ENV=production - DATABASE_URL=postgresql://postgres:postgres@localhost:5432/handy - REDIS_URL=redis://localhost:6379 - SEED=your-seed-for-token-generation - PORT=3005 depends_on: - postgres - redis postgres: image: postgres:15 environment: - POSTGRES_DB=handy - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data volumes: postgres_data: redis_data:

Run with: docker-compose up -d

This setup includes PostgreSQL and Redis containers that the Happy Server depends on.

Where to Host

Option 1: Home Server (Free)

Run on any computer at home:

  • Raspberry Pi ($35 one-time)
  • Old laptop
  • Mac Mini
  • Desktop that’s always on

Option 2: Cloud VPS ($5-10/month)

  • DigitalOcean: $6/month droplet works great
  • Linode: $5/month shared CPU
  • Vultr: $6/month regular performance
  • Hetzner: €4/month (best value in Europe)

Option 3: Corporate Network

Run inside your company network for team use. The server works behind firewalls and proxies.

System Requirements

Happy Server is lightweight:

For 1-10 developers:

  • 512MB RAM
  • 1 CPU core
  • 10GB storage
  • 100Mbps network

For 10-100 developers:

  • 2GB RAM
  • 2 CPU cores
  • 100GB storage
  • 1Gbps network

Monitor Your Server

Check server health:

# View logs docker logs -f happy-server # Check health endpoint curl http://your-server:3000/health # See connection count curl http://your-server:3000/stats

Backup Your Data

The server stores encrypted blobs in /data. To backup:

# Simple backup tar -czf backup-$(date +%Y%m%d).tar.gz ./data # Or sync to another location rsync -av ./data/ backup-location/

Remember: These backups are encrypted. No one can read them without your device keys.

Security Notes

The Happy Server design keeps your data safe:

  1. Server can’t read your data - Everything is encrypted before sending
  2. No account needed - Authentication uses cryptographic proofs
  3. No logs of your code - Server only logs connection metadata
  4. Open source - Audit the code yourself

For extra security:

  • Use HTTPS in production
  • Run behind a VPN for team deployments
  • Set up fail2ban for brute force protection

Cost Comparison

Self-hosted Happy Server:

  • Home: Free (use existing hardware)
  • VPS: $5-10/month for unlimited use

Commercial alternatives:

  • Omnara: $9/month per user
  • Cursor Mobile: Runs on their VMs
  • Terragon/Siteboon: Usage-based pricing
  • Conductor: $29/month after free tier

Self-hosting saves money and gives you control.

Advanced: Kubernetes Deployment

For teams using Kubernetes, here’s the production configuration:

apiVersion: apps/v1 kind: Deployment metadata: name: happy-server spec: strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 replicas: 1 selector: matchLabels: app: happy-server template: metadata: labels: app: happy-server spec: containers: - name: happy-server image: happy-server:latest # Use your actual image registry ports: - containerPort: 3005 envFrom: - secretRef: name: happy-secrets --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: happy-server-pdb spec: minAvailable: 1 selector: matchLabels: app: happy-server --- apiVersion: v1 kind: Service metadata: name: happy-server spec: selector: app: happy-server ports: - port: 3005 targetPort: 3005 type: ClusterIP

Configuration Notes:

  • All ports now consistently use 3005 (the application’s actual listening port)
  • Uses the happy-secrets secret created in the previous section
  • Update the image name to match your actual container registry

Kubernetes Secrets

Create a secret file for your environment variables:

# happy-secrets.yaml apiVersion: v1 kind: Secret metadata: name: happy-secrets type: Opaque stringData: DATABASE_URL: "postgresql://postgres:postgres@postgres-service:5432/handy" REDIS_URL: "redis://redis-service:6379" SEED: "your-secure-seed-for-token-generation" PORT: "3005" NODE_ENV: "production"

Apply the secret:

kubectl apply -f happy-secrets.yaml

Security Note: Replace the values with your actual configuration. For production:

  • Use a strong, random SEED value
  • Use proper database credentials
  • Consider using external secret management tools like external-secrets-operator with Vault

Next Steps

After setting up your server:

  1. Configure team access
  2. Set up monitoring
  3. Enable voice coding

Running your own Happy Server takes 3 minutes and gives you permanent control over your Claude Code mobile access. No subscriptions, no lock-in, no surprises.

Last updated on