fix(docker): make empty-database setup work in the production image - #30
Merged
Conversation
The Docker image failed to initialize an empty database (#28): setupDatabase() shelled out to `npx drizzle-kit push`, but drizzle-kit and its config are dev-only and absent from the pruned standalone image. The failure was then swallowed and the app booted in a broken state. Fixes: - setupDatabase() now runs the committed SQL migrations programmatically (shared runMigrations() from packages/db), with connection retries and a guard against foreign databases; on failure it exits non-zero so the container crash-loops visibly instead of serving a broken app - bundle packages/db migrations into the app image (MIGRATIONS_FOLDER) - /api/health now returns 503 until the core tables exist, so the Docker healthcheck reflects real readiness - CI: new smoke-test job boots the image against an empty MySQL, waits for health 200 and asserts core tables exist; it gates the registry push Latent bugs surfaced by the smoke test, also fixed: - migrate.ts queried __drizzle_migrations before creating it (empty-DB path never worked) - migrations 0032/0034 hold several statements without statement-breakpoint markers; migrator connections now enable multipleStatements - .dockerignore patterns only matched at the repo root: nested .next and the 24GB .turbo cache were shipped in the build context - public/ was copied without --chown, crashing the non-root app when build host permissions were restrictive Fixes #28 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Running the published Docker image against an empty MySQL fails to create any tables (#28).
setupDatabase()shelled out tonpx drizzle-kit push, but drizzle-kit and its config are dev-only and absent from the pruned standalone image. The error was then swallowed, so the app booted into a silently broken state.Fixes
setupDatabase()runs the committed SQL migrations programmatically via a sharedrunMigrations()(packages/db), with connection retries and a guard against foreign databases. On failure it now exits non-zero — visible crash loop instead of a broken "running" app./app/migrations+MIGRATIONS_FOLDER)./api/healthreturns 503 until the core tables exist, so the existing Docker healthcheck reflects real readiness.smoke-testjob builds the image, boots it against an empty MySQL 8.4, waits for health 200 and asserts the core tables exist. It gates the registry push on tags and runs on PRs touching docker/db files — this is the guard that would have caught Louez - Docker "no tables created" #28 before release.Latent bugs surfaced by the smoke test (also fixed)
migrate.tsqueried__drizzle_migrationsbefore creating it — the empty-database path had never worked.0032/0034contain multiple statements without--> statement-breakpoint; migrator connections now enablemultipleStatements(migration files untouched, hashes preserved)..dockerignorepatterns only matched at the repo root: nested.nextand the multi-GB.turbocache were shipped in the build context.public/was copied without--chown, crashing the non-root app when build-host permissions were restrictive.Verification
Full smoke test run locally on the production image (Colima): empty MySQL 8.4 → 53 migrations applied, 62 tables created,
/api/health200, Docker healthcheckhealthy, restart idempotent ("Database is up to date"). Typecheck passes onpackages/dbandapps/web.Fixes #28
🤖 Generated with Claude Code