Skip to content

Commit d248db1

Browse files
Matsuuuclaude
andauthored
build: Fix Docker build chain after DHI base drift and the pnpm 11 upgrade (#36984)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d62dc26 commit d248db1

4 files changed

Lines changed: 24 additions & 23 deletions

File tree

.github/workflows/build-base-image.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ jobs:
3232
# when updating.
3333
include:
3434
- node_version: '22'
35-
dhi_ref: dhi.io/node:22.23.2-alpine3.24-dev@sha256:a6ac21cfbc4bb746c1cfc6cf1501ec13c961ae71558ff2ac7e021caaaf91a224
36-
- node_version: '24.18.1'
37-
dhi_ref: dhi.io/node:24.18.1-alpine3.24-dev@sha256:074b5aa92e1ce74cd575214211bbcb8d1550710aec59558da734a67d84d31679
38-
- node_version: '26.5.1'
39-
dhi_ref: dhi.io/node:26.5.1-alpine3.24-dev@sha256:c4062f85acd1ca91ffb7d15048dcc5f15a922d630e65eb3c3c0dcdcef6ea36d8
35+
dhi_ref: dhi.io/node:22.23.2-alpine3.24-dev@sha256:155a95d59244a71e9479e191ff718f03a7197d6829612e0707608be92988cb87
36+
- node_version: '24.19.0'
37+
dhi_ref: dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd
38+
- node_version: '26.7.0'
39+
dhi_ref: dhi.io/node:26.7.0-alpine3.24-dev@sha256:4b494d89fb26c950ce97865acf45b480dc7a6868fdc2b81c2d66599702eeac3f
4040
steps:
4141
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4242

docker/images/n8n-base/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CI passes one DHI reference per published Node version (see the matrix in
22
# build-base-image.yml). The default keeps plain `docker build` working.
3-
ARG DHI_REF=dhi.io/node:24.18.1-alpine3.24-dev@sha256:074b5aa92e1ce74cd575214211bbcb8d1550710aec59558da734a67d84d31679
3+
ARG DHI_REF=dhi.io/node:24.19.0-alpine3.24-dev@sha256:dc2989ad23938772abaf549ed7bde5d61d70377005229bb55bef94bff40f8bbd
44
FROM ${DHI_REF}
55

66
# Install all dependencies in a single layer to minimize image size

pnpm-workspace.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ hoistPattern:
1212
- '*'
1313
- '!typescript'
1414
allowUnusedPatches: true
15+
# The docker build trims frontend manifests and deploys with --prod before later
16+
# scripts run; pnpm 11's pre-run install would reinstall production-only and prune
17+
# the devDependencies those scripts import.
18+
verifyDepsBeforeRun: false
1519

1620
pmOnFail: warn
1721
fund: false

scripts/build-n8n.mjs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import { $, echo, fs, chalk } from 'zx';
1212
import path from 'path';
13+
import os from 'os';
1314

1415
// Check if running in a CI environment
1516
const isCI = process.env.CI === 'true';
@@ -123,14 +124,13 @@ const packageJsonFiles = await $`cd ${config.rootDir} && find . -name "package.j
123124
-not -path "./compiled/*" \
124125
-type f`.lines();
125126

126-
// Backup all package.json files
127-
// This is only needed locally, not in CI
128-
if (process.env.CI !== 'true') {
129-
for (const file of packageJsonFiles) {
130-
if (file) {
131-
const fullPath = path.join(config.rootDir, file);
132-
await fs.copy(fullPath, `${fullPath}.bak`);
133-
}
127+
// Backup all package.json files. The FE trim below mutates them, and pnpm verifies
128+
// the lockfile before running any later script, which fails until they are restored.
129+
// Backups live outside the workspace: siblings would be packed into the deployment.
130+
const packageJsonBackupDir = await fs.mkdtemp(path.join(os.tmpdir(), 'n8n-build-pkgjson-'));
131+
for (const file of packageJsonFiles) {
132+
if (file) {
133+
await fs.copy(path.join(config.rootDir, file), path.join(packageJsonBackupDir, file));
134134
}
135135
}
136136
// Run FE trim script
@@ -303,18 +303,15 @@ if (generateLicenses) {
303303
}
304304

305305
// Restore package.json files
306-
// This is only needed locally, not in CI
307-
if (process.env.CI !== 'true') {
308-
for (const file of packageJsonFiles) {
309-
if (file) {
310-
const fullPath = path.join(config.rootDir, file);
311-
const backupPath = `${fullPath}.bak`;
312-
if (await fs.pathExists(backupPath)) {
313-
await fs.move(backupPath, fullPath, { overwrite: true });
314-
}
306+
for (const file of packageJsonFiles) {
307+
if (file) {
308+
const backupPath = path.join(packageJsonBackupDir, file);
309+
if (await fs.pathExists(backupPath)) {
310+
await fs.move(backupPath, path.join(config.rootDir, file), { overwrite: true });
315311
}
316312
}
317313
}
314+
await fs.remove(packageJsonBackupDir);
318315

319316
// Calculate output size
320317
const compiledAppOutputSize = (await $`du -sh ${config.compiledAppDir} | cut -f1`).stdout.trim();

0 commit comments

Comments
 (0)