diff --git a/apps/api/docker-entrypoint.sh b/apps/api/docker-entrypoint.sh index 6106dcb..ba89634 100644 --- a/apps/api/docker-entrypoint.sh +++ b/apps/api/docker-entrypoint.sh @@ -16,12 +16,20 @@ if [ ! -f node_modules/prisma/build/index.js ]; then exit 1 fi +SCHEMA_ENGINE=$(ls node_modules/@prisma/engines/schema-engine*debian* 2>/dev/null | head -n 1 || true) +if [ -z "$SCHEMA_ENGINE" ]; then + echo "[api] FATAL: schema-engine لینوکس در release نیست." >&2 + echo "[api] لوکال دوباره بسازید: pnpm run build:api:release" >&2 + ls -la node_modules/@prisma/engines/ 2>&1 || true + exit 1 +fi +echo "[api] schema-engine=$SCHEMA_ENGINE" + if [ -z "${DATABASE_URL:-}" ]; then echo "[api] FATAL: DATABASE_URL is empty" >&2 exit 1 fi -# پسورد را در لاگ نشان نده — فقط host/port/db echo "[api] DATABASE_URL (redacted)=$(node -e "try{const u=new URL(process.env.DATABASE_URL);u.password='***';console.log(u.toString())}catch(e){console.log('INVALID:'+e.message)}")" echo "[api] REDIS_HOST=${REDIS_HOST:-unset} REDIS_PORT=${REDIS_PORT:-unset}" @@ -39,7 +47,7 @@ const host = u.hostname; const port = Number(u.port || 5432); const socket = net.connect({ host, port }); const timer = setTimeout(() => { - console.error(`[api] FATAL: TCP timeout to ${host}:${port} — سرویس postgres در شبکه compose در دسترس نیست`); + console.error(`[api] FATAL: TCP timeout to ${host}:${port}`); socket.destroy(); process.exit(1); }, 10000); @@ -56,11 +64,11 @@ socket.on('error', (err) => { }); NODE -echo "[api] running prisma migrate deploy (60s timeout)..." -if ! timeout 60 node node_modules/prisma/build/index.js migrate deploy --schema=./prisma/schema.prisma; then - echo "[api] FATAL: prisma migrate failed or timed out" >&2 - exit 1 -fi +# جلوگیری از تلاش برای دانلود آنلاین روی سرور +export PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1 + +echo "[api] running prisma migrate deploy..." +node node_modules/prisma/build/index.js migrate deploy --schema=./prisma/schema.prisma echo "[api] migrate done" echo "[api] launching app.js on 0.0.0.0:${PORT:-3000}" diff --git a/apps/api/release/docker-entrypoint.sh b/apps/api/release/docker-entrypoint.sh index 6106dcb..ba89634 100644 --- a/apps/api/release/docker-entrypoint.sh +++ b/apps/api/release/docker-entrypoint.sh @@ -16,12 +16,20 @@ if [ ! -f node_modules/prisma/build/index.js ]; then exit 1 fi +SCHEMA_ENGINE=$(ls node_modules/@prisma/engines/schema-engine*debian* 2>/dev/null | head -n 1 || true) +if [ -z "$SCHEMA_ENGINE" ]; then + echo "[api] FATAL: schema-engine لینوکس در release نیست." >&2 + echo "[api] لوکال دوباره بسازید: pnpm run build:api:release" >&2 + ls -la node_modules/@prisma/engines/ 2>&1 || true + exit 1 +fi +echo "[api] schema-engine=$SCHEMA_ENGINE" + if [ -z "${DATABASE_URL:-}" ]; then echo "[api] FATAL: DATABASE_URL is empty" >&2 exit 1 fi -# پسورد را در لاگ نشان نده — فقط host/port/db echo "[api] DATABASE_URL (redacted)=$(node -e "try{const u=new URL(process.env.DATABASE_URL);u.password='***';console.log(u.toString())}catch(e){console.log('INVALID:'+e.message)}")" echo "[api] REDIS_HOST=${REDIS_HOST:-unset} REDIS_PORT=${REDIS_PORT:-unset}" @@ -39,7 +47,7 @@ const host = u.hostname; const port = Number(u.port || 5432); const socket = net.connect({ host, port }); const timer = setTimeout(() => { - console.error(`[api] FATAL: TCP timeout to ${host}:${port} — سرویس postgres در شبکه compose در دسترس نیست`); + console.error(`[api] FATAL: TCP timeout to ${host}:${port}`); socket.destroy(); process.exit(1); }, 10000); @@ -56,11 +64,11 @@ socket.on('error', (err) => { }); NODE -echo "[api] running prisma migrate deploy (60s timeout)..." -if ! timeout 60 node node_modules/prisma/build/index.js migrate deploy --schema=./prisma/schema.prisma; then - echo "[api] FATAL: prisma migrate failed or timed out" >&2 - exit 1 -fi +# جلوگیری از تلاش برای دانلود آنلاین روی سرور +export PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1 + +echo "[api] running prisma migrate deploy..." +node node_modules/prisma/build/index.js migrate deploy --schema=./prisma/schema.prisma echo "[api] migrate done" echo "[api] launching app.js on 0.0.0.0:${PORT:-3000}" diff --git a/apps/api/release/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node b/apps/api/release/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node new file mode 100644 index 0000000..827ccc8 Binary files /dev/null and b/apps/api/release/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node differ diff --git a/apps/api/release/node_modules/@prisma/engines/schema-engine-debian-openssl-3.0.x b/apps/api/release/node_modules/@prisma/engines/schema-engine-debian-openssl-3.0.x new file mode 100644 index 0000000..54db741 Binary files /dev/null and b/apps/api/release/node_modules/@prisma/engines/schema-engine-debian-openssl-3.0.x differ diff --git a/apps/api/scripts/bundle-release.cjs b/apps/api/scripts/bundle-release.cjs index de4e71f..b48c5bc 100644 --- a/apps/api/scripts/bundle-release.cjs +++ b/apps/api/scripts/bundle-release.cjs @@ -1,15 +1,57 @@ /** * باندل تک‌فایل + نصب Prisma لوکال داخل release/ * خروجی کامل برای Docker کپی‌only: app.js + prisma + node_modules + * + * مهم: schema-engine لینوکس هم باید لوکال دانلود شود؛ وگرنه migrate داخل + * سرور ایران برای دانلود از binaries.prisma.sh تایم‌اوت می‌خورد. */ const esbuild = require('esbuild'); -const { existsSync, mkdirSync, cpSync, writeFileSync, rmSync } = require('fs'); +const { existsSync, mkdirSync, cpSync, writeFileSync, rmSync, readdirSync } = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const root = path.join(__dirname, '..'); const releaseDir = path.join(root, 'release'); const config = require(path.join(root, 'esbuild.release.config.cjs')); +const LINUX_TARGET = 'debian-openssl-3.0.x'; + +async function downloadLinuxEngines() { + const fetchEnginePath = path.join(releaseDir, 'node_modules', '@prisma', 'fetch-engine'); + const enginesVersionPath = path.join(releaseDir, 'node_modules', '@prisma', 'engines-version'); + const enginesDir = path.join(releaseDir, 'node_modules', '@prisma', 'engines'); + + // eslint-disable-next-line import/no-dynamic-require, global-require + const { download } = require(fetchEnginePath); + // eslint-disable-next-line import/no-dynamic-require, global-require + const { enginesVersion } = require(enginesVersionPath); + const version = enginesVersion; + + + console.log('در حال دانلود Prisma engines برای', LINUX_TARGET, 'commit=', version); + + await download({ + binaries: { + 'schema-engine': enginesDir, + 'libquery-engine': enginesDir, + }, + binaryTargets: [LINUX_TARGET], + version, + }); + + const files = readdirSync(enginesDir); + const schemaEngine = files.find((f) => f.startsWith('schema-engine') && f.includes('debian')); + const queryEngine = files.find((f) => f.includes('debian') && f.includes('query')); + + console.log('engines dir:', files.filter((f) => f.includes('engine') || f.includes('debian')).join(', ')); + + if (!schemaEngine) { + throw new Error( + `schema-engine برای ${LINUX_TARGET} دانلود نشد. بدون آن migrate داخل Docker تایم‌اوت می‌شود.`, + ); + } + + console.log('OK schema-engine:', schemaEngine, queryEngine || '(query via generate)'); +} async function main() { const entry = path.join(root, config.entryPoints[0]); @@ -34,7 +76,6 @@ async function main() { } cpSync(path.join(root, 'prisma'), prismaDest, { recursive: true }); - // entrypoint برای لاگ واضح استارت در Dokploy cpSync(path.join(root, 'docker-entrypoint.sh'), path.join(releaseDir, 'docker-entrypoint.sh')); const releasePkg = { @@ -48,20 +89,29 @@ async function main() { }; writeFileSync(path.join(releaseDir, 'package.json'), `${JSON.stringify(releasePkg, null, 2)}\n`); - // نصب و generate کاملاً لوکال — ایمیج Docker دیگر npm/apk نمی‌زند console.log('در حال npm install داخل release (لوکال)...'); execSync('npm install --omit=dev', { cwd: releaseDir, stdio: 'inherit', - env: { ...process.env, PRISMA_SKIP_POSTINSTALL_GENERATE: '1' }, + env: { + ...process.env, + PRISMA_SKIP_POSTINSTALL_GENERATE: '1', + PRISMA_CLI_BINARY_TARGETS: LINUX_TARGET, + }, }); - console.log('در حال prisma generate (باینری لینوکس برای Docker)...'); + console.log('در حال prisma generate (query engine لینوکس)...'); execSync('npx prisma generate --schema=./prisma/schema.prisma', { cwd: releaseDir, stdio: 'inherit', + env: { + ...process.env, + PRISMA_CLI_BINARY_TARGETS: LINUX_TARGET, + }, }); + await downloadLinuxEngines(); + console.log('آماده‌ی کپی‌only:', releaseDir); }