Skip to content

Commit 37ea285

Browse files
committed
self-hosted supabase guidde
1 parent cc74199 commit 37ea285

File tree

4 files changed

+158
-26
lines changed

4 files changed

+158
-26
lines changed

pkgs/website/src/content/docs/deploy/database-connection.mdx

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,46 @@ sidebar:
55
order: 110
66
---
77

8-
import { Aside, CardGrid, LinkCard } from "@astrojs/starlight/components";
8+
import { Aside, CardGrid, LinkCard } from '@astrojs/starlight/components';
99

1010
pgflow auto-detects your database connection in local development and requires minimal configuration for production. This guide explains how connection detection works and how to configure it for different environments.
1111

1212
## Connection Priority
1313

1414
When an Edge Worker starts, pgflow resolves the database connection using this priority chain:
1515

16-
| Priority | Source | Use Case |
17-
|----------|--------|----------|
18-
| 1 | `config.sql` | Full postgres.js control (SSL, custom options) |
19-
| 2 | `config.connectionString` | Custom connection URL |
20-
| 3 | `EDGE_WORKER_DB_URL` | Production environment variable |
21-
| 4 | Local fallback | Supabase local development (automatic) |
16+
| Priority | Source | Use Case |
17+
| -------- | ------------------------- | ---------------------------------------------- |
18+
| 1 | `config.sql` | Full postgres.js control (SSL, custom options) |
19+
| 2 | `config.connectionString` | Custom connection URL |
20+
| 3 | `EDGE_WORKER_DB_URL` | Production environment variable |
21+
| 4 | Local fallback | Supabase local development (automatic) |
2222

2323
If none of these are available, the worker throws an error: `"No database connection available"`.
2424

2525
<Aside type="note" title="Explicit config wins">
26-
Providing `config.sql`, `config.connectionString`, or `EDGE_WORKER_DB_URL` **skips the automatic local connection**. The local fallback only applies when no explicit configuration is provided.
26+
Providing `config.sql`, `config.connectionString`, or `EDGE_WORKER_DB_URL`
27+
**skips the automatic local connection**. The local fallback only applies when
28+
no explicit configuration is provided.
2729
</Aside>
2830

2931
## Local Development
3032

3133
When running locally with `supabase start`, pgflow automatically connects to your database without any configuration needed.
3234

3335
```typescript title="supabase/functions/my-worker/index.ts"
34-
import { EdgeWorker } from "@pgflow/edge-worker";
35-
import { MyFlow } from "../../flows/index.ts";
36+
import { EdgeWorker } from '@pgflow/edge-worker';
37+
import { MyFlow } from '../../flows/index.ts';
3638

3739
// Just works locally - no config needed!
3840
EdgeWorker.start(MyFlow);
3941
```
4042

4143
<Aside type="note" title="How local connections work">
42-
pgflow recognizes local Supabase environments by checking for known local dev credentials in environment variables. When running locally, it connects to the Docker pooler at `postgresql://postgres.localhost:postgres@127.0.0.1:54329/postgres`.
44+
pgflow recognizes local Supabase environments by checking for known local dev
45+
credentials in environment variables. When running locally, it connects to the
46+
Docker pooler at
47+
`postgresql://postgres.localhost:postgres@127.0.0.1:54329/postgres`.
4348
</Aside>
4449

4550
## Production Deployment
@@ -50,11 +55,18 @@ For production, set the `EDGE_WORKER_DB_URL` secret in your Supabase project:
5055
npx supabase secrets set EDGE_WORKER_DB_URL="postgresql://postgres.pooler-yourproject:[YOUR-PASSWORD]@aws-0-us-east-1.pooler.supabase.com:6543/postgres"
5156
```
5257

58+
<Aside type="note" title="Self-hosted Supabase">
59+
Self-hosted instances do not auto-configure `EDGE_WORKER_DB_URL`. You must set
60+
it explicitly in your Edge Function environment. See the [Self-Hosted Supabase
61+
guide](/deploy/supabase/self-hosted/) for the connection string format for
62+
your pooler.
63+
</Aside>
64+
5365
Your worker code stays the same - pgflow automatically uses the environment variable when not in local development:
5466

5567
```typescript title="supabase/functions/my-worker/index.ts"
56-
import { EdgeWorker } from "@pgflow/edge-worker";
57-
import { MyFlow } from "../../flows/index.ts";
68+
import { EdgeWorker } from '@pgflow/edge-worker';
69+
import { MyFlow } from '../../flows/index.ts';
5870

5971
// Uses EDGE_WORKER_DB_URL in production
6072
EdgeWorker.start(MyFlow);
@@ -69,11 +81,11 @@ See [Get Connection String](/deploy/supabase/get-connection-string/) for how to
6981
If you need to use a custom connection URL (different from `EDGE_WORKER_DB_URL`), pass it via `config.connectionString`:
7082

7183
```typescript title="supabase/functions/my-worker/index.ts"
72-
import { EdgeWorker } from "@pgflow/edge-worker";
73-
import { MyFlow } from "../../flows/index.ts";
84+
import { EdgeWorker } from '@pgflow/edge-worker';
85+
import { MyFlow } from '../../flows/index.ts';
7486

7587
EdgeWorker.start(MyFlow, {
76-
connectionString: Deno.env.get("MY_CUSTOM_DB_URL"),
88+
connectionString: Deno.env.get('MY_CUSTOM_DB_URL'),
7789
});
7890
```
7991

@@ -82,14 +94,14 @@ EdgeWorker.start(MyFlow, {
8294
For advanced scenarios requiring SSL certificates or other postgres.js settings, create the SQL client yourself and pass it via `config.sql`. Note that `prepare: false` is required when using a transaction pooler:
8395

8496
```typescript title="supabase/functions/my-worker/index.ts" {6}
85-
import { EdgeWorker } from "@pgflow/edge-worker";
86-
import postgres from "postgres";
87-
import { MyFlow } from "../../flows/index.ts";
97+
import { EdgeWorker } from '@pgflow/edge-worker';
98+
import postgres from 'postgres';
99+
import { MyFlow } from '../../flows/index.ts';
88100

89-
const sql = postgres(Deno.env.get("DATABASE_URL")!, {
101+
const sql = postgres(Deno.env.get('DATABASE_URL')!, {
90102
prepare: false, // Required for transaction pooling
91103
connection: {
92-
application_name: "my-flow-worker", // Visible in pg_stat_activity
104+
application_name: 'my-flow-worker', // Visible in pg_stat_activity
93105
},
94106
});
95107

@@ -103,12 +115,12 @@ See [Database SSL](/deploy/database-ssl/) for SSL configuration examples.
103115
If you need to connect to a different database during local development (e.g., a remote staging database), provide an explicit configuration:
104116

105117
```typescript title="supabase/functions/my-worker/index.ts"
106-
import { EdgeWorker } from "@pgflow/edge-worker";
107-
import { MyFlow } from "../../flows/index.ts";
118+
import { EdgeWorker } from '@pgflow/edge-worker';
119+
import { MyFlow } from '../../flows/index.ts';
108120

109121
// Skips automatic local connection, uses custom URL instead
110122
EdgeWorker.start(MyFlow, {
111-
connectionString: Deno.env.get("STAGING_DB_URL"),
123+
connectionString: Deno.env.get('STAGING_DB_URL'),
112124
});
113125
```
114126

pkgs/website/src/content/docs/deploy/index.mdx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ Learn how to deploy pgflow to production, monitor workflow execution, and mainta
1111

1212
<CardGrid>
1313
<LinkCard
14-
title="Deploy to Supabase"
14+
title="Supabase.com"
1515
href="/deploy/supabase/"
1616
description="Step-by-step guide to deploying pgflow workers to Supabase.com production"
1717
/>
18+
<LinkCard
19+
title="Self-Hosted Supabase"
20+
href="/deploy/supabase/self-hosted/"
21+
description="Deploy pgflow on self-hosted Supabase instances running on your own infrastructure"
22+
/>
1823
</CardGrid>
1924

2025
## Configure

pkgs/website/src/content/docs/deploy/supabase/index.mdx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,25 @@ sidebar:
55
order: 0
66
---
77

8-
import { Steps, LinkButton, Card, CardGrid, LinkCard } from "@astrojs/starlight/components";
8+
import {
9+
Steps,
10+
LinkButton,
11+
Card,
12+
CardGrid,
13+
LinkCard,
14+
Aside,
15+
} from '@astrojs/starlight/components';
916

1017
This guide walks you through deploying pgflow workers to Supabase.com. Workers run as Edge Functions that poll for tasks, execute your flow handlers, and report results back to the database.
1118

1219
Before starting, ensure you have completed [Getting Started](/get-started/installation/) and have a Supabase project linked to your local environment.
1320

21+
<Aside type="tip" title="Self-hosted Supabase?">
22+
Running Supabase on your own infrastructure? See the [Self-Hosted Supabase
23+
guide](/deploy/supabase/self-hosted/) for specific setup instructions
24+
including Postgres image upgrades and database connection configuration.
25+
</Aside>
26+
1427
## Deployment Overview
1528

1629
<Steps>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: Self-Hosted Supabase
3+
description: Deploy pgflow on self-hosted Supabase instances running on your own infrastructure
4+
sidebar:
5+
order: 50
6+
---
7+
8+
import { Aside, Steps } from '@astrojs/starlight/components';
9+
10+
:::note[Acknowledgements]
11+
This guide was contributed by [@benatcadiqo](https://github.com/benatcadiqo)
12+
based on their self-hosted Supabase deployment experience. See [GitHub Issue
13+
#616](https://github.com/pgflow-dev/pgflow/issues/616) for the original
14+
discussion.
15+
:::
16+
17+
This guide covers running pgflow on self-hosted Supabase instances. Self-hosted deployments differ from Supabase.com in several ways this guide addresses.
18+
19+
## Requirements
20+
21+
Before running pgflow on self-hosted Supabase, ensure you have:
22+
23+
- **pgmq 1.5.0+** - Required for pgflow. May require upgrading your Supabase Postgres image.
24+
- **Connection pooler enabled** - Supavisor must be running and accessible to Edge Functions.
25+
- **Edge Functions deployed manually** - The Supabase CLI works only with Supabase.com and local development.
26+
27+
## Upgrade Postgres Image
28+
29+
The default Supabase docker image may ship with an older pgmq version. If you see errors related to missing `pgmq` functions after installing pgflow migrations, upgrade your Postgres image.
30+
31+
In your `docker/docker-compose.yml`, update the `db` service image:
32+
33+
```yaml
34+
db:
35+
image: supabase/postgres:15.14.1.098
36+
```
37+
38+
<Aside type="tip">
39+
A known working version is `15.14.1.098`. Later versions in the 15.x branch
40+
should also work. Moving to PostgreSQL 17 images may require additional
41+
configuration.
42+
</Aside>
43+
44+
After updating, restart your containers:
45+
46+
```bash frame="none"
47+
docker compose down
48+
docker compose up -d
49+
```
50+
51+
## Database Connection
52+
53+
Self-hosted Supabase does not auto-configure `EDGE_WORKER_DB_URL`. You must set this environment variable explicitly on your Edge Functions.
54+
55+
The connection string format for self-hosted Supabase:
56+
57+
```bash frame="none"
58+
EDGE_WORKER_DB_URL=postgresql://postgres.${POOLER_TENANT_ID}:${POSTGRES_PASSWORD}@supavisor:${POOLER_PROXY_PORT_TRANSACTION}/postgres
59+
```
60+
61+
Where:
62+
63+
- `POOLER_TENANT_ID` - Your pooler tenant ID (set in your `.env` file)
64+
- `POSTGRES_PASSWORD` - Your Postgres password
65+
- `POOLER_PROXY_PORT_TRANSACTION` - The transaction pooler port (default: `6543`)
66+
67+
<Aside type="note">
68+
The hostname is `supavisor` (not `pooler` which is used by the Supabase CLI
69+
local development environment).
70+
</Aside>
71+
72+
Set this environment variable in your Edge Function deployment configuration. See [Database Connection](/deploy/database-connection/) for all connection options including SSL configuration.
73+
74+
## Function Deployment
75+
76+
The Supabase CLI is designed for Supabase.com and local development. For self-hosted deployments, deploy Edge Functions manually:
77+
78+
<Steps>
79+
1. Copy your function directories to `./volumes/functions/` in your Supabase project
80+
81+
2. Mount the volumes in your `docker-compose.yml` under the `functions` service
82+
83+
3. Ensure your flows are also accessible (either in the functions volume or a separate mounted volume)
84+
85+
4. Restart the Edge Functions container
86+
</Steps>
87+
88+
## Running Migrations
89+
90+
When applying pgflow migrations to a self-hosted database, you may need to bypass SSL verification:
91+
92+
```bash frame="none"
93+
PGSSLMODE=disable npx supabase migrations up --db-url $DB_URL
94+
```
95+
96+
Where `DB_URL` is your direct Postgres connection string (not the pooler URL).
97+
98+
## See Also
99+
100+
- [Database Connection](/deploy/database-connection/) - Connection configuration options
101+
- [Database SSL](/deploy/database-ssl/) - SSL configuration for production
102+
- [Update pgflow](/deploy/update-pgflow/) - Upgrading pgflow on self-hosted

0 commit comments

Comments
 (0)