@Alijvhr's answer worked well for me until I needed to add another package through apk. Copying over all 4 directories completely ended up clobbering all of the symlinks that the libraries use to resolve library versions. So for example I'd see a lot of these kinds of errors:
0.101 Error loading shared library libcrypto.so.3: No such file or directory (needed by /sbin/apk)
0.102 Error loading shared library libssl.so.3: No such file or directory (needed by /usr/lib/libapk.so.2.14.0)
0.102 Error loading shared library libcrypto.so.3: No such file or directory (needed by /usr/lib/libapk.so.2.14.0)
I ran across this other thread which involved copying just two specific folders but this was for the -slim
variants of the images. https://stackoverflow.com/a/76362323/20506608
Using the copy statements from the other answer, but still using the alpine image also does not solve the problem fully as now we're missing the libstdc++ library. Installing it using apk add
before using node ended up fixing that issue.
So the Dockerfile will end up looking like:
ARG NODE_VERSION=20.18.0
FROM node:${NODE_VERSION}-alpine AS node
FROM alpine:3.21.0 AS base
COPY --from=node /usr/local/bin /usr/local/bin
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
# git, zip, and curl aren't necessary here, just an examples.
RUN apk update && apk add \
git \
zip \
curl \
libstdc++
# Removing the libstdc++ installation will cause this fail.
RUN node -v
...
I'm not 100% sure this will copy all components of node, but for my use it has worked out so far.