You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This guide covers a local development workflow for the jobs stack:
4
4
5
-
- Postgres + `launchql-ext-jobs`
5
+
- Postgres + `launchql-database-jobs`
6
6
- LaunchQL API server
7
7
-`simple-email` function
8
+
-`send-email-link` function
8
9
-`knative-job-service`
9
10
10
11
It assumes:
@@ -56,19 +57,19 @@ This ensures all subsequent `pgpm` and `psql` commands point at the same local d
56
57
57
58
Make sure `pgpm` is installed and up to date.
58
59
59
-
From the `constructive/` directory (with `pgenv` applied):
60
+
From the `constructive-db/` directory (with `pgenv` applied):
60
61
61
-
1.Bootstrap admin users:
62
+
1.Create the `launchql` database (if it does not already exist):
62
63
63
64
```sh
64
-
pgpm admin-users bootstrap --yes
65
-
pgpm admin-users add --test --yes
65
+
createdb launchql
66
66
```
67
67
68
-
2.Create the `launchql` database (if it does not already exist):
68
+
2.Bootstrap admin users:
69
69
70
70
```sh
71
-
createdb launchql
71
+
pgpm admin-users bootstrap --yes
72
+
pgpm admin-users add --test --yes
72
73
```
73
74
74
75
3. Deploy the main app and jobs packages into `launchql`:
@@ -88,52 +89,125 @@ At this point, the app schema and `database-jobs` should be installed and `app_j
88
89
With Postgres initialized, bring up the jobs-related services using `docker-compose.jobs.yml`:
89
90
90
91
```sh
92
+
docker compose -f docker-compose.jobs.yml build
91
93
docker compose -f docker-compose.jobs.yml up
92
94
```
93
95
94
96
Or run detached:
95
97
96
98
```sh
97
-
docker compose -f docker-compose.jobs.yml up -d
99
+
docker compose -f docker-compose.jobs.yml up -d --build
98
100
```
99
101
100
102
This starts:
101
103
102
104
-`launchql-server` – GraphQL API server
103
105
-`simple-email` – Knative-style HTTP function
106
+
-`send-email-link` – Knative-style HTTP function
104
107
-`knative-job-service` – jobs runtime (callback server + worker + scheduler)
105
108
106
-
By default, all three services use the published image:
109
+
---
110
+
111
+
### Switching dry run vs real Mailgun sending
112
+
113
+
By default, `docker-compose.jobs.yml` runs both email functions in dry-run mode (no real email is sent), and it uses placeholder Mailgun credentials unless you provide `MAILGUN_API_KEY` / `MAILGUN_KEY`.
114
+
115
+
Quick start commands:
116
+
117
+
Dry run:
118
+
119
+
```sh
120
+
docker compose -f docker-compose.jobs.yml up -d --build --force-recreate
To use a real Mailgun key without editing `docker-compose.jobs.yml`, set these env vars before starting the stack (or put them in a local `.env` file in the `constructive/` directory). Don't commit your `.env`.
130
+
131
+
```sh
132
+
export MAILGUN_API_KEY="your-mailgun-key"
133
+
export MAILGUN_KEY="your-mailgun-key"
134
+
```
135
+
136
+
If you're not using `mg.constructive.io`, also override `MAILGUN_DOMAIN`, `MAILGUN_FROM`, and `MAILGUN_REPLY` (for example in the override file below) to match your Mailgun setup.
137
+
138
+
To actually send email (instead of dry-run), set these env vars (or put them in your local `.env`):
107
139
108
-
```text
109
-
ghcr.io/constructive-io/launchql:b88e3d1
140
+
```sh
141
+
export SIMPLE_EMAIL_DRY_RUN=false
142
+
export SEND_EMAIL_LINK_DRY_RUN=false
110
143
```
111
144
112
-
If you want to test a local build instead, build the image from the `constructive/` workspace and update `image:` in `docker-compose.jobs.yml` to point to your local tag, for example:
145
+
Then recreate the stack so the new env is applied:
113
146
114
147
```sh
115
-
docker build -t constructive-local .
148
+
docker compose -f docker-compose.jobs.yml up -d --build --force-recreate
149
+
```
150
+
151
+
If you prefer not to export env vars, create a local override file (don't commit it) at `docker-compose.jobs.override.yml`:
152
+
153
+
```yml
154
+
services:
155
+
simple-email:
156
+
environment:
157
+
SIMPLE_EMAIL_DRY_RUN: "false"
158
+
159
+
send-email-link:
160
+
environment:
161
+
SEND_EMAIL_LINK_DRY_RUN: "false"
116
162
```
117
163
118
-
Then in `docker-compose.jobs.yml`:
164
+
Start the stack with both files:
119
165
120
-
```yaml
121
-
image: constructive-local
166
+
```sh
167
+
docker compose -f docker-compose.jobs.yml -f docker-compose.jobs.override.yml up -d --build --force-recreate
122
168
```
123
169
124
-
All services are attached to the shared `constructive-net` network and talk to the `postgres` container by hostname `postgres`.
170
+
To switch back to dry-run, set `SIMPLE_EMAIL_DRY_RUN=true`and `SEND_EMAIL_LINK_DRY_RUN=true` (or delete the override file) and recreate again.
125
171
126
172
---
127
173
128
-
## 5. Enqueue a test job (simple-email)
174
+
## 5. Ensure GraphQL host routing works for `send-email-link`
175
+
176
+
LaunchQL selects the API by the HTTP `Host` header using rows in `meta_public.domains`.
177
+
178
+
For local development, `app-svc-local` seeds `admin.localhost` as the admin API domain. `docker-compose.jobs.yml` adds a Docker network alias so other containers can resolve `admin.localhost` to the `launchql-server` container, and `send-email-link` uses:
Quick check from your host (should return JSON, not HTML):
183
+
184
+
```sh
185
+
curl -s -H 'Host: admin.localhost' \
186
+
-H 'Content-Type: application/json' \
187
+
-X POST http://localhost:3000/graphql \
188
+
--data '{"query":"query { __typename }"}'
189
+
```
190
+
191
+
If your GraphQL server requires auth, set `GRAPHQL_AUTH_TOKEN` before starting the jobs stack (it is passed through to the `send-email-link` container).
192
+
193
+
---
194
+
195
+
## 6. Enqueue a test job (simple-email)
129
196
130
197
With the jobs stack running, you can enqueue a test job from your host into the Postgres container:
131
198
199
+
First, grab a real `database_id` (required by `send-email-link`, optional for `simple-email`):
200
+
201
+
```sh
202
+
DBID="$(docker exec -i postgres psql -U postgres -d launchql -Atc 'SELECT id FROM collections_public.database ORDER BY created_at LIMIT 1;')"
0 commit comments