Skip to content

Commit c7131f5

Browse files
authored
feat: Upgrade to Postgres 18, add UUID v7 support, and upgrade Redis to 8.6 (#865)
1 parent 0ba6744 commit c7131f5

40 files changed

Lines changed: 568 additions & 154 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@baseplate-dev/plugin-auth': patch
3+
'@baseplate-dev/plugin-storage': patch
4+
'@baseplate-dev/plugin-payments': patch
5+
---
6+
7+
Update plugin model definitions to use `defaultGeneration: 'uuidv7'` for UUID primary key fields
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
'@baseplate-dev/core-generators': patch
3+
---
4+
5+
Upgrade PostgreSQL from 17.5 to 18.3 and Redis from 8.0 to 8.6 in Docker Compose generators
6+
7+
## Breaking: Volume mount path changed
8+
9+
PostgreSQL 18 changed its default data directory from `/var/lib/postgresql/data` to `/var/lib/postgresql/<major>/docker` and placed a symlink at the old path. Mounting a volume directly to `/var/lib/postgresql/data` on Postgres 18+ will cause a container startup error:
10+
11+
```
12+
error mounting "..." to rootfs at "/var/lib/postgresql/data": no such file or directory
13+
```
14+
15+
To align with this change, the Docker Compose volume mount has been updated from `db-data:/var/lib/postgresql/data` to `db-data:/var/lib/postgresql`. This means **existing dev databases will not be found** after upgrading and you must re-create or migrate your database.
16+
17+
## Upgrading your dev database
18+
19+
After syncing, your `docker-compose.yml` will reference `postgres:18.3-alpine` with the new volume mount path. You have three options:
20+
21+
### Option 1: Auto-upgrade with pgautoupgrade (in-place upgrade)
22+
23+
Use the [`pgautoupgrade`](https://github.com/pgautoupgrade/docker-pgautoupgrade) Docker image to upgrade the data directory in-place:
24+
25+
1. Stop your containers:
26+
27+
```bash
28+
cd docker && docker compose down
29+
```
30+
31+
2. Temporarily swap the image in `docker-compose.yml`:
32+
33+
```yaml
34+
image: pgautoupgrade/pgautoupgrade:18-alpine
35+
```
36+
37+
3. Start the container and watch for the upgrade:
38+
39+
```bash
40+
docker compose up # wait for "Upgrade to PostgreSQL 18.3 complete." message
41+
```
42+
43+
4. Once complete, stop and revert the image:
44+
```bash
45+
docker compose down
46+
```
47+
Change the image back in `docker-compose.yml`:
48+
```yaml
49+
image: postgres:18.3-alpine
50+
```
51+
```bash
52+
docker compose up
53+
```
54+
55+
### Option 2: Fresh start (for dev databases with no important data)
56+
57+
Delete the old volume and start fresh:
58+
59+
```bash
60+
cd docker
61+
docker compose down -v # removes containers AND volumes
62+
docker compose up # starts fresh with Postgres 18
63+
cd ../apps/backend
64+
pnpm db:migrate # re-apply all migrations
65+
pnpm db:seed # re-seed if applicable
66+
```
67+
68+
### Option 3: Dump and restore (preserves data)
69+
70+
If you need to keep your data but don't want to use pgautoupgrade:
71+
72+
```bash
73+
cd docker
74+
75+
# 1. While still on the OLD docker-compose.yml, dump your data
76+
docker compose exec db pg_dumpall -U postgres > backup.sql
77+
78+
# 2. Now sync your project to get the new docker-compose.yml
79+
# ... run baseplate sync ...
80+
81+
# 3. Remove old volume and start with new config
82+
docker compose down -v
83+
docker compose up -d
84+
85+
# 4. Restore your data
86+
docker compose exec -T db psql -U postgres < backup.sql
87+
rm backup.sql
88+
```

.changeset/uuid-field-ui-update.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@baseplate-dev/project-builder-web': patch
3+
---
4+
5+
Update UUID field default value UI to support selecting between UUID v4 and v7 generation
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@baseplate-dev/project-builder-lib': patch
3+
---
4+
5+
Add schema migration 031 to convert `genUuid` boolean to `defaultGeneration` enum on UUID fields
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@baseplate-dev/fastify-generators': patch
3+
---
4+
5+
Add UUID v7 support by replacing `genUuid` boolean with `defaultGeneration` enum (`none` | `uuidv4` | `uuidv7`), leveraging PostgreSQL 18's native `uuidv7()` function

examples/blog-with-auth/baseplate/generated/docker/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
db:
3-
image: postgres:17.5-alpine
3+
image: postgres:18.3-alpine
44
container_name: ${COMPOSE_PROJECT_NAME:-blog-with-auth}-db
55
restart: on-failure
66
security_opt:
@@ -12,7 +12,7 @@ services:
1212
ports:
1313
- '${POSTGRES_PORT:-5432}:5432'
1414
volumes:
15-
- db-data:/var/lib/postgresql/data
15+
- db-data:/var/lib/postgresql
1616
networks:
1717
- backend
1818
logging:

examples/blog-with-auth/baseplate/project-definition.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
"id": "model-scalar-field:adbpe9Hhybb1",
150150
"isOptional": false,
151151
"name": "id",
152-
"options": { "default": "", "genUuid": true },
152+
"options": { "defaultGeneration": "uuidv4" },
153153
"type": "uuid"
154154
},
155155
{
@@ -207,7 +207,7 @@
207207
"id": "model-scalar-field:x5uM_Nhnixmv",
208208
"isOptional": false,
209209
"name": "id",
210-
"options": { "default": "", "genUuid": true },
210+
"options": { "defaultGeneration": "uuidv4" },
211211
"type": "uuid"
212212
},
213213
{
@@ -235,7 +235,7 @@
235235
"id": "model-scalar-field:h8RjTcvjiTB9",
236236
"isOptional": true,
237237
"name": "userId",
238-
"options": { "default": "" },
238+
"options": { "defaultGeneration": "none" },
239239
"type": "uuid"
240240
},
241241
{
@@ -321,7 +321,7 @@
321321
"id": "model-scalar-field:PPNcQYjHcLJM",
322322
"isOptional": false,
323323
"name": "id",
324-
"options": { "default": "", "genUuid": true },
324+
"options": { "defaultGeneration": "uuidv4" },
325325
"type": "uuid"
326326
},
327327
{
@@ -335,7 +335,7 @@
335335
"id": "model-scalar-field:5r4qOjWPcsk",
336336
"isOptional": false,
337337
"name": "userId",
338-
"options": { "default": "" },
338+
"options": { "defaultGeneration": "none" },
339339
"type": "uuid"
340340
},
341341
{
@@ -423,21 +423,21 @@
423423
"id": "model-scalar-field:6AEaW6mjUeMi",
424424
"isOptional": false,
425425
"name": "id",
426-
"options": { "default": "", "genUuid": true },
426+
"options": { "defaultGeneration": "uuidv4" },
427427
"type": "uuid"
428428
},
429429
{
430430
"id": "model-scalar-field:dLndbykf8h2f",
431431
"isOptional": false,
432432
"name": "blogId",
433-
"options": { "default": "" },
433+
"options": { "defaultGeneration": "none" },
434434
"type": "uuid"
435435
},
436436
{
437437
"id": "model-scalar-field:PNfjIfpZjmkw",
438438
"isOptional": false,
439439
"name": "publisherId",
440-
"options": { "default": "" },
440+
"options": { "defaultGeneration": "none" },
441441
"type": "uuid"
442442
},
443443
{
@@ -525,14 +525,14 @@
525525
"id": "model-scalar-field:EwhSjvGdsL9q",
526526
"isOptional": false,
527527
"name": "blogId",
528-
"options": { "default": "", "genUuid": false },
528+
"options": { "defaultGeneration": "none" },
529529
"type": "uuid"
530530
},
531531
{
532532
"id": "model-scalar-field:HBbSkN0_M0TR",
533533
"isOptional": false,
534534
"name": "userId",
535-
"options": { "default": "" },
535+
"options": { "defaultGeneration": "none" },
536536
"type": "uuid"
537537
},
538538
{
@@ -653,7 +653,7 @@
653653
"id": "model-scalar-field:iZSakQLjj07M",
654654
"isOptional": false,
655655
"name": "id",
656-
"options": { "default": "", "genUuid": true },
656+
"options": { "defaultGeneration": "uuidv4" },
657657
"type": "uuid"
658658
},
659659
{
@@ -732,14 +732,14 @@
732732
"id": "model-scalar-field:z6JrpgbtlGck",
733733
"isOptional": false,
734734
"name": "id",
735-
"options": { "default": "", "genUuid": true },
735+
"options": { "defaultGeneration": "uuidv4" },
736736
"type": "uuid"
737737
},
738738
{
739739
"id": "model-scalar-field:aJSc9y1cCfDp",
740740
"isOptional": false,
741741
"name": "userId",
742-
"options": { "default": "" },
742+
"options": { "defaultGeneration": "none" },
743743
"type": "uuid"
744744
},
745745
{
@@ -819,7 +819,7 @@
819819
"id": "model-scalar-field:7f865kOwXryv",
820820
"isOptional": false,
821821
"name": "userId",
822-
"options": { "default": "", "genUuid": false },
822+
"options": { "defaultGeneration": "none" },
823823
"type": "uuid"
824824
},
825825
{
@@ -870,7 +870,7 @@
870870
"id": "model-scalar-field:CjiJr2PTCCeT",
871871
"isOptional": false,
872872
"name": "id",
873-
"options": { "default": "", "genUuid": true },
873+
"options": { "defaultGeneration": "uuidv4" },
874874
"type": "uuid"
875875
},
876876
{
@@ -884,7 +884,7 @@
884884
"id": "model-scalar-field:7Y3oZIHFIY2V",
885885
"isOptional": false,
886886
"name": "userId",
887-
"options": { "default": "" },
887+
"options": { "defaultGeneration": "none" },
888888
"type": "uuid"
889889
},
890890
{
@@ -1040,7 +1040,7 @@
10401040
"version": "0.1.0"
10411041
}
10421042
],
1043-
"schemaVersion": 30,
1043+
"schemaVersion": 31,
10441044
"settings": {
10451045
"general": {
10461046
"name": "blog-with-auth",

examples/blog-with-auth/docker/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
db:
3-
image: postgres:17.5-alpine
3+
image: postgres:18.3-alpine
44
container_name: ${COMPOSE_PROJECT_NAME:-blog-with-auth}-db
55
restart: on-failure
66
security_opt:
@@ -12,7 +12,7 @@ services:
1212
ports:
1313
- '${POSTGRES_PORT:-5432}:5432'
1414
volumes:
15-
- db-data:/var/lib/postgresql/data
15+
- db-data:/var/lib/postgresql
1616
networks:
1717
- backend
1818
logging:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- DropForeignKey
2+
ALTER TABLE "file" DROP CONSTRAINT "file_uploader_id_fkey";
3+
4+
-- AddForeignKey
5+
ALTER TABLE "file" ADD CONSTRAINT "file_uploader_id_fkey" FOREIGN KEY ("uploader_id") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE RESTRICT;

examples/todo-with-better-auth/baseplate/generated/docker/docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
db:
3-
image: postgres:17.5-alpine
3+
image: postgres:18.3-alpine
44
container_name: ${COMPOSE_PROJECT_NAME:-todo-with-better-auth}-db
55
restart: on-failure
66
security_opt:
@@ -12,7 +12,7 @@ services:
1212
ports:
1313
- '${POSTGRES_PORT:-6432}:5432'
1414
volumes:
15-
- db-data:/var/lib/postgresql/data
15+
- db-data:/var/lib/postgresql
1616
networks:
1717
- backend
1818
logging:
@@ -31,7 +31,7 @@ services:
3131
retries: 2
3232
start_period: 10s
3333
redis:
34-
image: redis:8.0-alpine
34+
image: redis:8.6-alpine
3535
container_name: ${COMPOSE_PROJECT_NAME:-todo-with-better-auth}-redis
3636
restart: on-failure
3737
security_opt:

0 commit comments

Comments
 (0)