From e1e1ed55b27fae6424d2f732d62d990e9d12b797 Mon Sep 17 00:00:00 2001 From: Sheogorath Date: Wed, 4 May 2022 03:02:06 +0200 Subject: [PATCH] feat(distroless): Provide distroless container image This patch introduces a distroless container image, which cuts down the container content to the bare minimum. No shells, no package managers, nothing, just the hedgedoc. These constraints make this setup very robust, but also hard to debug without the right tools, therefore it's not recommended to be used by people who are not completely familiar with containers and low-level debugging tools. Nontheless this image should be very useful in Kubernetes deployments. Further, compared to the alpine container image, it'll further cut down dependencies while staying on glibc, which can prevent some common issues with musllib. The distroless image is based on Google distroless base image for nodejs: https://github.com/GoogleContainerTools/distroless/tree/55d918e07c9341f83519ab1fc6d8fe0197bca13f/nodejs Signed-off-by: Sheogorath --- .github/workflows/nightly.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- distroless/Dockerfile | 49 +++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 distroless/Dockerfile diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a5030a45..af0d0f74 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - base: [debian, alpine] + base: [debian, alpine, distroless] env: HEDGEDOC_VERSION: master HEDGEDOC_IMAGE: quay.io/hedgedoc/hedgedoc-nightly diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0d13823c..ace964d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - base: [debian, alpine] + base: [debian, alpine, distroless] env: # renovate: datasource=github-tags depName=hedgedoc/hedgedoc versioning=semver HEDGEDOC_VERSION: 1.9.3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef3c9709..7f5306cc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - base: [debian, alpine] + base: [debian, alpine, distroless] env: BASE: ${{ matrix.base }} # needed in tests/version.sh steps: diff --git a/distroless/Dockerfile b/distroless/Dockerfile new file mode 100644 index 00000000..a887ef39 --- /dev/null +++ b/distroless/Dockerfile @@ -0,0 +1,49 @@ +FROM docker.io/library/node:16.14.2-bullseye-slim@sha256:d54981fe891c9e3442ea05cb668bc8a2a3ee38609ecce52c7b5a609fadc6f64b AS base + +FROM base AS builder + + +RUN apt-get update && apt-get install --no-install-recommends -y git jq ca-certificates python-is-python3 build-essential + + +# Build arguments to change source url, branch or tag +ARG CODIMD_REPOSITORY +ARG HEDGEDOC_REPOSITORY=https://github.com/hedgedoc/hedgedoc.git +ARG VERSION=master +RUN if [ -n "${CODIMD_REPOSITORY}" ]; then echo "CODIMD_REPOSITORY is deprecated. Please use HEDGEDOC_REPOSITORY instead" && exit 1; fi + +# Clone the source and remove git repository but keep the HEAD file +RUN git clone --depth 1 --branch "$VERSION" "$HEDGEDOC_REPOSITORY" /hedgedoc +RUN git -C /hedgedoc log --pretty=format:'%ad %h %d' --abbrev-commit --date=short -1 +RUN git -C /hedgedoc rev-parse HEAD > /tmp/gitref +RUN rm -rf /hedgedoc/.git/* +RUN mv /tmp/gitref /hedgedoc/.git/HEAD +RUN jq ".repository.url = \"${HEDGEDOC_REPOSITORY}\"" /hedgedoc/package.json > /hedgedoc/package.new.json +RUN mv /hedgedoc/package.new.json /hedgedoc/package.json + + +# Install app dependencies and build +WORKDIR /hedgedoc +RUN yarn install --production=false --frozen-lockfile +RUN yarn run build +RUN yarn install --production=true --frozen-lockfile +RUN rm -f /hedgedoc/config.json +RUN ln -s /files/config.json /hedgedoc/config.json +COPY --chown=$UID /resources/healthcheck.mjs /hedgedoc/healthcheck.mjs + +# Use distroless image +FROM gcr.io/distroless/nodejs:16@sha256:2b0fe69900014a74bc85fd4588e86b90139777a8fa7e2feea1f14447ea82e651 + +ARG UID=10000 +ENV NODE_ENV=production +ENV UPLOADS_MODE=0700 + +COPY --chown=$UID --from=builder /hedgedoc /hedgedoc +COPY ["resources/config.json", "/files/"] + +HEALTHCHECK --interval=5s CMD node healthcheck.mjs +WORKDIR /hedgedoc +EXPOSE 3000 +USER $UID + +CMD ["app.js"]