Skip to content

Commit eae2d01

Browse files
pgflow botjumski
authored andcommitted
docs: add node and bun edge worker deployment
1 parent 34cbcd8 commit eae2d01

5 files changed

Lines changed: 155 additions & 2 deletions

File tree

pkgs/edge-worker/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@ Edge Worker processes messages from a PostgreSQL queue and executes handler func
2121
import { EdgeWorker } from 'jsr:@pgflow/edge-worker';
2222
```
2323

24-
> [!WARNING]
25-
> Always import from JSR.io using the `jsr:` prefix. Never install from npm.
24+
## Package Registries
25+
26+
`@pgflow/edge-worker` is published to both registries:
27+
28+
- Use JSR for Supabase Edge Functions and Deno deployments.
29+
- Use npm for Node and Bun long-running process deployments.
30+
31+
Supabase Edge Functions remain the primary deployment path. Node and Bun process hosting is intended for Railway, Docker, and similar hosts that run workers as normal long-running processes.
2632

2733
For database setup, see [pgflow installation docs](https://pgflow.dev/getting-started/install-pgflow/).
2834

pkgs/website/astro.config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ export default defineConfig({
299299
id: 'deploy',
300300
items: [
301301
{ label: 'Overview', link: '/deploy/' },
302+
{
303+
label: 'Node and Bun process workers',
304+
link: '/deploy/node-bun-process-workers/',
305+
},
302306
{
303307
label: 'Supabase',
304308
autogenerate: { directory: 'deploy/supabase/' },

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ Learn how to deploy pgflow to production, monitor workflow execution, and mainta
2020
href="/deploy/supabase/self-hosted/"
2121
description="Deploy pgflow on self-hosted Supabase instances running on your own infrastructure"
2222
/>
23+
<LinkCard
24+
title="Node and Bun process workers"
25+
href="/deploy/node-bun-process-workers/"
26+
description="Run workers as long-running processes on Railway, Fly, Docker, or VMs"
27+
/>
2328
</CardGrid>
2429

2530
## Configure
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: Node And Bun Process Workers
3+
description: Deploy pgflow workers as long-running Node or Bun processes
4+
sidebar:
5+
order: 2
6+
---
7+
8+
import { Aside, CardGrid, LinkCard, Tabs, TabItem } from '@astrojs/starlight/components';
9+
10+
Use this deployment mode when your host runs a long-running process, such as Railway, Fly, Docker, or a VM worker service.
11+
12+
Use Supabase Edge Functions instead when you want pgflow to start workers through HTTP and have `ensure_workers()` respawn missing edge functions.
13+
14+
<Aside type="note" title="Supabase remains the primary path">
15+
Process workers are for hosts that supervise normal processes. If you deploy
16+
to Supabase Edge Functions, keep using JSR imports and the [Supabase deployment
17+
guide](/deploy/supabase/).
18+
</Aside>
19+
20+
## Install
21+
22+
Install the npm package in the application that owns your worker process:
23+
24+
```sh frame="none"
25+
pnpm add @pgflow/edge-worker
26+
```
27+
28+
## Worker Script
29+
30+
Create a user-owned worker script that imports `EdgeWorker` and calls `EdgeWorker.start(...)`.
31+
32+
```ts title="worker.ts"
33+
import { EdgeWorker } from '@pgflow/edge-worker';
34+
35+
await EdgeWorker.start('process-orders', async (payload, context) => {
36+
context.logger.info('Processing order', { payload });
37+
38+
return {
39+
processedAt: new Date().toISOString(),
40+
};
41+
});
42+
```
43+
44+
Flow workers use the same process runtime. Import your flow definition from your app code and pass it to `EdgeWorker.start(...)`:
45+
46+
```ts title="worker.ts"
47+
import { EdgeWorker } from '@pgflow/edge-worker';
48+
import { ProcessOrders } from './flows/process-orders.js';
49+
50+
await EdgeWorker.start(ProcessOrders);
51+
```
52+
53+
## Required Environment Variables
54+
55+
Set these variables in your process host:
56+
57+
| Variable | Required | Description |
58+
| --- | --- | --- |
59+
| `SUPABASE_URL` | Yes | Your Supabase project URL. |
60+
| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Service role key used by the worker runtime. |
61+
| `DATABASE_URL` | Yes, unless `EDGE_WORKER_DB_URL` is set | PostgreSQL connection string for the pgflow database. |
62+
| `EDGE_WORKER_DB_URL` | Yes, unless `DATABASE_URL` is set | Alternative PostgreSQL connection string name shared with Supabase Edge Functions. |
63+
| `WORKER_NAME` | No | Worker function name recorded in pgflow. Defaults to `pgflow-worker`. |
64+
65+
Use `DATABASE_URL` for process hosts when possible. `EDGE_WORKER_DB_URL` remains supported for deployments that share configuration with Supabase Edge Functions.
66+
67+
## Run The Worker
68+
69+
<Tabs>
70+
<TabItem label="Node">
71+
Compile your app worker script to JavaScript for production, then run the compiled file:
72+
73+
```sh frame="none"
74+
node dist/worker.js
75+
```
76+
</TabItem>
77+
<TabItem label="Bun">
78+
Bun can run the app worker script directly:
79+
80+
```sh frame="none"
81+
bun run worker.ts
82+
```
83+
</TabItem>
84+
</Tabs>
85+
86+
Your process manager should keep this command running. On Railway, Fly, Docker, or a VM, configure it as the service start command.
87+
88+
## Shutdown
89+
90+
Process workers drain on `SIGTERM`, `SIGINT`, and `SIGQUIT`.
91+
92+
On the first signal, the worker stops accepting new work, lets in-flight tasks finish, marks the worker stopped in pgflow, and exits with code `0`. A second signal exits immediately with code `1`.
93+
94+
## Health
95+
96+
There is no built-in HTTP health endpoint for process workers. Use your host's process liveness checks and pgflow worker heartbeat data in the database.
97+
98+
```sql frame="none"
99+
SELECT worker_id, function_name, last_heartbeat_at
100+
FROM pgflow.workers
101+
WHERE stopped_at IS NULL
102+
ORDER BY last_heartbeat_at DESC;
103+
```
104+
105+
For more heartbeat queries, see [Monitor workers health](/deploy/monitor-workers-health/).
106+
107+
## Supervision
108+
109+
Process workers are tracked with `start_mode = 'process'`. `ensure_workers()` only pings HTTP-started workers and never invokes process workers.
110+
111+
That means your process host is responsible for restarting crashed Node or Bun workers. pgflow still tracks worker rows, heartbeats, deprecation, and task recovery.
112+
113+
## Related
114+
115+
<CardGrid>
116+
<LinkCard
117+
title="Deploy to Supabase"
118+
href="/deploy/supabase/"
119+
description="Primary deployment path using Supabase Edge Functions"
120+
/>
121+
<LinkCard
122+
title="Worker Management"
123+
href="/deploy/worker-management/"
124+
description="How pgflow registers, deprecates, and tracks workers"
125+
/>
126+
<LinkCard
127+
title="Database Connection"
128+
href="/deploy/database-connection/"
129+
description="Connection options and production database configuration"
130+
/>
131+
</CardGrid>

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ Before starting, ensure you have completed [Getting Started](/get-started/instal
2424
including Postgres image upgrades and database connection configuration.
2525
</Aside>
2626

27+
<Aside type="note" title="Running workers outside Supabase?">
28+
For Railway, Docker, or other long-running process hosts, use the [Node/Bun
29+
process worker deployment guide](/deploy/node-bun-process-workers/) instead.
30+
Process workers are tracked by pgflow but are not restarted by
31+
`ensure_workers()`.
32+
</Aside>
33+
2734
## Deployment Overview
2835

2936
<Steps>

0 commit comments

Comments
 (0)