Skip to content

Production Docker image installs dependencies via npm/package-lock.json — bun.lock is explicitly excluded from the build context #424

Description

@abayomicornelius

Where: Dockerfile (both stages) and .dockerignore.

What's wrong: every other part of this repo's tooling is bun-first:
bun.lock is the lockfile actually kept in sync with package.json,
every CI workflow (ci.yml, release.yml, security-audit.yml) installs
via bun install --frozen-lockfile, package.json's engines field lists
bun >=1.0.0, and README.md/docs/SETUP.md instruct contributors to use
bun install/bun run dev exclusively. But the Dockerfile — the thing
that actually produces the artifact deployed to staging/production per
deploy.yml — does this instead:

# builder stage
COPY package*.json ./
RUN npm ci --ignore-scripts
...
RUN npm run build

# production stage
COPY package*.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force

npm ci resolves and installs strictly from package-lock.json, not
bun.lock. And .dockerignore makes this explicit rather than
accidental — it lists bun.lock among the excluded files, so it isn't
even available in the build context for the Docker build to use.

Impact: this means the dependency versions actually running in the
deployed production container come from package-lock.json — a file that
(per the separately-filed CI/npm-audit issue) no automated process ever
regenerates or validates against package.json/bun.lock, since every CI
job installs via bun install instead. In other words: CI builds and
tests the application against one set of resolved dependency versions
(bun.lock), while the artifact that's actually shipped and run in
production is built against a different, independently-drifting set
(package-lock.json) — the exact "what we tested isn't what we shipped"
gap that lockfiles exist to prevent. A patch/minor version difference in
even one transitive dependency between the two lockfiles means CI's green
checkmark doesn't actually vouch for the container that goes to
production.

Suggested fix: build the Docker image with bun (RUN bun install --frozen-lockfile and bun run build, using a bun base image or
installing bun in the node:20-alpine stage) so the same lockfile that CI
validates against is the one that ships, and remove bun.lock from
.dockerignore.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-backlogKnown bugs and edge caseshighSignificant functionality broken, no workaround, affects multiple usersinfrastructureDevOps and infrastructure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions