From f2b9993427e7e45e7b343193010ecf89751f2c50 Mon Sep 17 00:00:00 2001 From: Nick Szaunig Date: Thu, 27 Aug 2026 08:02:58 +0200 Subject: [PATCH] fix: OOM-Crash beim Seed-Schritt durch Vorkompilieren beheben ts-node prisma/seed.ts lief bisher live im Container - der TypeScript-Compiler dafuer braucht deutlich mehr Heap als das 512Mi-Pod-Limit, daher sporadische "JavaScript heap out of memory"- Crashes beim Start (manchmal lief's, manchmal nicht, reine GC-Zufaelligkeit an der Speichergrenze). Fix: seed.ts wird jetzt wie main.ts beim Docker-Build vorkompiliert (tsconfig.seed.json, rootDir bewusst auf prisma/ statt Projekt-Root gesetzt, damit der relative Import '../generated/prisma' nach dem Kompilieren weiterhin auf denselben Pfad zeigt). Laufzeit-CMD startet nur noch plain `node dist/seed.js` - kein TypeScript-Compiler mehr im Container. ts-node/typescript zurueck zu devDependencies (nur noch fuer den Build-Schritt gebraucht, nicht mehr zur Laufzeit). incremental in tsconfig.seed.json explizit deaktiviert - ein stale tsconfig.seed.tsbuildinfo liess tsc beim zweiten Testlauf sonst faelschlich "nichts zu tun" melden (derselbe Fallstrick wie bei tsconfig.build.tsbuildinfo). Verifiziert: tsc/eslint clean, 304/304 Tests, Build reproduzierbar (zweimal hintereinander ohne Cache-Reset getestet), node dist/seed.js lief erfolgreich gegen die echte lokale DB (erkannte den bestehenden Admin korrekt und legte ihn nicht erneut an). --- ApiCore-Backend/Dockerfile | 14 ++++++++------ ApiCore-Backend/package-lock.json | 24 +++++++++++++++++++++--- ApiCore-Backend/package.json | 10 +++++----- ApiCore-Backend/tsconfig.seed.json | 10 ++++++++++ 4 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 ApiCore-Backend/tsconfig.seed.json diff --git a/ApiCore-Backend/Dockerfile b/ApiCore-Backend/Dockerfile index 807a3f3..56b3cc4 100644 --- a/ApiCore-Backend/Dockerfile +++ b/ApiCore-Backend/Dockerfile @@ -15,14 +15,16 @@ COPY package.json package-lock.json ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist COPY --from=builder /app/generated ./generated -# schema.prisma, migrations/, seed.ts und prisma.config.ts: noetig fuer -# `npm run migrate:deploy` und `npm run seed`, die der Container beim Start -# selbst ausfuehrt (siehe CMD unten), bevor der Server Verbindungen annimmt. -# tsconfig.json: ts-node (Laufzeit-Dependency, siehe package.json) braucht es, -# um seed.ts direkt auszufuehren, ohne separaten Kompilierschritt. +# schema.prisma, migrations/ und prisma.config.ts: noetig fuer +# `npm run migrate:deploy`, das der Container beim Start selbst ausfuehrt +# (siehe CMD unten). seed.ts selbst wird NICHT zur Laufzeit ausgefuehrt - +# `npm run build` kompiliert es vorab zu dist/seed.js (siehe +# tsconfig.seed.json), das schon in ./dist enthalten ist. Frueher lief +# `ts-node prisma/seed.ts` direkt im Container: der TypeScript-Compiler +# braucht dafuer deutlich mehr Heap als das 512Mi-Pod-Limit hergibt und +# fuehrte zu sporadischen OOM-Crashes beim Start. COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/prisma.config.ts ./prisma.config.ts -COPY --from=builder /app/tsconfig.json ./tsconfig.json EXPOSE 3001 USER node # migrate deploy ist idempotent und nutzt einen DB-seitigen Advisory-Lock, diff --git a/ApiCore-Backend/package-lock.json b/ApiCore-Backend/package-lock.json index fc20b18..1f120b4 100644 --- a/ApiCore-Backend/package-lock.json +++ b/ApiCore-Backend/package-lock.json @@ -31,9 +31,7 @@ "prisma": "^7.9.1", "qrcode": "^1.5.4", "reflect-metadata": "^0.2.2", - "rxjs": "^7.8.1", - "ts-node": "^10.9.2", - "typescript": "^5.7.3" + "rxjs": "^7.8.1" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", @@ -61,7 +59,9 @@ "supertest": "^7.0.0", "ts-jest": "^29.2.5", "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3", "typescript-eslint": "^8.20.0" } }, @@ -750,6 +750,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -762,6 +763,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -2061,6 +2063,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -2081,6 +2084,7 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3247,24 +3251,28 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.13.tgz", "integrity": "sha512-gcLdvR9HO1ZJBypsOGqaP6TFEzb6vIta0KSTLt9NAQ6pXQO3cRgSVyCN6pzYqI9DlJgY71XKO0dpDhCf08b3pg==", + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { @@ -4732,6 +4740,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4767,6 +4776,7 @@ "version": "8.3.5", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -4941,6 +4951,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -5883,6 +5894,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { @@ -6192,6 +6204,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -9076,6 +9089,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, "license": "ISC" }, "node_modules/makeerror": { @@ -11812,6 +11826,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -11975,6 +11990,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -12195,6 +12211,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -12598,6 +12615,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/ApiCore-Backend/package.json b/ApiCore-Backend/package.json index 52a83ec..a9d41d9 100644 --- a/ApiCore-Backend/package.json +++ b/ApiCore-Backend/package.json @@ -6,7 +6,7 @@ "private": true, "license": "UNLICENSED", "scripts": { - "build": "nest build", + "build": "nest build && tsc -p tsconfig.seed.json", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", @@ -20,7 +20,7 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", "migrate:deploy": "prisma migrate deploy", - "seed": "ts-node prisma/seed.ts" + "seed": "node dist/seed.js" }, "dependencies": { "@nestjs/common": "^11.0.1", @@ -45,9 +45,7 @@ "prisma": "^7.9.1", "qrcode": "^1.5.4", "reflect-metadata": "^0.2.2", - "rxjs": "^7.8.1", - "ts-node": "^10.9.2", - "typescript": "^5.7.3" + "rxjs": "^7.8.1" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", @@ -75,7 +73,9 @@ "supertest": "^7.0.0", "ts-jest": "^29.2.5", "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3", "typescript-eslint": "^8.20.0" }, "jest": { diff --git a/ApiCore-Backend/tsconfig.seed.json b/ApiCore-Backend/tsconfig.seed.json new file mode 100644 index 0000000..7dc3af5 --- /dev/null +++ b/ApiCore-Backend/tsconfig.seed.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./prisma", + "outDir": "./dist", + "declaration": false, + "incremental": false + }, + "include": ["prisma/seed.ts"] +}