Skip to content
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

Use scratch as base image #1254

Merged
merged 5 commits into from
Jul 11, 2022
Merged

Use scratch as base image #1254

merged 5 commits into from
Jul 11, 2022

Conversation

holgerkoser
Copy link
Member

@holgerkoser holgerkoser commented Jul 8, 2022

What this PR does / why we need it:
The goal of this PR was to get rid of all unused dependencies in the dashboard docker image, so as not to get false positive security messages from the image scan. To achieve this goal there were two possible base images. In both cases a C standard library implementation needs to be added as well as the shared libraries libstdc++.so.6 and libgcc_s.so.1. Below you can find the two different approaches.

  1. Image base on scratch
FROM node:18-alpine3.16 as builder

WORKDIR /usr/src/app

RUN mkdir -p ./.yarn/cache && echo "console.log('Hello World')" > ./server.js

WORKDIR /volume

RUN apk add --no-cache tini \
    # tini and node binaries
    && mkdir -p ./sbin ./usr/local/bin \
    && cp /sbin/tini ./sbin/ \
    && cp /usr/local/bin/node ./usr/local/bin/ \
    # root ca certificates
    && mkdir -p ./etc/ssl \
    && cp -r /etc/ssl/certs ./etc/ssl \
    # node user
    && echo 'node:x:1000:1000:node,,,:/home/node:/sbin/nologin' > ./etc/passwd \
    && echo 'node:x:1000:node' > ./etc/group \
    && mkdir -p ./home/node \
    && chown 1000:1000 ./home/node \
    # libc, libgcc and libstdc++ libraries
    && mkdir -p ./lib ./usr/lib \
    && cp -d /lib/ld-musl-x86_64.so.* ./lib \
    && cp -d /lib/libc.musl-x86_64.so.* ./lib \
    && cp -d /usr/lib/libgcc_s.so.* ./usr/lib \
    && cp -d /usr/lib/libstdc++.so.* ./usr/lib \
    # application
    && mv /usr/src/app ./app \
    && find ./app/.yarn -mindepth 1 -name cache -prune -o -exec rm -rf {} + \
    && chown -R 1000:1000 ./app

FROM scratch

WORKDIR /app

COPY --from=builder /volume /

USER node

ENTRYPOINT [ "tini", "--", "node" ]
CMD [ "server.js" ]

In this case the node binary uses the musl as C standard library implementation. A nonroot node use and the ssl ca certificates must be added to the image.

  1. Image base on gcr.io/distroless/static-debian11
FROM node:18-bullseye-slim as builder

WORKDIR /usr/src/app

RUN mkdir -p ./.yarn/cache && echo "console.log('Hello World')" > ./server.js

WORKDIR /volume

ARG GLIBC_VERSION=2.31
ARG GLIBC_DIR=x86_64-linux-gnu
ARG NONROOT=65532

RUN apt-get update \
    && apt-get -y install tini \
    # tini and node binaries
    && mkdir -p ./usr/bin ./usr/local/bin \
    && cp /usr/bin/tini ./usr/bin \
    && cp /usr/local/bin/node ./usr/local/bin \
    # libc, libgcc and libstdc++ libraries
    && mkdir -p ./lib/${GLIBC_DIR} ./usr/lib/${GLIBC_DIR} ./lib64 ./etc \
    && cp -d /lib/${GLIBC_DIR}/ld-${GLIBC_VERSION}.so ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/ld-linux-x86-64.so.* ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libc-${GLIBC_VERSION}.so ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libc.so.* ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libdl-${GLIBC_VERSION}.so ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libdl.so.* ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libm-${GLIBC_VERSION}.so ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libm.so.* ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libpthread-${GLIBC_VERSION}.so ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libpthread.so.* ./lib/${GLIBC_DIR} \
    && cp -d /lib/${GLIBC_DIR}/libgcc_s.so.* ./lib/${GLIBC_DIR} \
    && cp -d /usr/lib/${GLIBC_DIR}/libstdc++.so.* ./usr/lib/${GLIBC_DIR} \
    && cp -r /lib64/ld-linux-x86-64.so.* ./lib64 \
    && cp -r /etc/ld.so.conf.d ./etc \
    # application
    && mv /usr/src/app ./app \
    && find ./app/.yarn -mindepth 1 -name cache -prune -o -exec rm -rf {} + \
    && chown -R ${NONROOT}:${NONROOT} ./app

FROM gcr.io/distroless/static-debian11

WORKDIR /app

COPY --from=builder /volume /

USER nonroot

ENTRYPOINT [ "tini", "--", "node" ]
CMD [ "server.js" ]

In this case the node binary uses the glibc as C standard library implementation. A nonroot user and the ssl ca certificates are already included in the base image.

We decided to with scratchand musl as libc impl.

Image name: eu.gcr.io/gardener-project/gardener/dashboard:latest
Total Image size: 116 MB
Potential wasted space: 0 B
Image efficiency score: 100 %

Which issue(s) this PR fixes:
Fixes #

Special notes for your reviewer:

Release note:

Use `scratch` as base image 

@gardener-robot gardener-robot added needs/review Needs review size/s Size of pull request is small (see gardener-robot robot/bots/size.py) labels Jul 8, 2022
@gardener-robot-ci-3 gardener-robot-ci-3 added reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) needs/ok-to-test Needs approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Jul 8, 2022
@gardener-robot-ci-3 gardener-robot-ci-3 added reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) and removed reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) labels Jul 8, 2022
@gardener-robot
Copy link

@grolu You have pull request review open invite, please check

@gardener-robot-ci-3 gardener-robot-ci-3 added the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Jul 11, 2022
@gardener-robot-ci-1 gardener-robot-ci-1 removed the reviewed/ok-to-test Has approval for testing (check PR in detail before setting this label because PR is run on CI/CD) label Jul 11, 2022
@holgerkoser holgerkoser changed the title Use scratch as base Use scratch as base image Jul 11, 2022
@holgerkoser holgerkoser changed the title Use scratch as base image Use scratch as base image Jul 11, 2022
Copy link
Member

@petersutter petersutter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@gardener-robot gardener-robot added reviewed/lgtm Has approval for merging and removed needs/review Needs review labels Jul 11, 2022
@holgerkoser holgerkoser merged commit 338d2b7 into master Jul 11, 2022
@gardener-robot gardener-robot added the status/closed Issue is closed (either delivered or triaged) label Jul 11, 2022
@holgerkoser holgerkoser deleted the enh/node-scratch branch July 11, 2022 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs/ok-to-test Needs approval for testing (check PR in detail before setting this label because PR is run on CI/CD) reviewed/lgtm Has approval for merging size/s Size of pull request is small (see gardener-robot robot/bots/size.py) status/closed Issue is closed (either delivered or triaged)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants