chore: upgrade to node 24 lts and clean up docker image (#3332)

Upgrade to Node 24 LTS, using the alpine 3.23 tag to handle issues with
streaming zip files on 24.16 which hangs npm ci.

Pin npm to 11.19.1 for min-release-age-exclude support.

Slim the runner image by dropping dev deps, the react-email CLI, and
esbuild,
none of which run in production.

Install turbo from the lockfile version instead of a hardcoded one.
This commit is contained in:
Lucas Smith
2026-09-04 12:29:02 +10:00
committed by GitHub
parent dabb7b7a0d
commit 30a6b19b47
10 changed files with 68 additions and 85 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ name: 'Setup node'
inputs:
node_version:
required: false
default: v22.x
default: v24.x
runs:
using: 'composite'
+1 -1
View File
@@ -107,7 +107,7 @@ Contact us if you are interested in our Enterprise plan for large organizations
To run Documenso locally, you will need
- Node.js (v22 or above)
- Node.js (v24 or above)
- Postgres SQL Database
- Docker (optional)
@@ -14,8 +14,8 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
## Prerequisites
- Node.js 22 or later
- npm 11 or later
- Node.js 24 or later
- npm 11.17 or later
- PostgreSQL 14 or later
- A Linux server (for systemd service setup)
@@ -141,8 +141,8 @@ If building from source (not using Docker images):
| Requirement | Version |
| ----------- | ------- |
| Node.js | 22+ |
| npm | 11+ |
| Node.js | 24+ |
| npm | 11.17+ |
---
@@ -169,7 +169,7 @@ Documenso runs on:
| MySQL/MariaDB | PostgreSQL-specific features required |
| SQLite | Not suitable for production workloads |
| MongoDB | Relational database required |
| Node.js < 22 | Modern JavaScript features required |
| Node.js < 24 | Modern JavaScript features required |
---
-25
View File
@@ -1,25 +0,0 @@
FROM oven/bun:1 AS dependencies-env
COPY . /app
FROM dependencies-env AS development-dependencies-env
COPY ./package.json bun.lockb /app/
WORKDIR /app
RUN bun i --frozen-lockfile
FROM dependencies-env AS production-dependencies-env
COPY ./package.json bun.lockb /app/
WORKDIR /app
RUN bun i --production
FROM dependencies-env AS build-env
COPY ./package.json bun.lockb /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN bun run build
FROM dependencies-env
COPY ./package.json bun.lockb /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["bun", "run", "start"]
-26
View File
@@ -1,26 +0,0 @@
FROM node:20-alpine AS dependencies-env
RUN npm i -g pnpm
COPY . /app
FROM dependencies-env AS development-dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
WORKDIR /app
RUN pnpm i --frozen-lockfile
FROM dependencies-env AS production-dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
WORKDIR /app
RUN pnpm i --prod --frozen-lockfile
FROM dependencies-env AS build-env
COPY ./package.json pnpm-lock.yaml /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN pnpm build
FROM dependencies-env
COPY ./package.json pnpm-lock.yaml /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["pnpm", "start"]
+25 -12
View File
@@ -1,7 +1,7 @@
###########################
# BASE CONTAINER #
###########################
FROM node:22-alpine3.22 AS base
FROM node:24-alpine3.23 AS base
RUN apk add --no-cache openssl
RUN apk add --no-cache font-freefont
@@ -19,7 +19,10 @@ WORKDIR /app
COPY . .
RUN npm install -g "turbo@^2.10.0"
# Install the exact turbo version resolved in the lockfile, without installing
# the rest of the dependency tree (prune must run before any npm ci).
RUN TURBO_VERSION="$(jq -r '.packages["node_modules/turbo"].version' package-lock.json)" \
&& npm install -g "turbo@${TURBO_VERSION}"
# Outputs to the /out folder
# source: https://turbo.build/repo/docs/reference/command-line-reference/prune#--docker
@@ -39,9 +42,9 @@ RUN apk add --no-cache make cmake g++ openssl bash
WORKDIR /app
# Disable husky from installing hooks
ENV HUSKY 0
ENV DOCKER_OUTPUT 1
ENV NEXT_TELEMETRY_DISABLED 1
ENV HUSKY=0
ENV DOCKER_OUTPUT=1
ENV NEXT_TELEMETRY_DISABLED=1
# Encryption keys
ARG NEXT_PRIVATE_ENCRYPTION_KEY="CAFEBABE"
@@ -85,17 +88,17 @@ COPY --from=builder /app/out/full/ .
# Finally copy the turbo.json file so that we can run turbo commands
COPY turbo.json turbo.json
RUN npm install -g "turbo@^2.10.0"
ENV NODE_OPTIONS="--max-old-space-size=8192"
RUN turbo run build --filter=@documenso/remix...
RUN npx turbo run build --filter=@documenso/remix...
###########################
# RUNNER CONTAINER #
###########################
FROM base AS runner
ENV HUSKY 0
ENV DOCKER_OUTPUT 1
ENV HUSKY=0
ENV DOCKER_OUTPUT=1
# Telemetry credentials (baked into image at build time, can be disabled at runtime)
ARG NEXT_PRIVATE_TELEMETRY_KEY=""
@@ -118,7 +121,16 @@ COPY --from=builder --chown=nodejs:nodejs /app/out/full/packages/tailwind-config
# Copy the patches across
COPY --from=builder --chown=nodejs:nodejs /app/patches ./patches
RUN npm ci --only=production
RUN npm ci --omit=dev --no-audit --no-fund && npm cache clean --force
# Strip build-time residue that ships as production dependencies but is never
# executed at runtime.
RUN rm -rf \
node_modules/react-email/dist/cli \
node_modules/esbuild \
node_modules/@esbuild \
node_modules/.bin/esbuild \
node_modules/.bin/email
# Automatically leverage output traces to reduce image size
# https://nodejs.org/docs/advanced-features/output-file-tracing
@@ -129,8 +141,9 @@ COPY --from=installer --chown=nodejs:nodejs /app/apps/remix/public ./apps/remix/
COPY --from=installer --chown=nodejs:nodejs /app/packages/prisma/schema.prisma ./packages/prisma/schema.prisma
COPY --from=installer --chown=nodejs:nodejs /app/packages/prisma/migrations ./packages/prisma/migrations
# Generate the prisma client again
RUN npx prisma generate --schema ./packages/prisma/schema.prisma
# Generate the prisma client again, this time only targeting the client generator
RUN npx prisma generate --schema ./packages/prisma/schema.prisma --generator client \
&& npm cache clean --force
# Get the start script from docker/
+28 -7
View File
@@ -102,8 +102,8 @@
"zod-prisma-types": "3.3.5"
},
"engines": {
"node": ">=22.0.0",
"npm": ">=11.11.0"
"node": ">=24.0.0",
"npm": ">=11.17.0"
}
},
"apps/docs": {
@@ -3153,6 +3153,7 @@
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz",
"integrity": "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@chevrotain/gast": "10.5.0",
@@ -3164,6 +3165,7 @@
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.5.0.tgz",
"integrity": "sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@chevrotain/types": "10.5.0",
@@ -3174,12 +3176,14 @@
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.5.0.tgz",
"integrity": "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@chevrotain/utils": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.5.0.tgz",
"integrity": "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@commitlint/cli": {
@@ -5723,6 +5727,7 @@
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/@mrleebo/prisma-ast/-/prisma-ast-0.13.1.tgz",
"integrity": "sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==",
"dev": true,
"license": "MIT",
"dependencies": {
"chevrotain": "^10.5.0",
@@ -10295,12 +10300,14 @@
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/dmmf/-/dmmf-6.19.3.tgz",
"integrity": "sha512-+D6v7RIF21bJrZAXiiIdW0qR73TleYVCqTDozokdEHdGeqN997O7jJW5z+43s5CVwWTZJIwFGpoeXxDDyXDVxA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/driver-adapter-utils": {
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-6.19.3.tgz",
"integrity": "sha512-UUxn6VLfKKVqm5n9vexOQgFJ9TCBIxupb7F5FzLQ6iM2VV0WZxhgzbQVqBDsGY+VmQLmqaSoKRusEfy3O5KZpA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.19.3"
@@ -10349,12 +10356,14 @@
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/generator/-/generator-6.19.3.tgz",
"integrity": "sha512-rzHJaIZEnEDUWNjjFAimsyMCS9osPxwbwiAbymwFprSHJSAglMxMDVU+xbQUCLeDsjUF09W5ag/aBPL2t3YqgA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/generator-helper": {
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-6.19.3.tgz",
"integrity": "sha512-13S8ngSWVKcyuRFqaK/JGMyovjQC5sOKJ9A+ufqePQWeIUbvKO2QY2CmhcV4JAa2vuN22//4Sip5mORVKwS0sw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.19.3",
@@ -10375,6 +10384,7 @@
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/internals/-/internals-6.19.3.tgz",
"integrity": "sha512-1V5ba+BNtGFFlgoA8ecyAbjmoMWzIrEuebmLbJpeS7qbhnY6vbc1OZ6qc55lI/VAkfdALSL5vePG5KF9P8feLw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/config": "6.19.3",
@@ -10405,18 +10415,21 @@
"version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
"resolved": "https://registry.npmjs.org/@prisma/prisma-schema-wasm/-/prisma-schema-wasm-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz",
"integrity": "sha512-/5JrsJQAOIWSl+9WMM/0ugd737kT9zdMNr7EFaP7ogeMxAhxQ78uaOV6JYGEocD8LC0gZx7MXmVE/CTfYdJ2iA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/schema-engine-wasm": {
"version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
"resolved": "https://registry.npmjs.org/@prisma/schema-engine-wasm/-/schema-engine-wasm-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz",
"integrity": "sha512-mXtzeePkSdqpr/HAIclqzQEf+tBzLawy7NQ9AaRCfg8N/cruavpsocgbSwOOfV7JTk9JubyzKuR3tp2bNNuWbQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/schema-files-loader": {
"version": "6.19.3",
"resolved": "https://registry.npmjs.org/@prisma/schema-files-loader/-/schema-files-loader-6.19.3.tgz",
"integrity": "sha512-rnoL2PgopghakRZLCZwj+d7LPvjbY9mFholFWuibEKzwO7aqS16s60Hz4wxAnKwqOcS/M6pV7QLrsHBYnNR0KA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/prisma-schema-wasm": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
@@ -16274,6 +16287,7 @@
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.5.0.tgz",
"integrity": "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@chevrotain/cst-dts-gen": "10.5.0",
@@ -16625,6 +16639,7 @@
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
"integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
"dev": true,
"license": "MIT"
},
"node_modules/collapse-white-space": {
@@ -19871,6 +19886,7 @@
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
@@ -22537,6 +22553,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -26383,6 +26400,7 @@
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-3.6.2.tgz",
"integrity": "sha512-WX/oENQ0S74r/Wgd2uuHT5i3KbnwLFCP2Fq5ISzrXkus/htOC4uCaQPYuGP2m/wSeKZZCw1RxptTlD+ib7Ht/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@prisma/generator-helper": "^6.16.1",
@@ -26408,6 +26426,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/prisma-kysely/-/prisma-kysely-2.3.0.tgz",
"integrity": "sha512-/+VF2t2DlY+t/27hhyH5ULWxBAAsMBPgOo8Ltq7uXpBz49lUf4XuO1ff9HV0l7J3aDojG+YyczEvY0og9uRqsw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mrleebo/prisma-ast": "^0.13.1",
@@ -27608,6 +27627,7 @@
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz",
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==",
"dev": true,
"license": "MIT"
},
"node_modules/rehype-raw": {
@@ -31654,6 +31674,7 @@
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/zod-prisma-types/-/zod-prisma-types-3.3.5.tgz",
"integrity": "sha512-PDuRRCdX1d6ch6UclNvrqM1SLb2qvuaQPvZT/OHRrcxOQqQUnCz009aBc1uxuwMho1+d42TTDCQr+HPXhTSJtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@prisma/dmmf": "^6.16.3",
@@ -32410,17 +32431,17 @@
"nanoid": "^5.1.6",
"prisma": "^6.19.0",
"prisma-extension-kysely": "^3.0.0",
"prisma-json-types-generator": "^3.6.2",
"prisma-kysely": "^2.3.0",
"ts-pattern": "^5.9.0",
"zod": "^3.25.76",
"zod-prisma-types": "3.3.5"
"zod": "^3.25.76"
},
"devDependencies": {
"dotenv": "^17.2.3",
"dotenv-cli": "^11.0.0",
"prisma-json-types-generator": "^3.6.2",
"prisma-kysely": "^2.3.0",
"tsx": "^4.23.1",
"typescript": "5.6.2"
"typescript": "5.6.2",
"zod-prisma-types": "3.3.5"
}
},
"packages/prisma/node_modules/@esbuild/aix-ppc64": {
+3 -3
View File
@@ -41,10 +41,10 @@
"translate:extract": "lingui extract --clean",
"translate:compile": "lingui compile"
},
"packageManager": "npm@11.11.0",
"packageManager": "npm@11.19.1",
"engines": {
"npm": ">=11.11.0",
"node": ">=22.0.0"
"npm": ">=11.17.0",
"node": ">=24.0.0"
},
"devDependencies": {
"@biomejs/biome": "2.4.8",
+5 -5
View File
@@ -26,16 +26,16 @@
"nanoid": "^5.1.6",
"prisma": "^6.19.0",
"prisma-extension-kysely": "^3.0.0",
"prisma-kysely": "^2.3.0",
"prisma-json-types-generator": "^3.6.2",
"ts-pattern": "^5.9.0",
"zod": "^3.25.76",
"zod-prisma-types": "3.3.5"
"zod": "^3.25.76"
},
"devDependencies": {
"dotenv": "^17.2.3",
"dotenv-cli": "^11.0.0",
"prisma-kysely": "^2.3.0",
"prisma-json-types-generator": "^3.6.2",
"tsx": "^4.23.1",
"typescript": "5.6.2"
"typescript": "5.6.2",
"zod-prisma-types": "3.3.5"
}
}