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 stringREDIS_URL
: Your Redis connection stringSEED
: A secure random seed for token generationPORT
: The port the application listens on (3005)
Step 3: Configure Your Devices
On your phone:
- Open Happy app
- Go to Settings
- Set “Relay Server URL” to
http://your-server:3000
- 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:
- Server can’t read your data - Everything is encrypted before sending
- No account needed - Authentication uses cryptographic proofs
- No logs of your code - Server only logs connection metadata
- 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:
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.