try.directtry.direct

Connect Supabase to PostHog with Stacker PIPEs - Complete Setup Guide

What You'll Build

A working data pipe between a Supabase stack (Kong + PostgREST) and a PostHog-compatible event receiver, deployed on Hetzner Cloud with Stacker. Events flow from Supabase through Kong to PostHog - all self-hosted.

  • Supabase with Kong API gateway, PostgREST, Auth, Realtime, Storage
  • PostHog-compatible event receiver
  • Stacker PIPE connecting both services
  • Deployed on Hetzner Cloud with status panel agent

Quick Answer

# Deploy the stack
stacker deploy --target cloud --key htz-0

# Create the pipe
stacker pipe create supabase-posthog posthog --manual

# Test the connection
curl -X POST http://<SERVER_IP>:8000/posthog/capture \
  -H "Content-Type: application/json" \
  -d '{"event":"test","properties":{"source":"pipe-demo"}}'
Events flow from Supabase through Kong to PostHog.

Prerequisites

  • Stacker CLI installed and authenticated (stacker login)
  • Hetzner cloud credentials configured (stacker clouds)
  • Docker running locally (for image transfer if needed)

Step 1: Create the Project

stacker init supabase-posthog

Set the project identity in stacker.yml:

name: supabase-posthog
project:
  identity: supabase-posthog

Step 2: Define the Stack

Configure Kong as the API gateway, Supabase services, and a PostHog-compatible event receiver in stacker.yml.

app:
  type: custom
  image: kong/kong:3.9.1
  ports:
    - "8000:8000"
    - "8443:8443"

services:
  - name: db
    image: supabase/postgres:17.6.1.136
    # ... database init, healthcheck, volumes

  - name: posthog
    image: python:3.11-alpine
    ports:
      - "8001:8000"
    volumes:
      - ./posthog-receiver/app.py:/app/app.py:ro
    command: python /app/app.py

Kong Route Configuration

Create kong.yml with upstream timeouts to avoid probe hangs. Without explicit timeouts, Kong defaults to 60 seconds per upstream operation - probes hitting a down service would hang for the full duration.

services:
  - name: rest-v1
    url: http://rest:3000
    connect_timeout: 5000
    write_timeout: 5000
    read_timeout: 5000
    routes:
      - name: rest-all
        paths:
          - /rest/v1/

  - name: posthog-v1
    url: http://posthog:8000
    connect_timeout: 5000
    write_timeout: 5000
    read_timeout: 5000
    routes:
      - name: posthog-capture
        paths:
          - /posthog/

Step 3: Deploy to Cloud

stacker deploy --target cloud --key htz-0

Stacker provisions a Hetzner server, installs Docker and the status panel agent, copies the config bundle, and starts all containers.

After deployment completes, verify everything is running:

stacker status
stacker agent status
stacker agent containers

All services should show running. If some are restarting, check their logs:

stacker agent logs rest --limit 20

Step 4: Create the Pipe

The pipe connects Supabase PostgREST (source) to PostHog's /capture endpoint (target). First, scan for endpoints - note the probe takes 3-5 minutes, so the CLI timeout may need extending.

# Using pipe scan (may time out if probe takes long)
stacker pipe scan --app supabase-posthog

# Alternative: use agent exec with a longer timeout
stacker agent exec probe_endpoints \
  --params '{"app_code":"supabase-posthog","capture_samples":true}' \
  --timeout 600 --json

Then create the pipe:

stacker pipe create supabase-posthog posthog --manual

Step 5: Test the Pipe

Verify the PostHog receiver accepts events:

# Direct to PostHog
curl -X POST http://<SERVER_IP>:8001/capture \
  -H "Content-Type: application/json" \
  -d '{"event":"test","properties":{"source":"pipe-demo"}}'

# Through Kong gateway
curl -X POST http://<SERVER_IP>:8000/posthog/capture \
  -H "Content-Type: application/json" \
  -d '{"event":"test","properties":{"source":"pipe-demo"}}'

Check the PostHog logs to confirm receipt:

stacker agent logs posthog --limit 10
# Expected: Received capture event: {"event": "test", "properties": {"source": "pipe-demo"}}

Troubleshooting

Probe Hangs or Times Out

Most common cause: The remote docker-compose.yml is invalid - missing volume definitions, undefined networks, or file ownership issues. Run docker compose ps on the server to check.

ssh trydirect@<SERVER_IP>
cd /home/trydirect/project
docker compose ps

# Validate compose file
docker compose config

Probe Works but Endpoints Are Empty

Check Kong upstream timeouts. If Kong's upstream connections hang (default 60s), the probe waits for each timeout. Set connect_timeout, write_timeout, read_timeout to 5000ms on all Kong services.

Container Name Not Resolved

The agent needs access to Docker and a valid compose file. Run docker compose ps directly on the server. If it errors with "refers to undefined network" or "refers to undefined volume", the compose file is broken.

Agent Responds Slowly

If the compose file is invalid, every agent operation that validates the compose will hang. Fix the compose file first, then restart the agent:

ssh trydirect@<SERVER_IP>
sudo docker compose -f /home/trydirect/statuspanel/docker-compose.yml up -d

Verification Checklist

  • stacker deployments shows all deployments
  • stacker status shows last deployment status
  • stacker agent containers lists all services as running
  • stacker agent exec probe_endpoints returns endpoints with operations
  • Direct curl to PostHog /capture returns {"status": "ok"}
  • Events appear in stacker agent logs posthog

Frequently Asked Questions

Why use Kong as the API gateway?

Kong routes traffic to multiple Supabase services (PostgREST, Auth, Realtime, Storage) through a single entry point. It also handles timeouts, rate limiting, and CORS.

Can I use the real PostHog instead of a receiver?

Yes. Replace the Python receiver with the official PostHog Docker image. The pipe endpoint remains the same - /capture.

How do I extend the probe timeout?

Use stacker agent exec probe_endpoints --timeout 600 for a 10-minute timeout. The default CLI timeout may be too short for complex stacks.

Do I need to open firewall ports?

Yes. After cloud deploy, open the ports you need: stacker cloud firewall add --public-ports 8000/tcp,8001/tcp.

Key Takeaways

  • Supabase + PostHog deploys as a single Stacker project
  • Kong upstream timeouts must be set explicitly to avoid probe hangs
  • Invalid compose files cause agent slowness - validate with docker compose config
  • The pipe works through Kong gateway or directly to the PostHog receiver
  • Source: github.com/trydirect/stacker

Try It Yourself

Deploy this stack or browse pre-built templates in the marketplace. Your first deployment is always free.