GithubHelp home page GithubHelp logo

astefanutti / scratch-node Goto Github PK

View Code? Open in Web Editor NEW
841.0 17.0 43.0 98 KB

Distroless Node.js Docker Images

Home Page: https://hub.docker.com/r/astefanutti/scratch-node

License: MIT License

Dockerfile 43.32% Shell 33.79% Makefile 22.89%
nodejs docker docker-image dockerfile distroless musl

scratch-node's Introduction

Distroless Node.js Docker Images

Multi-architecture distroless Node.js Docker images.

Content

  • The Node.js binary, statically linked using musl, with opt-in support for i18n data
  • The musl dynamic linker, to support native modules
  • A /etc/passwd entry for a node user

Images

Multi-architecture images for amd64, arm32v6, arm32v7 and arm64v8:

  • latest, 18, 18.10, 18.10.0 – 18.7 MB / 47.5 MB
  • 17, 17.7, 17.7.2 – 17.9 MB / 46.4 MB
  • 16, 16.14, 16.14.2 – 17.1 MB / 43.0 MB
  • 15, 15.14, 15.14.0 – 16.7 MB / 42.7 MB
  • 14, 14.17, 14.17.0 – 15.9 MB / 41.7 MB
  • 13, 13.14, 13.14.0 – 14.8 MB / 39.0 MB
  • 12, 12.22, 12.22.1 – 15.2 MB / 39.8 MB
  • 10, 10.22, 10.22.0 – 13.3 MB / 34.1 MB
  • 8, 8.17, 8.17.0 – 11.2 MB / 30.1 MB

The image sizes are compressed / unpacked. They are published to the following repositories:

Usage

FROM node as builder

WORKDIR /app

COPY package.json package-lock.json index.js ./

RUN npm install --prod

FROM astefanutti/scratch-node

COPY --from=builder /app /

ENTRYPOINT ["node", "index.js"]

Native modules

Native modules need to be statically compiled with musl to be loadable. This can easily be achieved by updating the above example with:

FROM node:alpine as builder

RUN apk update && apk add make g++ python

WORKDIR /app

COPY package.json package-lock.json index.js ./

RUN LDFLAGS='-static-libgcc -static-libstdc++' npm install --build-from-source=<native_module>

FROM astefanutti/scratch-node

COPY --from=builder /app /

ENTRYPOINT ["node", "index.js"]

Internationalization

The Node binaries are linked against the ICU library statically, and include a subset of ICU data (typically only the English locale) to keep the image sizes small. Additional locales data can be provided if needed, so that methods work for all ICU locales. It can be made available to ICU by retrieving the locales data from the ICU sources, e.g.:

FROM alpine as builder

RUN apk update && apk add curl

# Note the exact version of icu4c that's compatible depends on the Node version!
RUN curl -Lsq -o icu4c-71_1-src.zip https://github.com/unicode-org/icu/releases/download/release-71-1/icu4c-71_1-src.zip \
    && unzip -q icu4c-71_1-src.zip

FROM astefanutti/scratch-node:18.10.0

COPY --from=builder /icu/source/data/in/icudt71l.dat /icu/

ENV NODE_ICU_DATA=/icu

More information can be found in the Providing ICU data at runtime from the Node.js documentation.

Build

The image can be built by executing the following commands:

$ git clone https://github.com/astefanutti/scratch-node
$ cd scratch-node
$ docker build --build-arg version=<nodejs_version> --build-arg arch=<target_architecture> .

scratch-node's People

Contributors

astefanutti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scratch-node's Issues

Facing issue with - `configure: error: no such option: --enable-lto`

I'm building an image using this command docker build --build-arg version=8.0.0 --build-arg arch=x86_64 .. However I'm getting this error

Usage: configure [options]

configure: error: no such option: --enable-lto

on step 13 which is this piece here.

RUN tar -xf "node-v$NODE_VERSION.tar.xz" \
    && cd "node-v$NODE_VERSION" \
    && /patch.sh ${BUILD_ARCH} ${NODE_VERSION} \
    && export TARGET=$(/build.sh target ${BUILD_ARCH:-""}) \
    && export CC=$TARGET-gcc \
    && export CXX=$TARGET-g++ \
    && export AR=$TARGET-ar \
    && export LINK=$TARGET-g++ \
    && export CXXFLAGS="-O3 -ffunction-sections -fdata-sections" \
    && export LDFLAGS="-Wl,--gc-sections,--strip-all $(/build.sh ld_flags ${BUILD_ARCH:-""})" \
    && ln -snf libc.so /usr/local/$TARGET/lib/ld-musl-*.so.1 \
    && ln -snf /usr/local/$TARGET/lib/ld-musl-*.so.1 /lib \
    && ./configure \
        --partly-static \
        --with-intl=small-icu \
        --without-dtrace \
        --without-inspector \
        --without-etw \
        $(/build.sh node_config ${BUILD_ARCH:-""}) \
    && make -j$(getconf _NPROCESSORS_ONLN) V=

I'm not sure what is causing the error or how to resolve it. Please let me know if you need more information.

Node binary not in PATH

Hi!

I was playing with this image, and i can't run my project with it. What's the limitations of using this node?

Below is my Dockerfile

FROM astefanutti/scratch-node
ENV NODE_ENV production
WORKDIR /api
COPY ./build ./dist
# Only necessary to debug container in developer machine
# Kubernetes uses ConfigMaps to handle environment variables
COPY .env .env

EXPOSE 3000
# I tried this with ENTRYPOINT [ "./node", "./dist/build.js"] but didn't work either
CMD node dist/build.js

This's the error i got building this Dockerfile:

image

docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"./node\": stat ./node: no such file or directory": unknown.

My original Dockerfile is this:

# The only difference between the two files is the FROM line
FROM node:8.9-alpine 
ENV NODE_ENV production
WORKDIR /api
COPY ./build ./dist
# Only necessary to debug container in developer machine
# Kubernetes uses ConfigMaps to handle environment variables
COPY .env .env

EXPOSE 3000
CMD node dist/build.js

That outputs this:
image

My package.json dependencies are below:

"dependencies": {
    "@commitlint/cli": "^7.5.2",
    "@commitlint/config-conventional": "^7.5.0",
    "@types/mongoose": "^5.0.18",
    "@types/redis": "^2.8.6",
    "axios": "^0.18.0",
    "body-parser": "^1.18.2",
    "compression": "^1.7.3",
    "concat-stream": "^1.6.2",
    "cors": "^2.8.4",
    "dotenv": "^6.0.0",
    "express": "^4.16.3",
    "express-validator": "^5.2.0",
    "http-status-codes": "^1.3.0",
    "husky": "^1.3.1",
    "mongodb": "^3.0.4",
    "mongoose": "^5.4.14",
    "morgan": "^1.9.0",
    "prettier": "^1.16.4",
    "pretty-quick": "^1.10.0",
    "redis": "^2.8.0",
    "ts-node": "^7.0.0",
    "tslint": "^5.15.0",
    "typescript": "^2.9.2",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0"
  },
  "devDependencies": {
    "@types/body-parser": "^1.17.0",
    "@types/express": "^4.16.0",
    "@types/node": "^10.3.6",
    "source-map-support": "^0.5.9"
  }

And these two commands, take care of bundle the service to build/build.js folder:

"build": "npm run clean && tsc",
"build:webpack": "webpack --config webpack.config.js",

How to handle tzdata, tls root certificates, etc?

I haven't tried this yet, but in the past when using from scratch for other projects there are usually certain system files that have to be dealt with in some way, specifically:

  • tzdata or /usr/share/zoneinfo
  • /etc/ssl/certs/

Does this bake those into the node build, or are they require to be copied over as part of the build process?

Dynamic (native) module loading not supported

After trying to use these modules, it seems that they cannot load dynamic modules like bcrypt, for example.

I found this issue smebberson/docker-alpine#52 which seems to highlight the --fully-static compilation flag as being responsible for this and noticed that it is indeed passed here.

Would it be possible to get these images to work in a way that supports dynamic module loading, but is still rather small?

SBOM scan

Hi,

I'm fairly new to the concept of distroless images and I cannot seem to understand the following: How would one go about to do an SBOM scan with e.g. anchore/syft?

Write file Permission Denied

Problem:
I would like to populate .env on the entry point command but due user being node, I am getting permission denied error while writing content to .env.

I am new to docker, so cannot figure out solution.
I tried changing user to root but got error
docker: Error response from daemon: unable to find user root: no matching entries in passwd file.
I see you have changed your user to node in your Dockerfile, and I am using your image so I cant use root user as a result getting above error.

Can you remove changing user to node in your Dockerfile, if that solves above problem.

Any user of your image can switch to node user if they wish to while using.

Updating the GPG keys

These keys:

94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
FD3A5288F042B6850C66B31F09FE44734EB7990E \
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
56730D5401028683275BD23C23EFEFE93C4CFFFE \
77984A986EBC2AA786BC0F66B01FBB92821C587A \
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \

appear to be outdated but when I try to update them to use the newest GPG keys:

4ED778F539E3634C779C87C6D7062848A1AB005C \
B9E2F5981AA6E0CD28160D9FF13993A75599653C \
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
77984A986EBC2AA786BC0F66B01FBB92821C587A \
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
FD3A5288F042B6850C66B31F09FE44734EB7990E \
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
A48C2BEE680E841632CD4E44F07496B3EB3C1762 \

while the build succeeds, the runtime instance of my project never seems to start.

Any idea what could be causing this?

build node 10 not work

i'm build with node 10 with error result

node version 10.16.3 and 10.9.0
armv7

  CXX(host) /root/node-v10.9.0/out/Release/obj.host/genrb/deps/icu-small/source/tools/genrb/prscmnts.o
  CXX(host) /root/node-v10.9.0/out/Release/obj.host/genrb/deps/icu-small/source/tools/genrb/wrtjava.o
  CXX(host) /root/node-v10.9.0/out/Release/obj.host/genrb/deps/icu-small/source/tools/genrb/reslist.o
  CC(host) /root/node-v10.9.0/out/Release/obj.host/genrb/deps/icu-small/source/tools/genrb/errmsg.o
  CXX(host) /root/node-v10.9.0/out/Release/obj.host/genrb/deps/icu-small/source/tools/genrb/genrb.o
  CXX(host) /root/node-v10.9.0/out/Release/obj.host/iculslocs/tools/icu/iculslocs.o
  CXX(host) /root/node-v10.9.0/out/Release/obj.host/iculslocs/tools/icu/no-op.o
  LINK(target) /root/node-v10.9.0/out/Release/openssl-cli
  TOUCH e63ea4f50354fffbe97d4615b808dd79a1e2f9fe.intermediate
  ACTION _root_node_v10_9_0_deps_v8_gypfiles_v8_gyp_v8_torque_host_run_torque e63ea4f50354fffbe97d4615b808dd79a1e2f9fe.intermediate
  LINK(host) /root/node-v10.9.0/out/Release/genccode
/root/node-v10.9.0/out/Release/torque: line 1: syntax error: unexpected word (expecting ")")
make[1]: *** [deps/v8/gypfiles/v8_torque.host.mk:17: e63ea4f50354fffbe97d4615b808dd79a1e2f9fe.intermediate] Error 2
make[1]: *** Waiting for unfinished jobs....
In file included from ../deps/icu-small/source/tools/genrb/reslist.h:31,
                 from ../deps/icu-small/source/tools/genrb/reslist.cpp:33:
../deps/icu-small/source/tools/genrb/reslist.cpp: In member function ‘void SRBRoot::write(const char*, const char*, char*, int, UErrorCode&)’:
../deps/icu-small/source/common/cstring.h:43:70: warning: ‘char* strncpy(char*, const char*, size_t)’ specified bound depends on the length of the source argument [-Wstringop-overflow=]
 #define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
../deps/icu-small/source/tools/genrb/reslist.cpp:945:12: note: in expansion of macro ‘uprv_strncpy’
            uprv_strncpy(writtenFilename, outputDir, len);
            ^~~~~~~~~~~~
../deps/icu-small/source/common/cstring.h:37:57: note: length computed here
 #define uprv_strlen(str) U_STANDARD_CPP_NAMESPACE strlen(str)
../deps/icu-small/source/tools/genrb/reslist.cpp:941:27: note: in expansion of macro ‘uprv_strlen’
            len = (int32_t)uprv_strlen(outputDir);
                           ^~~~~~~~~~~
../deps/icu-small/source/common/cstring.h:43:70: warning: ‘char* strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
 #define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
../deps/icu-small/source/tools/genrb/reslist.cpp:964:16: note: in expansion of macro ‘uprv_strncpy’
                uprv_strncpy(writtenFilename + off, fLocale, len);
                ^~~~~~~~~~~~
../deps/icu-small/source/common/cstring.h:37:57: note: length computed here
 #define uprv_strlen(str) U_STANDARD_CPP_NAMESPACE strlen(str)
../deps/icu-small/source/tools/genrb/reslist.cpp:960:31: note: in expansion of macro ‘uprv_strlen’
                len = (int32_t)uprv_strlen(fLocale);
                               ^~~~~~~~~~~
../deps/icu-small/source/common/cstring.h:43:70: warning: ‘char* strncpy(char*, const char*, size_t)’ output may be truncated copying between 1 and 5 bytes from a string of length 4 [-Wstringop-truncation]
 #define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
../deps/icu-small/source/tools/genrb/reslist.cpp:971:20: note: in expansion of macro ‘uprv_strncpy’
                    uprv_strncpy(writtenFilename +  off, ".res", len);
                    ^~~~~~~~~~~~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.