Add production compose stack and stop idle load in containers
The development stack was running permanently on a server: polling file watchers, a healthcheck that rendered a full page every five seconds and no memory limit grew next dev to 10 GB and pushed the host into swap. - add compose.prod.yaml running compiled output in separate api/web services - make the Dockerfile multi-stage with dev and prod targets, prune devDependencies and run the runtime image as node instead of root - bake API_INTERNAL_URL at build time; next start ignores it at runtime because rewrite destinations are resolved into routes-manifest.json - drop CHOKIDAR_USEPOLLING and WATCHPACK_POLLING - probe /health instead of /, which redirects to /projects and made every healthcheck render the project list - give every service a memory limit and forbid swap in production - rename the development compose project to leistungsbilanz-dev so its down command cannot target the production stack - bind development ports to localhost - close the http server and the SQLite handle on SIGTERM/SIGINT - match probe user agents in the navigation log filter; Node's fetch sends one, so the previous check never matched - exit docker-start.sh when either supervised process dies - remove drizzle.config.js, a compiled copy drizzle-kit never reads, and the pre-Next index.html/styles.css leftovers Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
a17e2e3f4b
commit
01fa527b9c
14 changed files with 424 additions and 118 deletions
51
Dockerfile
Normal file → Executable file
51
Dockerfile
Normal file → Executable file
|
|
@ -1,14 +1,51 @@
|
|||
FROM node:22
|
||||
WORKDIR /app
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# deps: complete dependency tree, shared by the build and the dev target.
|
||||
# Stays on the full node image because better-sqlite3 needs a toolchain.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM node:22 AS deps
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# dev: watch-mode target used by compose.yaml. Keeps devDependencies so
|
||||
# tsx, drizzle-kit and next dev are available. Sources come from bind mounts.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM deps AS dev
|
||||
ENV NODE_ENV=development
|
||||
COPY . .
|
||||
RUN mkdir -p data
|
||||
EXPOSE 3000 3001
|
||||
CMD ["npm", "run", "dev:api"]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# build: compile the API to dist/ and the frontend to .next/, then drop
|
||||
# devDependencies so the runtime stage carries only what it executes.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM deps AS build
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
# Next.js resolves next.config.mjs rewrites at build time and writes the literal
|
||||
# destination into .next/routes-manifest.json. Setting API_INTERNAL_URL only at
|
||||
# runtime has no effect on `next start`, so the API address of the target
|
||||
# topology has to be known here. Server components read the variable at runtime.
|
||||
ARG API_INTERNAL_URL=http://localhost:3000
|
||||
ENV API_INTERNAL_URL=$API_INTERNAL_URL
|
||||
COPY . .
|
||||
RUN npm run build:api && npm run build:web
|
||||
RUN npm prune --omit=dev
|
||||
|
||||
RUN mkdir -p data && chmod +x scripts/docker-start.sh
|
||||
|
||||
EXPOSE 3001
|
||||
|
||||
CMD ["sh", "scripts/docker-start.sh"]
|
||||
# ---------------------------------------------------------------------------
|
||||
# prod: runtime image. node:22-slim shares the Debian release of the build
|
||||
# stage, so the compiled better-sqlite3 binding stays loadable.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM node:22-slim AS prod
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
WORKDIR /app
|
||||
COPY --from=build --chown=node:node /app ./
|
||||
RUN mkdir -p data && chown node:node data
|
||||
USER node
|
||||
EXPOSE 3000 3001
|
||||
CMD ["node", "dist/server/index.js"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue