diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml index 2dbbaa2..136728d 100644 --- a/.gitea/workflows/docker.yml +++ b/.gitea/workflows/docker.yml @@ -61,7 +61,16 @@ jobs: STAGING=".ci/docker/backend" rm -rf "$STAGING" mkdir -p "$STAGING/packages/contracts" "$STAGING/backend" - cp package.json package-lock.json "$STAGING/" + cp package-lock.json "$STAGING/" + node <<'NODE' + const fs = require("node:fs") + const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")) + pkg.workspaces = ["packages/*", "backend"] + pkg.dependencies = {} + pkg.devDependencies = {} + delete pkg.scripts + fs.writeFileSync(".ci/docker/backend/package.json", `${JSON.stringify(pkg, null, 2)}\n`) + NODE cp packages/contracts/package.json packages/contracts/tsconfig.json "$STAGING/packages/contracts/" cp -R packages/contracts/src "$STAGING/packages/contracts/" cp backend/package.json backend/tsconfig.json "$STAGING/backend/" @@ -70,6 +79,7 @@ jobs: cp -R backend/drizzle "$STAGING/backend/" fi + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 diff --git a/README.md b/README.md index 7e5c9b5..b0a340b 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ sequenceDiagram - **Node.js 22** (как в `Dockerfile.frontend` и `backend/Dockerfile`). - **npm** с workspaces; установка из корня: `npm ci` или `npm install`. - Для нативной сборки `better-sqlite3` на Linux может понадобиться toolchain (`python3`, `make`, `g++`); в Docker-образе backend они уже ставятся. +- Backend Docker-образ ставит только workspaces `backend` + `contracts` (без корневых Next/React deps); в production логи — JSON без `pino-pretty`. ### Запуск diff --git a/backend/Dockerfile b/backend/Dockerfile index 8543ed9..75e50fb 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -5,10 +5,23 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends python3 make g++ \ && rm -rf /var/lib/apt/lists/* WORKDIR /app +# Do not set NODE_ENV=production here — npm would omit typescript needed for the build stage. COPY package.json package-lock.json ./ COPY packages/contracts/package.json packages/contracts/ COPY backend/package.json backend/ -RUN npm ci --workspace=@mmapp/contracts --workspace=mikrotik-manager-backend --include-workspace-root --ignore-scripts \ +# Drop root frontend deps (Next/React/UI) so backend image stays lean. +RUN node -e "\ + const fs=require('fs');\ + const p=JSON.parse(fs.readFileSync('package.json','utf8'));\ + p.dependencies={};\ + p.devDependencies={};\ + delete p.scripts;\ + p.workspaces=['packages/*','backend'];\ + fs.writeFileSync('package.json', JSON.stringify(p,null,2)+'\\n');\ +" +# Prefer npm ci; if lockfile rejects stripped root package.json, fall back to install. +RUN (npm ci --workspace=@mmapp/contracts --workspace=mikrotik-manager-backend --ignore-scripts \ + || npm install --workspace=@mmapp/contracts --workspace=mikrotik-manager-backend --ignore-scripts) \ && npm rebuild better-sqlite3 FROM deps AS build diff --git a/backend/package.json b/backend/package.json index 915ed09..768566a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -24,7 +24,6 @@ "drizzle-orm": "^0.45.2", "fastify": "^5.8.5", "fastify-plugin": "^5.1.0", - "pino-pretty": "^13.1.3", "undici": "^8.1.0", "zod": "^4.4.1" }, @@ -33,6 +32,7 @@ "@types/node": "^22.15.3", "drizzle-kit": "^0.31.10", "jose": "^6.2.11", + "pino-pretty": "^13.1.3", "tsx": "^4.19.3", "typescript": "^5.8.3" } diff --git a/backend/src/index.ts b/backend/src/index.ts index db12c5d..f93305f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -29,22 +29,26 @@ export async function buildApp(opts?: { logger?: boolean startScheduler?: boolean }): Promise { + const usePrettyLogger = + opts?.logger !== false && process.env.NODE_ENV !== "production" const app = Fastify({ bodyLimit: 512 * 1024 * 1024, requestTimeout: 10 * 60 * 1000, logger: opts?.logger === false ? false - : { - transport: { - target: "pino-pretty", - options: { - colorize: true, - translateTime: "HH:MM:ss", - ignore: "pid,hostname", + : usePrettyLogger + ? { + transport: { + target: "pino-pretty", + options: { + colorize: true, + translateTime: "HH:MM:ss", + ignore: "pid,hostname", + }, }, - }, - }, + } + : true, }) app.setValidatorCompiler(validatorCompiler) diff --git a/package-lock.json b/package-lock.json index 65ca490..ce317aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,6 @@ "drizzle-orm": "^0.45.2", "fastify": "^5.8.5", "fastify-plugin": "^5.1.0", - "pino-pretty": "^13.1.3", "undici": "^8.1.0", "zod": "^4.4.1" }, @@ -67,6 +66,7 @@ "@types/node": "^22.15.3", "drizzle-kit": "^0.31.10", "jose": "^6.2.11", + "pino-pretty": "^13.1.3", "tsx": "^4.19.3", "typescript": "^5.8.3" } @@ -3951,6 +3951,70 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.8.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.8.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz", @@ -5741,6 +5805,7 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -5967,6 +6032,7 @@ "version": "4.6.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, "license": "MIT", "engines": { "node": "*" @@ -7237,6 +7303,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-4.0.3.tgz", "integrity": "sha512-58apWr0GUiDFM8+3afrO6eYwJBn9ZAhDOzG3L+/9llab/haCARS2UIfffmOurYLwbgDRs8n0rfr6qAAPEAuAQw==", + "dev": true, "license": "MIT" }, "node_modules/fast-decode-uri-component": { @@ -7370,6 +7437,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, "license": "MIT" }, "node_modules/fast-string-truncated-width": { @@ -8166,6 +8234,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "dev": true, "license": "MIT" }, "node_modules/hermes-estree": { @@ -8977,6 +9046,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -10573,6 +10643,7 @@ "version": "13.1.3", "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.3.tgz", "integrity": "sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==", + "dev": true, "license": "MIT", "dependencies": { "colorette": "^2.0.7", @@ -10597,6 +10668,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", + "dev": true, "license": "MIT", "engines": { "node": ">=14.16"