A configurable Caddy-based reverse proxy for PostHog analytics with Docker support and automatic publishing to GitHub Container Registry.
- 🚀 Reverse proxy for PostHog analytics
- 🔧 Environment variable configuration
- 🐳 Docker and Docker Compose support
- 📦 Automatic multi-platform builds (amd64/arm64)
- 🔄 GitHub Actions CI/CD pipeline
- 🔐 SSL/TLS support via Caddy (auto-provisioned)
- 📊 Support for both US and EU PostHog regions
- 💓 Health check endpoint (
/healthz) for monitoring
- Clone this repository:
git clone https://github.com/yourusername/ph-caddy-proxy.git
cd ph-caddy-proxy- Copy the example environment file:
cp .env.example .env- Edit
.envwith your configuration:
nano .env- Start the proxy:
docker-compose up -ddocker run -d \
--name ph-caddy-proxy \
-p 80:80 \
-p 443:443 \
-e TRACKING_DOMAIN=tracking.example.com \
-e POSTHOG_HOST=us.i.posthog.com \
-e POSTHOG_ASSETS_HOST=us-assets.i.posthog.com \
-e SSL_ENABLED=true \
-v caddy_data:/data \
-v caddy_config:/config \
ghcr.io/yourusername/ph-caddy-proxy:latestdocker pull ghcr.io/yourusername/ph-caddy-proxy:latest| Variable | Description | Default |
|---|---|---|
TRACKING_DOMAIN |
Your tracking domain (e.g., tracking.example.com) | localhost |
POSTHOG_HOST |
PostHog API host | us.i.posthog.com |
POSTHOG_ASSETS_HOST |
PostHog assets host | us-assets.i.posthog.com |
SSL_ENABLED |
Enable HTTPS/SSL (set to false for local dev or behind proxy) | true |
DEBUG |
Enable debug mode to see generated Caddyfile | false |
POSTHOG_HOST=us.i.posthog.com
POSTHOG_ASSETS_HOST=us-assets.i.posthog.comPOSTHOG_HOST=eu.i.posthog.com
POSTHOG_ASSETS_HOST=eu-assets.i.posthog.comOnce your proxy is running, update your PostHog JavaScript snippet:
<script>
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('YOUR_POSTHOG_PROJECT_API_KEY', {
api_host: 'https://tracking.example.com', // Your tracking domain
ui_host: 'https://us.posthog.com' // or https://eu.posthog.com for EU
})
</script>The proxy includes a health check endpoint at /healthz that returns:
- Status Code: 200 OK
- Response Body: "OK"
This endpoint is useful for:
- Container orchestration health checks (Kubernetes, Docker Swarm)
- Load balancer health probes
- Monitoring systems (Prometheus, Datadog, etc.)
Example usage:
curl http://your-domain.com/healthz
# Returns: OK (with HTTP 200)Docker Compose automatically configures health checks using this endpoint.
By default, SSL is enabled and Caddy will automatically provision certificates. To disable SSL for local development or when running behind another SSL proxy:
SSL_ENABLED=falseThis will configure Caddy to serve HTTP only on port 80.
docker build -t ph-caddy-proxy:local .# Start the proxy
docker-compose up -d
# Test health check endpoint
curl http://localhost/healthz
# Test the proxy
curl -I http://localhost/static/array.jsThis repository includes GitHub Actions workflows that:
- Build multi-platform Docker images (linux/amd64, linux/arm64)
- Push to GitHub Container Registry (ghcr.io)
- Tag images with:
- Branch names
- Semantic versions (from git tags)
- SHA hashes
latestfor the main branch
Builds are triggered on:
- Push to
mainormasterbranches - Creating version tags (e.g.,
v1.0.0) - Pull requests
- Manual workflow dispatch
- SSL/TLS: Caddy automatically provisions and renews SSL certificates via Let's Encrypt
- Data Privacy: This proxy doesn't store or log any analytics data - it only forwards requests
Set DEBUG=true to see the generated Caddyfile:
docker-compose down
DEBUG=true docker-compose updocker-compose logs -f caddy-proxy-
Port 80/443 already in use: Stop other services using these ports or change the port mapping in docker-compose.yml
-
SSL certificate issues: Ensure your domain's DNS points to the server and ports 80/443 are accessible
-
Connection refused: Check that the container is running and healthy with
docker psanddocker logs ph-caddy-proxy
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
MIT
For issues specific to this proxy, please open an issue in this repository. For PostHog-related questions, visit PostHog Documentation.