Skip to content

Commit 98a01a7

Browse files
committed
docs(BestPractices): move the warning into the node-gyp section, as reviewed
Replaces the added 'Multi-architecture images' heading (and its doctoc entry) with a short note under the multistage example that already demonstrates the pattern - COPY --from=builder node_modules. Six lines instead of twenty, no new section to maintain. Validated with this repo's own checks: prettier --check, doctoc --update-only --dryrun.
1 parent 6a57404 commit 98a01a7

1 file changed

Lines changed: 6 additions & 19 deletions

File tree

‎docs/BestPractices.md‎

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
- [Docker Run](#docker-run)
1616
- [Security](#security)
1717
- [node-gyp alpine](#node-gyp-alpine)
18-
- [Multi-architecture images](#multi-architecture-images)
1918
- [Smaller images without npm/yarn](#smaller-images-without-npmyarn)
2019

2120
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -181,24 +180,12 @@ FROM node:alpine as app
181180
COPY --from=builder node_modules .
182181
```
183182

184-
## Multi-architecture images
185-
186-
A dependency tree installed once cannot serve two architectures. `docker buildx build` with
187-
`--platform linux/amd64,linux/arm64` builds each stage natively per platform, but if one stage runs
188-
`npm ci` on the build host and a later stage copies the result with
189-
`COPY --from=builder node_modules .`, that same tree - carrying the build host's prebuilt native
190-
addons - ends up inside every platform tag. The manifest still advertises both architectures, so nothing
191-
looks wrong until an arm64 host loads an x86-64 binary:
192-
193-
```console
194-
Error: /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node: invalid ELF header
195-
```
196-
197-
Install dependencies inside each platform's stage (or rebuild them there with `npm rebuild`), and
198-
publish only the architectures actually built. To check an image that is already published, without a
199-
Docker engine: fetch its manifest from the registry, decompress the layer tarballs, and read the
200-
`e_machine` field of any `.node` file - two bytes at offset 18, `0x3e` for x86-64 and `0xb7` for
201-
AArch64.
183+
Note that this multistage pattern only produces a tree that works on the architecture the builder ran on.
184+
Native addons are compiled or downloaded for that host, so `COPY --from=builder node_modules .` into a stage
185+
built for a different architecture puts a mismatched binary in the image while the manifest still looks
186+
correct, and the first `require()` of it fails with `invalid ELF header`. Under
187+
`docker buildx build --platform linux/amd64,linux/arm64`, install or `npm rebuild` inside each platform's
188+
stage instead of sharing one tree between them.
202189

203190
## Smaller images without npm/yarn
204191

0 commit comments

Comments
 (0)