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
|
password hashing and the Prisma engine run their glibc builds. The
|
||||||
published arm64 image renders PDF pages on a Raspberry Pi 4 again, where
|
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
|
the Alpine build of the renderer needs CPU features an ARMv8.0 core
|
||||||
lacks. Node security releases now reach the image with the official
|
lacks. Node security releases now come with the official Node image,
|
||||||
Node image, usually within days. The image carries no package manager:
|
which HealthLog pins and moves forward with its releases. The image
|
||||||
npm, npx, corepack and yarn are removed. `pg_dump` and `pg_restore` are
|
carries no package manager: npm, npx, corepack and yarn are removed.
|
||||||
PostgreSQL 18.6, the bundled database's version; `psql` is no longer in
|
`pg_dump` and `pg_restore` are PostgreSQL 18.6, the bundled database's
|
||||||
the app image, so run it in the `db` container. A health check that
|
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
|
still calls `wget`, from a compose file copied before this release or a
|
||||||
platform template, keeps working: the image carries a small `wget` that
|
platform template, keeps working: the image carries a small `wget` that
|
||||||
answers health checks and nothing else. The current `docker-compose.yml`
|
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
|
# pending migration count, the second runs `migrate deploy` with its
|
||||||
# lock-timeout retry. `db-dump.mjs` takes the dump before migrating, and
|
# lock-timeout retry. `db-dump.mjs` takes the dump before migrating, and
|
||||||
# `db-restore.mjs` is the `db-restore` service; both share
|
# `db-restore.mjs` is the `db-restore` service; both share
|
||||||
# `src/lib/database-backup/dump-core.mjs` with the app. Root-owned on purpose:
|
# `src/lib/database-backup/dump-core.mjs` with the app. The files are
|
||||||
# the app user can run them but not rewrite them.
|
# 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/reset-password.mjs ./scripts/reset-password.mjs
|
||||||
COPY --from=builder /app/scripts/pending-migrations.mjs ./scripts/pending-migrations.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
|
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\."
|
pg_restore --version | grep -q "(PostgreSQL) 18\."
|
||||||
|
|
||||||
# The migration CLI from the `prisma-cli` stage. The Prisma config loads
|
# 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
|
# dotenv from /app, so expose the isolated copy there. /opt/prisma-cli is
|
||||||
# user can run it but not rewrite it.
|
# root-owned: the app user can run it but not change it.
|
||||||
COPY --from=prisma-cli /opt/prisma-cli /opt/prisma-cli
|
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 && \
|
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 && \
|
ln -sfn /opt/prisma-cli/node_modules/dotenv /app/node_modules/dotenv && \
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ function parseArgs(argv) {
|
|||||||
};
|
};
|
||||||
if (/^https?:\/\//i.test(arg)) {
|
if (/^https?:\/\//i.test(arg)) {
|
||||||
opts.url ??= 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") {
|
} else if (arg === "--spider") {
|
||||||
opts.spider = true;
|
opts.spider = true;
|
||||||
} else if (arg === "-q" || arg === "--quiet") {
|
} else if (arg === "-q" || arg === "--quiet") {
|
||||||
|
|||||||
@@ -92,7 +92,12 @@ describe("runtime package pins", () => {
|
|||||||
pg!.image,
|
pg!.image,
|
||||||
);
|
);
|
||||||
expect(client, `a pinned major 18 image, not ${pg!.image}`).not.toBeNull();
|
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();
|
expect(db, "the compose file pins the database").not.toBeNull();
|
||||||
// One decision: a database minor bump moves the client with it.
|
// One decision: a database minor bump moves the client with it.
|
||||||
expect(client![1]).toBe(db![1]);
|
expect(client![1]).toBe(db![1]);
|
||||||
|
|||||||
@@ -175,6 +175,12 @@ describe("wget shim", () => {
|
|||||||
expect((await wget(["--spider"])).code).toBe(2);
|
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", () => {
|
it("is what the image installs as wget", () => {
|
||||||
const dockerfile = readSource("Dockerfile", "AS runner");
|
const dockerfile = readSource("Dockerfile", "AS runner");
|
||||||
const runner = dockerfile.slice(dockerfile.search(/^FROM .* AS runner$/m));
|
const runner = dockerfile.slice(dockerfile.search(/^FROM .* AS runner$/m));
|
||||||
|
|||||||
Reference in new issue
Block a user