Skip to content

GodSEye Proxy

A production-ready reverse proxy for PostHog Cloud that helps you:

  • Bypass ad blockers - Use your own domain instead of us.i.posthog.com
  • Handle large payloads - Supports up to 64MB for session recordings
  • Multi-region support - Route different domains to US or EU PostHog regions
  • Proper CORS - Configurable CORS headers for browser-based tracking
Terminal window
godseye-proxy config generate --output godseye.config.yml

Edit the config to use your domain:

server:
host: '0.0.0.0'
port: 64980
routes:
- domain: 'e.yourdomain.com' # Change this to your subdomain
posthog_host: 'us.i.posthog.com'
assets_host: 'us-assets.i.posthog.com'
Terminal window
godseye-proxy serve --config godseye.config.yml

Update your PostHog initialization to use your proxy domain:

posthog.init('phc_YOUR_PROJECT_KEY', {
api_host: 'https://e.yourdomain.com', // Your proxy domain
ui_host: 'https://us.posthog.com', // PostHog UI (don't proxy this)
});

That’s it! PostHog will now send events through your proxy.

The proxy forwards requests while overriding the Host header (critical for PostHog):

Client Request:
POST https://e.yourdomain.com/capture
Godseye Proxy Forwards:
POST https://us.i.posthog.com/capture
Host: us.i.posthog.com ← Critical!

Static assets are routed to the assets host:

Client Request:
GET https://e.yourdomain.com/static/array.js
Godseye Proxy Forwards:
GET https://us-assets.i.posthog.com/static/array.js
Host: us-assets.i.posthog.com

Point your subdomain to where godseye-proxy is running:

e.yourdomain.com → A/CNAME → your-server-ip or your-server-domain.com

Create docker-compose.yml:

version: '3.8'
services:
godseye-proxy:
image: godseye-proxy:latest
ports:
- '64980:64980'
environment:
GODSEYE_SERVER__PORT: 64980
GODSEYE_OBSERVABILITY__LOGGING__LEVEL: info
volumes:
- ./godseye.config.yml:/etc/godseye/godseye.config.yml:ro
restart: unless-stopped

Run:

Terminal window
docker-compose up -d

Override any config value with environment variables:

Terminal window
# Server
GODSEYE_SERVER__HOST=0.0.0.0
GODSEYE_SERVER__PORT=64980
# Logging
GODSEYE_OBSERVABILITY__LOGGING__LEVEL=debug
GODSEYE_OBSERVABILITY__LOGGING__FORMAT=json
# Limits
GODSEYE_LIMITS__MAX_BODY_SIZE=67108864
Terminal window
# Start server (default)
godseye-proxy
godseye-proxy serve --port 8080
# Configuration management
godseye-proxy config show
godseye-proxy config validate --file config.yml
godseye-proxy config generate --output config.yml
# Test route resolution
godseye-proxy config test-route e.yourdomain.com /capture
# Health check (for Docker/K8s)
godseye-proxy health --target http://localhost:64980
# Version info
godseye-proxy version --detailed

Route different domains to different PostHog regions:

routes:
# US customers
- domain: 'e-us.yourdomain.com'
posthog_host: 'us.i.posthog.com'
assets_host: 'us-assets.i.posthog.com'
description: 'US region'
# EU customers
- domain: 'e-eu.yourdomain.com'
posthog_host: 'eu.i.posthog.com'
assets_host: 'eu-assets.i.posthog.com'
description: 'EU region'
  1. Don’t use obvious tracking subdomains - Avoid analytics., tracking., or posthog. in your subdomain
  2. Use HTTPS - Always run behind a TLS terminator (nginx, Caddy, Cloudflare, etc.)
  3. Set ui_host - Configure ui_host: 'https://us.posthog.com' in PostHog init for toolbar authentication
  4. Monitor limits - PostHog session recordings can be up to 64MB per message

The proxy exposes a health endpoint at /health:

Terminal window
curl http://localhost:64980/health
# {"status":"healthy","service":"godseye-proxy"}

Use this for Docker healthchecks and Kubernetes liveness probes.

  1. Check the proxy logs for errors
  2. Verify DNS points to your proxy
  3. Ensure api_host in PostHog init matches your domain
  4. Check that Host header override is working (logs show target host)

Update the cors section in your config:

cors:
allow_origins: ['https://yourdomain.com'] # Your actual domain
allow_credentials: true # If you need cookies

Increase the body size limit:

limits:
max_body_size: 134217728 # 128MB

See the repository root for license information.