# syntax=docker/dockerfile:1 # # Build context is the REPO ROOT (see docker/docker-compose.yml and # docker/docker-compose.prod.yml: `context: ..`), because this image bundles # both apps/server and the built apps/web static assets, plus the shared # workspace package. FROM node:22-alpine AS base RUN corepack enable # pg_dump — used by modules/admin/backup.ts (Admin > Backups), not just the # standalone scripts/backup.sh. Alpine's postgresql-client tracks a recent # major version; pg_dump's wire protocol is compatible against our # postgres:16-alpine server regardless of exact version match. RUN apk add --no-cache postgresql-client WORKDIR /workspace # ---- deps: install workspace dependencies (cached separately from source) ---- FROM base AS deps COPY package.json pnpm-workspace.yaml pnpm-lock.yaml* ./ COPY apps/server/package.json apps/server/package.json COPY apps/web/package.json apps/web/package.json COPY packages/shared/package.json packages/shared/package.json # Falls back to a non-frozen install until a pnpm-lock.yaml exists in the # repo (run `pnpm install` locally once to generate it, then this can be # tightened to `--frozen-lockfile` for reproducible builds). RUN pnpm install # ---- dev: source comes from the docker-compose.yml bind mount at runtime ---- FROM deps AS dev ENV NODE_ENV=development EXPOSE 8080 8081 CMD ["pnpm", "run", "dev"] # ---- build: compile server + web for the production image ---- FROM deps AS build COPY . . RUN pnpm --filter @notizarr/web build RUN pnpm --filter @notizarr/server build # ---- runtime: minimal image, non-root, only what's needed to run ---- # Deliberately not using `pnpm deploy` here: it's meant for publishable # packages and its file-inclusion rules interact awkwardly with dist/ being # gitignored. A plain workspace-root `pnpm install --prod` + explicit copies # of the two build outputs is more predictable and easy to reason about. FROM node:22-alpine AS runtime RUN corepack enable WORKDIR /app ENV NODE_ENV=production ENV STATIC_WEB_DIR=/app/apps/web/dist RUN addgroup -S notizarr && adduser -S notizarr -G notizarr COPY --from=build /workspace/package.json /workspace/pnpm-workspace.yaml /workspace/pnpm-lock.yaml* ./ COPY --from=build /workspace/apps/server/package.json ./apps/server/package.json COPY --from=build /workspace/apps/web/package.json ./apps/web/package.json COPY --from=build /workspace/packages/shared/package.json ./packages/shared/package.json RUN pnpm install --prod COPY --from=build /workspace/apps/server/dist ./apps/server/dist COPY --from=build /workspace/apps/web/dist ./apps/web/dist COPY --from=build /workspace/apps/server/healthcheck.js ./apps/server/healthcheck.js USER notizarr EXPOSE 8080 8081 HEALTHCHECK --interval=15s --timeout=5s --retries=3 --start-period=20s \ CMD ["node", "apps/server/healthcheck.js"] CMD ["node", "apps/server/dist/index.js"]