Skip to content

Commit c134701

Browse files
committed
fix(docker): install pg and mysql2 in the official runtime image
`@objectstack/driver-sql` declares `pg`, `mysql2` and `tedious` as OPTIONAL peer dependencies, and npm skips optional peers, so the official runtime image -- built by `npm install -g @objectstack/cli` and nothing else -- had no `pg` in it. Every documented Postgres path landed on that image: the `docker run ... -e OS_DATABASE_URL=postgres://...` invocation in docker/README.md, the same invocation in this Dockerfile's own header, and `npm create objectstack` followed by `docker compose up` against the generated `postgres:17` service. All of them failed fast at boot with `Cannot find module 'pg'`. Per the maintainer ruling on #14510 (direction B'): the image installs the drivers, and docker/README.md publishes which ones it carries as a maintained public promise. The scaffolder is unchanged. The version ranges are copied verbatim from driver-sql's `peerDependencies`, so the image satisfies the driver's own contract rather than a second one; both packages are pure JavaScript with no native build. A promise with nothing holding it to the artifact drifts silently, so `check-docs-image-tag` -- the gate that already owns exactly this file pair -- grows a third limb comparing the Dockerfile's install line against the README's published table: package set, version ranges, and an anti-vacuity rule on both sides. Every new finding kind is observed failing in `--self-test` (94 assertions), and the limb was proven red against the pre-change tree before the docker files were touched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
1 parent 9b30cc1 commit c134701

3 files changed

Lines changed: 645 additions & 10 deletions

File tree

docker/Dockerfile

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,36 @@ FROM node:22-slim
4040
# Pinned by CI to the @objectstack/cli release that triggered the publish.
4141
# `latest` is only the fallback for ad-hoc local builds of this file.
4242
ARG OS_CLI_VERSION=latest
43-
RUN npm install -g @objectstack/cli@${OS_CLI_VERSION} \
43+
44+
# The SQL drivers ship WITH the image, not with the app (#14510).
45+
#
46+
# `@objectstack/driver-sql` declares `pg`, `mysql2` and `tedious` as OPTIONAL
47+
# peer dependencies. npm 7+ installs peer dependencies automatically but SKIPS
48+
# the optional ones, so `npm install -g @objectstack/cli` on its own produced a
49+
# tree with no `pg` in it -- while the header of this very file, README.md, and
50+
# the `docker-compose.yml` that `npm create objectstack` generates (whose `db`
51+
# service is `postgres:17`) all hand this image a `postgres://` URL. Every one
52+
# of those paths died at boot on `Cannot find module 'pg'`, with the loud
53+
# fail-fast ADR-0062 D5 requires but nothing documented to act on. Installing
54+
# the drivers here is the "whoever makes the promise installs it" half of the
55+
# fix; the other half is that README.md publishes the list.
56+
#
57+
# The ranges are copied VERBATIM from driver-sql's `peerDependencies`, so the
58+
# image satisfies the driver's own contract rather than a second one invented
59+
# here. Both packages are pure JavaScript with no native build step, which is
60+
# why they are affordable for every user of the image. `tedious` (SQL Server)
61+
# and `@objectstack/driver-turso` are deliberately NOT installed -- extend the
62+
# image when you need one, as README.md shows.
63+
#
64+
# This install line is a PUBLIC PROMISE, published as the driver table in
65+
# ./README.md. Adding or removing a package here changes which databases a
66+
# deployment can reach, so the two files must move in the same commit:
67+
# `pnpm check:docs-image-tag` fails when the install line and that table
68+
# disagree on the package set or on a version range.
69+
RUN npm install -g \
70+
@objectstack/cli@${OS_CLI_VERSION} \
71+
"pg@^8.0.0" \
72+
"mysql2@^3.0.0" \
4473
&& npm cache clean --force
4574

4675
LABEL org.opencontainers.image.source="https://github.com/objectstack-ai/objectstack" \

docker/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,44 @@ docker run -p 8080:8080 \
4646
`OS_ARTIFACT_PATH` also accepts an `https://` URL, so the artifact can come
4747
straight from your release storage.
4848

49+
## Database drivers in the image
50+
51+
**This list is a public promise.** The dialects below need nothing installed —
52+
their driver is already in the image, which is why the `postgres://` invocation
53+
above works exactly as written.
54+
55+
| `OS_DATABASE_URL` scheme | Driver package installed in the image |
56+
|:---|:---|
57+
| `postgres://`, `postgresql://` | `pg@^8.0.0` |
58+
| `mysql://`, `mysql2://` | `mysql2@^3.0.0` |
59+
60+
The ranges are `@objectstack/driver-sql`'s own optional-peer ranges, so the
61+
image satisfies the driver's contract rather than a second one. Both packages
62+
are pure JavaScript — they add no native build step and no compiler to the
63+
image.
64+
65+
Two more dialects work without appearing above, because they arrive with
66+
`@objectstack/cli` rather than from that install line: SQLite (`better-sqlite3`,
67+
for a `file:…` path — one box only, wrong for multi-node) and MongoDB
68+
(`mongodb://…`, **single-tenant only**; see
69+
[Drivers](https://objectstack.ai/docs/data-modeling/drivers)).
70+
71+
**Not in the image:** `tedious` (SQL Server) and `@objectstack/driver-turso`
72+
(`libsql://…` / Turso). Add one by extending the image:
73+
74+
```dockerfile
75+
FROM ghcr.io/objectstack-ai/objectstack:17.2.0
76+
USER root
77+
RUN npm install -g tedious
78+
USER node
79+
COPY --chown=node:node dist/objectstack.json /srv/app/objectstack.json
80+
```
81+
82+
Changing this table is a change to what deployments can connect to, so it does
83+
not move on its own: `pnpm check:docs-image-tag` compares it against
84+
[`Dockerfile`](./Dockerfile)'s install line and fails if the two disagree on the
85+
package set or on a version range.
86+
4987
## What the image presets
5088

5189
- `OS_ARTIFACT_PATH=/srv/app/objectstack.json`, `OS_PORT=8080`,

0 commit comments

Comments
 (0)