fix: skip backend pod migrations when migrationJob is enabled - #135
Merged
Merged
Conversation
When migrationJob.enabled=true, the backend Deployment pods still ran DB migrations on startup alongside the dedicated pre-upgrade migration Job, so a helm upgrade had the Job and every rolling backend pod racing for the knex migration lock. Gate the backend container command so that when the Job is enabled (and image.command is unset) the pod starts the server without migrating, leaving the Job as the sole migrator. Default and worker behavior unchanged. Bump chart version 2.9.0 -> 2.9.1. Closes: PROD-8562 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ZeRego
reviewed
Jun 30, 2026
ZeRego
approved these changes
Jun 30, 2026
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.
Closes: https://linear.app/lightdash/issue/PROD-8562
Closes #134
Summary
When
migrationJob.enabled=true, the backend Deployment pods still ran DB migrations on startup, in addition to the dedicated pre-upgrade migration Job. On ahelm upgradethe Job and every rolling backend pod then ranknex migrate:latestagainst the same database concurrently, contending on the knex migration lock; a migrator killed mid-run left the lock held, blocking every subsequent startup.Affects only deployments that opt into
migrationJob.enabled=true(default isfalse). The default path — and the workers — are unchanged.Root cause
The chart never told backend pods to skip migrating when the Job was enabled. The backend container command rendered unconditionally, and
image.commandis unset by default:The image entrypoint (
docker/prod-entrypoint.shinlightdash/lightdash) migrates before starting the server (pnpm -F backend migrate-productionthenexec node dist/index.js). So enablingmigrationJobadded a migrator (the Job) without removing the per-pod one —1 Job + N replicasall migrating at once. The worker templates were never affected because they already set their own non-migrating command. The pre-upgrade Job was introduced in #121, where this exact gap was raised and deferred.Fix
When
migrationJob.enabledand the operator hasn't set their ownimage.command, give the backend container an explicit command that starts the server without migrating, so the Job is the sole migrator.dumb-initis preserved as PID 1 (the image ENTRYPOINT wraps it) andnode dist/index.jsis the image's default CMD — i.e. the normal boot minus the migrate step.templates/backendDeployment.yaml— gate the backendcommand: userimage.commandwins if set; else whenmigrationJob.enabledrender["dumb-init", "--", "node", "dist/index.js"]; else render nothing (image entrypoint migrates, exactly as today — preserving the kubectl-update-without-helm path Run database migrations in pre-install,pre-upgrade hook #121 wanted to keep).values.yaml— document themigrationJob.enabledbehavioural coupling.Chart.yaml/README.md— bump chart version2.9.0 -> 2.9.1(required byct lint).Out of scope: a
SKIP_DB_MIGRATIONSenv toggle inprod-entrypoint.sh(lives inlightdash/lightdash); the/api/v1/healthconnection-pool pressure during upgrades (upstream).Before / After
Rendered
templates/backendDeployment.yamlwithmigrationJob.enabled=true:migrationJob.enabled=false(default) — unchanged in both:Test plan
helm lint .— 0 charts failed.helm template … --set migrationJob.enabled=true→ backend renders the non-migrating command; the-migrateJob still renders.helm template …(default) → no backendcommand:line (image entrypoint migrates) — unchanged from before the fix.image.commandset → user value wins, with and withoutmigrationJob.enabled.ct lint --all+ct installon kind (runs on the PR).🤖 Generated with Claude Code