docker-node icon indicating copy to clipboard operation
docker-node copied to clipboard

feat: add alpine-runtime variant

Open SomaticIT opened this issue 2 years ago • 8 comments

This PR aims to add a new variant named alpine-runtime which only bundles the node executable (without npm nor yarn).

Description

This PR adds a new variant: alpine-linux. This new variant is a very minimal variant of the alpine variant. It contains only the node executable (without npm nor yarn).

The objective is to create the littlest image possible.

Motivation and Context

When working on microservice archictures, the size of images is really important because a lot of images are running on small servers. Having minimal images reduce the disk footprint , the download time and the update time.

With multi-stage builds, we are able to install and build all the appropriate dependencies in a first image then only copy the result in a final image. This final image does not need anything but the runtime.

Testing Details

  • [x] ci: avoid testing npm and yarn on runtime variants
  • [x] update.sh: ensure that no other images are impacted
  • [x] update.sh: ensure that runtime variants are well generated
  • [x] genMatrix.js: ensure that the matrix is valid
  • [ ] genMatrix.js: ensure that runtime variants runs last
  • [ ] stackbrew.js: ensure that runtime variants are well tagged
  • [x] build: ensure that runtime variants images build succesfully
  • [x] run: ensure that runtime variants images run successfully
  • [x] run: ensure that docker-entrypoint run successfully

Example

Now you can build images like this: (maybe this example could be added to the documentation)

FROM node:alpine
COPY package.json package-lock.json /app
RUN npm ci --prod 

FROM node:alpine-runtime
COPY --from=0 /app /app
COPY dist /app/dist

EXPOSE 3000
CMD [ "node", "dist" ]

Types of changes

  • [ ] Documentation
  • [ ] Version change (Update, remove or add more Node.js versions)
  • [x] Variant change (Update, remove or add more variants, or versions of variants)
  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)
  • [ ] Others (none of above)

Checklist

  • [x] My code follows the code style of this project.
  • [ ] My change requires a change to the documentation.
  • [ ] I have updated the documentation accordingly.
  • [x] I have read the CONTRIBUTING.md document.
  • [x] All new and existing tests passed.

SomaticIT avatar Oct 30 '21 23:10 SomaticIT

Note that 3.11 goes EOL on Monday, so you should skip it for anything in here

nschonni avatar Oct 30 '21 23:10 nschonni

Thank you for this feedback.

Does that mean that 3.11 will be dropped for all node versions? If yes, what will be the default version for v12 and v14?

Thanks

SomaticIT avatar Oct 31 '21 02:10 SomaticIT

They will all go to 3.14 with https://github.com/nodejs/docker-node/pull/1596

nschonni avatar Oct 31 '21 03:10 nschonni

OK, I aligned my PR with #1596.

I noticed that v16 was not upgraded to 3.14 so I did not upgrade this version. If it's not expected and #1596 is upgraded, I will update my code.

Once #1596 is merged, I will rebase my PR to allow safe merge.

SomaticIT avatar Oct 31 '21 13:10 SomaticIT

I don't think that a separate image is necessary. We should just document how this is possible. The user will already need to pull the regular node image in order to bring in their dependencies via yarn/npm and so pulling a second image is just extra bandwidth when they already have everything they need.

FROM node:version-alpine3.14 as build
# optional space saving for target image
# RUN apk add --no-cache binutils && strip /usr/local/bin/node
COPY source-files /app
RUN cd /app && [yarm | npm ...]

FROM alpine:3.14
RUN apk install --no-cache libstdc++
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "node" ]
COPY --from=build /usr/local/bin/node /usr/local/bin/
COPY --from=build /usr/local/bin/docker-entrypoint.sh /usr/local/bin/
COPY --from=build [node modules and code]

yosifkit avatar Nov 02 '21 18:11 yosifkit

Maybe something for https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md then?

nschonni avatar Nov 02 '21 20:11 nschonni

I'm ok for leaving this in best practices. However, it could be interesting to give users a prebuilt version of the runtime variant (to avoid them to write the same code on all their projects, which can lead to maintenance issues).

SomaticIT avatar Nov 09 '21 18:11 SomaticIT

I'm following up on this PR.

What approach do you prefer? 1/ Give users a prebuilt version of the runtime variant (to avoid code duplication on the developer side) 2/ Write a documentation and close this PR

Thanks

SomaticIT avatar Dec 08 '21 13:12 SomaticIT

Hi,

I have updated the documentation in the following PR: https://github.com/nodejs/docker-node/pull/1771

All credits go to @yosifkit

zsolt-dev avatar Sep 16 '22 12:09 zsolt-dev

Good job, i can close this PR

SomaticIT avatar Sep 16 '22 14:09 SomaticIT