-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image without npm nor yarn #404
Comments
I agree but we use the official distribution which include npm. The core node doesn't have a version of node without npm, as far as I am aware. |
Yeah, that would be great. I think if we do that we'd have to somehow build node without npm. Or convince the build group that we need that as another option. It might make sense to do more of a clean break and create a new node-minimal image that better fits this use case. |
I just saw that https://github.com/mhart/alpine-node provides that kind of image (with the Node binary only). Maybe you can get some ideas from there. |
Yeah they build node with |
Well, theoretically we could just |
@pesho I do see the value. You'd be reducing the image size by 40% (22MB from 54MB belong to npm and yarn in the Node 6.10 image). In some environments that's important. |
@rubennorte I spoke too soon before. Indeed, there is value in having a minimal image without package managers for production. |
I agree, a minimal image without npm nor yarn would be nice for production use cases. This only makes sens for the Nice issue number #404 😜 |
I had something in mind when multi-stage builds got introduced to make the smallest possible Node image: # Dockerfile-alpine-minimal.template
FROM node:0.0.0-alpine AS builder
FROM alpine:0.0
COPY --from=builder /usr/local/bin/node /usr/local/bin/
COPY --from=builder /usr/lib/ /usr/lib/
CMD [ "node" ] I'm not sure if it's OK to use multi-stage builds in docker-node yet, but I like the idea of using the previously built |
They used to have a statically-linked |
Is this worth revisiting as a variant? Doing |
A few suggestions: I like the idea in general. |
The complexity this would bring kind of scares me. |
@valeriangalliat I like your approach but in the current setup, that would mean building the alpine images twice because different images are not aware of each other. |
I think we should only do this for Debian, something like: FROM debian:jessie-slim
RUN groupadd --gid 1000 node \
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node
# gpg keys listed at https://github.com/nodejs/node#release-team
RUN set -ex \
&& for key in \
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
FD3A5288F042B6850C66B31F09FE44734EB7990E \
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
56730D5401028683275BD23C23EFEFE93C4CFFFE \
77984A986EBC2AA786BC0F66B01FBB92821C587A \
; do \
gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
gpg --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
gpg --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
done
ENV NODE_VERSION 10.2.0
RUN buildDeps='ca-certificates curl xz-utils' \
&& ARCH= && dpkgArch="$(dpkg --print-architecture)" \
&& case "${dpkgArch##*-}" in \
amd64) ARCH='x64';; \
ppc64el) ARCH='ppc64le';; \
s390x) ARCH='s390x';; \
arm64) ARCH='arm64';; \
armhf) ARCH='armv7l';; \
i386) ARCH='x86';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac \
&& set -x \
&& apt-get update && apt-get install -y $buildDeps --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION-linux-$ARCH.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
&& rm -rf /usr/local/lib/node_modules/ \
&& rm -rf /usr/local/bin/npm \
&& rm -rf /usr/local/bin/npx \
&& rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& apt-get purge -y --auto-remove $buildDeps \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
CMD [ "node" ] The above image is about 125MB (edit: updated to delete |
Also, for a variant name, I kind of like |
How much space is saved on Debian? |
You can delete the entire node_modules directory, not just the npm
directory. The only other modules that ship with Node.js are npm's
dependencies.
Instead of installing Node.js and npm and then deleting npm, could you just
avoid installing npm in the first place? I think the Node.js site has a
statically compiled version of Node.js with no npm (just the Node.js
executable), and I believe Debian packages Node.js and npm in two separate
packages.
Sent from my phone.
…On Fri, May 25, 2018, 8:02 AM Christopher Horrell ***@***.***> wrote:
Also, for a variant name, I kind of like node:core, node:10-core
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#404 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFnHTq78qfmFrNjk4vx1TZyRxfj507kks5t2Bz4gaJpZM4Ncdol>
.
|
We're looking at a ~60MB difference using the [chorrell:~/GitHub/docker-node-main] master(+6/-6)* ± docker images | grep 10.2.0-slim
node 10.2.0-slim c164ad185a38 20 hours ago 184MB vs [chorrell:~/GitHub/docker-node-main] master(+6/-6)* ± docker images | grep 10.2.0-core
node 10.2.0-core 68519b454a55 3 minutes ago 125MB |
Note that I don't think the statically compiled versions are available, or at least I cannot find them at |
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Closes #404
love this idea, @chorrell how soon this can be released? |
@SimenB definitely think it's worth it – the fact that y'all are getting the work done is super valuable if Node.js core were to do the same 💚 |
@bnb Feel free to put this on the TSC agenda by adding the label to it and/or mentioning it in the current TSC meeting issue (nodejs/TSC#565) – ideally with a short summary of the question you’d like to see answered, which decision you’d like to see made, or what you’d like to raise awareness about. (It’s not super-clear from this thread for me, so that’s why I’m mentioning it 🙂). |
Would really like to see this as well. It's actually far-preferred to not involve global dependencies at all for your production apps. |
A potentially related issue: nodejs/Release#341. The discussion is related to having different versions, some without extras. |
Discussed in last TSC meeting, but this should not block this issue and ongoing discussion about whether we should do something on the release side will continue in: nodejs/Release#341. Removing from TSC agenda. |
This is an image without npm or yarn installed, suitable for multi-stage builds. Also: - Skip setting yarn version in core variant - Skip npm and yarn tests for "core" variant Closes #404
This is an image without npm or yarn installed, suitable for multi-stage builds. Also: - Skip setting yarn version in core variant - Skip npm and yarn tests for "core" variant Closes #404
FWIW, I would like to add a vote in favor of this work, including providing an alpine-based image without npm. My needs are:
I would really like to see an official image, since it's not obvious to someone like myself which things are necessary vs what can safely be deleted when pairing down a larger image, or which specific combination of flags need to be set to build it from source without npm, while still allowing native modules to work. If one of the main obstacles is still the naming convention for the release, it would be nice if there could be a simple vote with github reactions by the maintainers so we could be unblocked. The suggestion of Thanks. |
I've made some tests. Using multi-stage docker build and node static build I was able to reduce node alpine image size by two times. And upx-packed is four times less size.
You can find dockerfile in my repo https://github.com/SkeLLLa/alpine-node, feel free to use it if needed. |
FWIW, I'm maintaining scratch Node images at https://github.com/astefanutti/scratch-node. The compressed size is around 14MB for Node 12. |
@astefanutti that's very nice. I've created static built based on your idea with scratch. And with upx it became even smaller: ~12MB. You may apply upx packer in your repo as well. If anyone here is interested in porting that into official repo - feel free to take, test, enhance the code (repo link is in docker repo description). |
Agree it would be useful! |
fwiw, I experimented a bit with this over here using GitHub Actions to build a statically compiled |
Building the |
Any news on this? Issue was created over 3 years ago :-S |
Almost one year in since last bump and still no info about minimal node base images suited for production workloads? |
We currently struggle because Microsoft Defender for Cloud flags all our Production builds because of an outdated dependency in npm (-> ip@2.0.0). |
I created the debian core image in #2058 |
Now that Docker supports multi-stage builds it'd be nice to have an official base image with just the Node.js binary. A build image could extend from the current images and a production image could extend from the standalone version (copying the built application with all installed dependencies from the build container).
The text was updated successfully, but these errors were encountered: