mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
fix(image): take scheme-less health-check URLs, anchor the compose pin, say which tools left
This commit is contained in:
1 parent
fb143a2d47
commit
27b054d8c4
5 files changed
+28
-10
No files matched your search
+8
-5
@@ -58,11 +58,14 @@
|
||||
password hashing and the Prisma engine run their glibc builds. The
|
||||
published arm64 image renders PDF pages on a Raspberry Pi 4 again, where
|
||||
the Alpine build of the renderer needs CPU features an ARMv8.0 core
|
||||
lacks. Node security releases now reach the image with the official
|
||||
Node image, usually within days. The image carries no package manager:
|
||||
npm, npx, corepack and yarn are removed. `pg_dump` and `pg_restore` are
|
||||
PostgreSQL 18.6, the bundled database's version; `psql` is no longer in
|
||||
the app image, so run it in the `db` container. A health check that
|
||||
lacks. Node security releases now come with the official Node image,
|
||||
which HealthLog pins and moves forward with its releases. The image
|
||||
carries no package manager: npm, npx, corepack and yarn are removed.
|
||||
`pg_dump` and `pg_restore` are PostgreSQL 18.6, the bundled database's
|
||||
version. A few tools the Alpine image happened to carry are gone too:
|
||||
`psql`, `pg_isready`, `pg_dumpall`, `ps`, `top`, `nc`, `unzip` and the
|
||||
full `wget`. HealthLog uses none of them in the app container; run
|
||||
`psql` in the `db` container. A health check that
|
||||
still calls `wget`, from a compose file copied before this release or a
|
||||
platform template, keeps working: the image carries a small `wget` that
|
||||
answers health checks and nothing else. The current `docker-compose.yml`
|
||||
|
||||
+5
-4
@@ -392,8 +392,9 @@ COPY --from=builder /app/src/generated ./src/generated
|
||||
# pending migration count, the second runs `migrate deploy` with its
|
||||
# lock-timeout retry. `db-dump.mjs` takes the dump before migrating, and
|
||||
# `db-restore.mjs` is the `db-restore` service; both share
|
||||
# `src/lib/database-backup/dump-core.mjs` with the app. Root-owned on purpose:
|
||||
# the app user can run them but not rewrite them.
|
||||
# `src/lib/database-backup/dump-core.mjs` with the app. The files are
|
||||
# root-owned, so the app user can run them but not edit them in place. The
|
||||
# directory around them stays the app user's.
|
||||
COPY --from=builder /app/scripts/reset-password.mjs ./scripts/reset-password.mjs
|
||||
COPY --from=builder /app/scripts/pending-migrations.mjs ./scripts/pending-migrations.mjs
|
||||
COPY --from=builder /app/scripts/migrate-deploy.mjs ./scripts/migrate-deploy.mjs
|
||||
@@ -421,8 +422,8 @@ RUN node scripts/db-dump.mjs 2>&1 | grep -q "db-dump: usage:" && \
|
||||
pg_restore --version | grep -q "(PostgreSQL) 18\."
|
||||
|
||||
# The migration CLI from the `prisma-cli` stage. The Prisma config loads
|
||||
# dotenv from /app, so expose the isolated copy there. Root-owned: the app
|
||||
# user can run it but not rewrite it.
|
||||
# dotenv from /app, so expose the isolated copy there. /opt/prisma-cli is
|
||||
# root-owned: the app user can run it but not change it.
|
||||
COPY --from=prisma-cli /opt/prisma-cli /opt/prisma-cli
|
||||
RUN ln -sfn /opt/prisma-cli/node_modules/.bin/tsx /usr/local/bin/healthlog-tsx && \
|
||||
ln -sfn /opt/prisma-cli/node_modules/dotenv /app/node_modules/dotenv && \
|
||||
|
||||
@@ -62,6 +62,9 @@ function parseArgs(argv) {
|
||||
};
|
||||
if (/^https?:\/\//i.test(arg)) {
|
||||
opts.url ??= arg;
|
||||
} else if (/^[a-z0-9.[\]:-]+(:\d+)?\//i.test(arg)) {
|
||||
// busybox wget takes `127.0.0.1:3000/api/health` without a scheme.
|
||||
opts.url ??= `http://${arg}`;
|
||||
} else if (arg === "--spider") {
|
||||
opts.spider = true;
|
||||
} else if (arg === "-q" || arg === "--quiet") {
|
||||
|
||||
@@ -92,7 +92,12 @@ describe("runtime package pins", () => {
|
||||
pg!.image,
|
||||
);
|
||||
expect(client, `a pinned major 18 image, not ${pg!.image}`).not.toBeNull();
|
||||
const db = /^\s*image:\s*postgres:(\d+\.\d+)-alpine$/m.exec(COMPOSE);
|
||||
// The `db` service's own image line, not the first postgres image in the
|
||||
// file: `db-upgrade` carries the previous major.
|
||||
const db =
|
||||
/^ {2}db:\n(?:(?! {2}\S).*\n)*? {4}image:\s*postgres:(\d+\.\d+)-alpine$/m.exec(
|
||||
COMPOSE,
|
||||
);
|
||||
expect(db, "the compose file pins the database").not.toBeNull();
|
||||
// One decision: a database minor bump moves the client with it.
|
||||
expect(client![1]).toBe(db![1]);
|
||||
|
||||
@@ -175,6 +175,12 @@ describe("wget shim", () => {
|
||||
expect((await wget(["--spider"])).code).toBe(2);
|
||||
});
|
||||
|
||||
it("takes a URL without a scheme, like busybox wget", async () => {
|
||||
const bare = base.replace(/^http:\/\//, "");
|
||||
expect((await wget(["-qO-", `${bare}/ok`])).code).toBe(0);
|
||||
expect((await wget(["-qO-", `${bare}/down`])).code).toBe(1);
|
||||
});
|
||||
|
||||
it("is what the image installs as wget", () => {
|
||||
const dockerfile = readSource("Dockerfile", "AS runner");
|
||||
const runner = dockerfile.slice(dockerfile.search(/^FROM .* AS runner$/m));
|
||||
|
||||
Reference in new issue
Block a user