Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the backend container build to produce a smaller production image by bundling/minifying the backend into a single runtime artifact and switching the runtime stage to a distroless Node.js base image, alongside tightening the Docker build context via .dockerignore.
Changes:
- Refactors
packages/backend/Dockerfileto build + bundle a singleruntime.cjsartifact and run it from a distrolessnodejs20nonroot image. - Removes production
npm ci --omit=devinstall from the runtime stage (nonode_modulescopied into the final image). - Expands
.dockerignoreto exclude VCS metadata, coverage outputs, and other workspace directories from the build context.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/backend/Dockerfile | Builds and bundles the backend into a single runtime.cjs and runs it in a distroless nonroot image. |
| .dockerignore | Shrinks Docker build context by ignoring repo metadata, coverage, and other package directories. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| COPY package.json package-lock.json ./ | ||
| COPY tsconfig.base.json ./ | ||
| COPY packages/backend/package.json ./packages/backend/ | ||
| COPY packages/backend/tsconfig.json ./packages/backend/ | ||
| COPY packages/backend/tsconfig.prod.json ./packages/backend/ | ||
| COPY packages/backend/src ./packages/backend/src | ||
|
|
||
| # Build and minify backend artifact inside Docker. | ||
| RUN npm ci \ | ||
| && npm run build:prod -w @mocker/backend \ | ||
| && npm run minify -w @mocker/backend \ |
There was a problem hiding this comment.
npm ci is executed from the repo root, but the image only copies the backend workspace files into /usr/src/app/packages. Since the root package.json declares workspaces ("packages/*") and the repo also has packages/frontend/package.json, npm workspaces installs can fail when the other workspace manifests aren’t present in the container filesystem. Consider either copying the missing workspace package.json files (at least packages/frontend/package.json) before npm ci, or switching the Docker build to install/build from packages/backend using packages/backend/package-lock.json so the root workspaces aren’t involved.
| # Copy bundled runtime artifact and writable path from build stage. | ||
| COPY --from=build --chown=65532:65532 /usr/src/app/packages/backend/dist/runtime.cjs ./runtime.cjs | ||
| COPY --from=build --chown=65532:65532 /usr/src/app/images ./images |
There was a problem hiding this comment.
The release stage only copies a single bundled runtime.cjs. The backend uses TypeORM’s getConnectionOptions() and requires TYPEORM_ENTITIES to be set (see src/index.ts), which typically points to entity files on disk (e.g. dist/shared/db/models/*.js). With only runtime.cjs present, TypeORM won’t be able to load entities from the filesystem, so DB initialization is likely to fail at runtime. Either keep/copy the compiled entity files into the image and set TYPEORM_ENTITIES accordingly, or change the app configuration to pass entity classes explicitly (and avoid relying on glob paths) when running from a bundled artifact.
| coverage | ||
| packages/**/coverage | ||
| packages/frontend | ||
| packages/jobs |
There was a problem hiding this comment.
.dockerignore excludes packages/frontend, but the Docker build currently runs npm ci from the repo root with npm workspaces enabled. If you address the workspace install issue by copying packages/frontend/package.json into the build stage, this ignore rule will prevent it from being available to COPY. Consider un-ignoring at least the workspace manifest(s) needed for install (e.g. add a !packages/frontend/package.json exception) or adjust the Docker build to install solely from packages/backend so other workspaces can remain ignored.
| packages/jobs | |
| packages/jobs | |
| !packages/frontend/package.json | |
| !packages/jobs/package.json |
No description provided.