Skip to content

chore(docker): migrate-on-startup + tini + image hygiene#41

Merged
CryptoJones merged 1 commit into
masterfrom
chore/docker-audit-and-migrate-on-startup
May 17, 2026
Merged

chore(docker): migrate-on-startup + tini + image hygiene#41
CryptoJones merged 1 commit into
masterfrom
chore/docker-audit-and-migrate-on-startup

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

Closes #40.

Summary

Fixes the real defect — docker compose up doesn't apply Sequelize migrations — and bundles five small image-hygiene changes.

  • migrate service in compose (load-bearing): runs sequelize-cli db:migrate between the SQL bootstrap and api start. Without this, any migration after the initial baseline never applied in a containerized deploy.
  • sequelize-clidependencies: was devDep, would be missing from npm ci --omit=dev.
  • tini as PID 1: clean signal forwarding to the Node process (server.js already has the graceful-shutdown handler; tini just makes sure it gets the signal).
  • Node-native HEALTHCHECK: drops wget + apt-install layer.
  • OCI image labels: source / license / vendor.
  • .dockerignore tightening: excludes tests/, vitest.config.js, docs; keeps LICENSE (Apache-2.0 §4(c) requires it ships with derivative works).

Test plan

  • docker compose config parses cleanly with services in correct dependency order (postgres → setup → migrate → api)
  • vitest: 167/167 still passing (no application code touched)
  • docker compose up --build end-to-end run on a real Docker daemon (couldn't verify in author's environment — current shell lacks daemon access)

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

Five Docker improvements bundled. The migrate one is the only
functional defect; the rest are hygiene.

  1. **migrate service in compose** — `docker compose up` now runs
     `sequelize-cli db:migrate` between the SQL bootstrap (`setup`)
     and the `api` service start. Without this, recent migrations
     (e.g. 20260517000000-purchase-orders-and-archive-columns)
     never apply in a containerized deploy and the api boots
     against an out-of-date schema.

  2. **sequelize-cli → dependencies** — was a devDependency, which
     would make the production `npm ci --omit=dev` build skip it
     and crash the new migrate service. It needs to ship in the
     runtime image. Lockfile regenerated.

  3. **tini as PID 1** — Node-as-PID-1 has known signal-handling
     quirks (some default signals aren't delivered by the kernel
     to PID 1). server.js already handles SIGTERM via the
     graceful-shutdown path; tini just makes sure it actually
     receives the signal. Adds ~250kB to the image.

  4. **Node-native HEALTHCHECK** — drops `wget` (and its apt
     install layer) in favor of `node -e '...require("http")...'`.
     The new probe still hits /healthz and still verifies the
     `"status":"ok"` JSON body, just without the extra package.

  5. **OCI image labels** — `org.opencontainers.image.*` annotations
     so registries (and `docker inspect`) surface source URL,
     license, and vendor metadata.

  6. **.dockerignore tightening** — exclude `tests/`, `vitest.config.js`,
     `CHANGELOG.md`, `README.md`, `docs/` from the runtime image.
     Keep `LICENSE` (Apache-2.0 §4(c) requires it accompany
     distributed derivative works, including container images).

Verified via `docker compose config` (file parses, services declared
in correct dependency order). Container build itself not run in
this env — local Docker daemon access blocked.

Tests: 167/167 still passing (no application code touched).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CryptoJones CryptoJones merged commit b9198e4 into master May 17, 2026
3 checks passed
@CryptoJones CryptoJones deleted the chore/docker-audit-and-migrate-on-startup branch May 17, 2026 23:37
CryptoJones added a commit that referenced this pull request May 17, 2026
The endpoint table in the README still showed only Customer +
TimeEntry — but #39 added ten more entities (Worker, Company,
BillingType, InventoryItem, Job, Invoice, CustomerPayment,
InvoiceJob, ProductEntry, VersionInfo) for a total of 35 paths.
This appends one row per new entity-group rather than restructuring
the table; the canonical machine-readable contract remains
`/openapi.json`.

CHANGELOG [Unreleased] picks up entries for the API surface
expansion (#38 / PR #39) and the Docker hygiene pass
(#40 / PR #41). Keeps the prior [Unreleased] entries intact
in a "earlier in [Unreleased] window" subhead so the prior history
isn't lost.

Co-authored-by: Aaron K. Clark <akclark@thenetwerk.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker: migrate step missing from compose; image hygiene cleanup

1 participant