From 56f5dbc1b7e338fa9bfaa8229be0f20fe303dd46 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 29 Feb 2024 09:55:52 -0500 Subject: [PATCH 1/9] chore: add secure base image dockerfile alternative Signed-off-by: Karl Haworth --- contrib/docker/secure-base-image/Dockerfile | 61 +++++++++++++++++++++ contrib/docker/secure-base-image/README.md | 5 ++ 2 files changed, 66 insertions(+) create mode 100644 contrib/docker/secure-base-image/Dockerfile create mode 100644 contrib/docker/secure-base-image/README.md diff --git a/contrib/docker/secure-base-image/Dockerfile b/contrib/docker/secure-base-image/Dockerfile new file mode 100644 index 0000000000..72bb59cfd0 --- /dev/null +++ b/contrib/docker/secure-base-image/Dockerfile @@ -0,0 +1,61 @@ +# This dockerfile builds an image for the backend package. +# It should be executed with the root of the repo as docker context. +# +# Before building this image, be sure to have run the following commands in the repo root: +# +# yarn install +# yarn tsc +# yarn build:backend +# +# Once the commands have been run, you can build the image using `yarn build-image` + +FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf + +ENV NODE_VERSION 20=~20.11 +ENV PYTHON_VERSION 3.12=~3.12 + +RUN apk add nodejs-$NODE_VERSION yarn + +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. +# Additionally, we install dependencies for `techdocs.generator.runIn: local`. +# https://backstage.io/docs/features/techdocs/getting-started#disabling-docker-in-docker-situation-optional +RUN --mount=type=cache,target=/var/cache/apk,sharing=locked \ + --mount=type=cache,target=/var/lib/apk,sharing=locked \ + apk update && \ + apk add sqlite-dev python-$PYTHON_VERSION py3-pip python-3-dev py3-setuptools build-base gcc libffi-dev glibc-dev openssl-dev brotli-dev c-ares-dev nghttp2-dev icu-dev zlib-dev gcc-12 libuv-dev && \ + yarn config set python /usr/bin/python3 + +# Set up a virtual environment for mkdocs-techdocs-core. +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +RUN pip3 install mkdocs-techdocs-core==1.3.3 + +# From here on we use the least-privileged `node` user to run the backend. +WORKDIR /app +RUN chown nonroot:nonroot /app +USER nonroot + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + +# Copy over Yarn 3 configuration, release, and plugins +COPY --chown=nonroot:nonroot .yarn ./.yarn +COPY --chown=nonroot:nonroot .yarnrc.yml ./ + +# Copy repo skeleton first, to avoid unnecessary docker cache invalidation. +# The skeleton contains the package.json of each package in the monorepo, +# and along with yarn.lock and the root package.json, that's enough to run yarn install. +COPY --chown=nonroot:nonroot yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz + +RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,sharing=locked,uid=1000,gid=1000 \ + yarn workspaces focus --all --production + +# Then copy the rest of the backend bundle, along with any other files we might want. +COPY --chown=nonroot:nonroot packages/backend/dist/bundle.tar.gz app-config*.yaml ./ +RUN tar xzf bundle.tar.gz && rm bundle.tar.gz + +CMD ["node", "packages/backend", "--config", "app-config.yaml"] diff --git a/contrib/docker/secure-base-image/README.md b/contrib/docker/secure-base-image/README.md new file mode 100644 index 0000000000..6f3375b77f --- /dev/null +++ b/contrib/docker/secure-base-image/README.md @@ -0,0 +1,5 @@ +# Secure Base Image for Backstage + +DockerHub images in general did not seem ideal for Backstage as the number of vulnerabilities were quite high regardless of the image used. + +The `Dockerfile` in this directory uses a [`wolfi-base`](https://github.com/wolfi-dev) image from Chainguard Images. This improves the security of the application and reduces false positives in scanners. From 7af6bad7f5bdce3861079da49e796a5440da453f Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 29 Feb 2024 10:10:01 -0500 Subject: [PATCH 2/9] add considerations Signed-off-by: Karl Haworth --- contrib/docker/secure-base-image/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/docker/secure-base-image/README.md b/contrib/docker/secure-base-image/README.md index 6f3375b77f..b261bae9c7 100644 --- a/contrib/docker/secure-base-image/README.md +++ b/contrib/docker/secure-base-image/README.md @@ -3,3 +3,10 @@ DockerHub images in general did not seem ideal for Backstage as the number of vulnerabilities were quite high regardless of the image used. The `Dockerfile` in this directory uses a [`wolfi-base`](https://github.com/wolfi-dev) image from Chainguard Images. This improves the security of the application and reduces false positives in scanners. + +## Considerations + +- Wolfi only releases the `latest` tag for public consumption however digests can be pinned. +- Wolfi OS uses packages from the [os repository](https://github.com/wolfi-dev/os) on GitHub. Some packages may be named differently. +- While Wolfi uses `apk`, the OS is designed to support `glibc`. +- Due to the stripped down nature of the base image, additional packages might be needed compared to a distribution like Debian or Ubuntu. From 9bbabbc26c1f09c1d2a00b311bd9af31ae228a02 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 29 Feb 2024 14:04:53 -0500 Subject: [PATCH 3/9] update build cmd Signed-off-by: Karl Haworth --- contrib/docker/secure-base-image/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/secure-base-image/Dockerfile b/contrib/docker/secure-base-image/Dockerfile index 72bb59cfd0..d4f1930023 100644 --- a/contrib/docker/secure-base-image/Dockerfile +++ b/contrib/docker/secure-base-image/Dockerfile @@ -7,7 +7,7 @@ # yarn tsc # yarn build:backend # -# Once the commands have been run, you can build the image using `yarn build-image` +# Once the commands have been run, you can build the image using `yarn docker-build` FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf From 38c5e7ea0572569734d86b9750877d5c0768a3be Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 1 Mar 2024 15:53:49 -0500 Subject: [PATCH 4/9] use node 18 to match upstream Signed-off-by: Karl Haworth --- contrib/docker/secure-base-image/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/secure-base-image/Dockerfile b/contrib/docker/secure-base-image/Dockerfile index d4f1930023..0e292a1e74 100644 --- a/contrib/docker/secure-base-image/Dockerfile +++ b/contrib/docker/secure-base-image/Dockerfile @@ -11,7 +11,7 @@ FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf -ENV NODE_VERSION 20=~20.11 +ENV NODE_VERSION 18=~18.19 ENV PYTHON_VERSION 3.12=~3.12 RUN apk add nodejs-$NODE_VERSION yarn From 53e38fe0ec71f3fd3bc77ecd3adfa89745baf1df Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 14 Mar 2024 09:46:34 -0400 Subject: [PATCH 5/9] remove digest per feedback Signed-off-by: Karl Haworth --- contrib/docker/secure-base-image/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/secure-base-image/Dockerfile b/contrib/docker/secure-base-image/Dockerfile index 0e292a1e74..8ee6a3d206 100644 --- a/contrib/docker/secure-base-image/Dockerfile +++ b/contrib/docker/secure-base-image/Dockerfile @@ -9,7 +9,7 @@ # # Once the commands have been run, you can build the image using `yarn docker-build` -FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf +FROM cgr.dev/chainguard/wolfi-base:latest ENV NODE_VERSION 18=~18.19 ENV PYTHON_VERSION 3.12=~3.12 From 1f8fb06f18d66ab5b56b2ca70d31825f2593daac Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 14 Mar 2024 10:03:23 -0400 Subject: [PATCH 6/9] `secure base image` -> `minimal hardened image` Signed-off-by: Karl Haworth --- .../{secure-base-image => minimal-harded-image}/Dockerfile | 0 .../{secure-base-image => minimal-harded-image}/README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename contrib/docker/{secure-base-image => minimal-harded-image}/Dockerfile (100%) rename contrib/docker/{secure-base-image => minimal-harded-image}/README.md (95%) diff --git a/contrib/docker/secure-base-image/Dockerfile b/contrib/docker/minimal-harded-image/Dockerfile similarity index 100% rename from contrib/docker/secure-base-image/Dockerfile rename to contrib/docker/minimal-harded-image/Dockerfile diff --git a/contrib/docker/secure-base-image/README.md b/contrib/docker/minimal-harded-image/README.md similarity index 95% rename from contrib/docker/secure-base-image/README.md rename to contrib/docker/minimal-harded-image/README.md index b261bae9c7..4aa7b8b139 100644 --- a/contrib/docker/secure-base-image/README.md +++ b/contrib/docker/minimal-harded-image/README.md @@ -1,4 +1,4 @@ -# Secure Base Image for Backstage +# Minimal Hardened Image for Backstage DockerHub images in general did not seem ideal for Backstage as the number of vulnerabilities were quite high regardless of the image used. From 687aa8a21d89b0a1eee0897a2747ef44f65f1dca Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 14 Mar 2024 10:04:03 -0400 Subject: [PATCH 7/9] add section to `docs/deployment/docker.md` for community contributed dockerfiles Signed-off-by: Karl Haworth --- docs/deployment/docker.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 675a8de947..fd55026fb2 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -338,3 +338,15 @@ Here's an example of these flags in use: ```sh docker image build . -f packages/backend/Dockerfile --tag backstage --progress=plain --no-cache ``` + +## Community Contributed Dockerfile Alternatives + +The `Dockerfile` mentioned above located in `packages/backend` is maintained by the maintainers of Backstage, however there are also community contributed Dockerfile alternatives located in `contrib/docker`. + +### Minimal Hardened Image + +A contributed `Dockerfile` exists within the directory of `contrib/docker/secure-base-image` which uses the [`wolfi-base`](https://github.com/wolfi-dev) image to reduce vulnerabilities. When this was contributed, this alternative `Dockerfile` reduced 98.2% of vulnerabilities in the built Backstage docker image when compared with the image built from `packages/backend/Dockerfile`. + +To reduce maintenance, the digest of the image has been removed from the `contrib/docker/secure-base-image/Dockerfile` file. A complete example with the digest would be `cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf` and it is suggested to update the `FROM` line in the `Dockerfile` to use a digest. Please do a docker pull on the image to get the latest digest. Using the digest allows tools such as Dependabot or Renovatebot to know exactly which image digest is being utilized and allows for Pull Requests to be triggered when a new digest is available. + +It is suggested to setup Dependabot/Renovatebot or a smiliar tool to ensure the image is kept up to date so that vulnerability fixes that have been addressed are pulled in frequently. From ec918c515b276e0f30048cc7de5b97f008d79292 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 14 Mar 2024 10:04:55 -0400 Subject: [PATCH 8/9] update path `contrib/docker/secure-base-image` -> `contrib/docker/minimal-harded-image` Signed-off-by: Karl Haworth --- docs/deployment/docker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index fd55026fb2..424d471a1a 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -345,8 +345,8 @@ The `Dockerfile` mentioned above located in `packages/backend` is maintained by ### Minimal Hardened Image -A contributed `Dockerfile` exists within the directory of `contrib/docker/secure-base-image` which uses the [`wolfi-base`](https://github.com/wolfi-dev) image to reduce vulnerabilities. When this was contributed, this alternative `Dockerfile` reduced 98.2% of vulnerabilities in the built Backstage docker image when compared with the image built from `packages/backend/Dockerfile`. +A contributed `Dockerfile` exists within the directory of `contrib/docker/minimal-harded-image` which uses the [`wolfi-base`](https://github.com/wolfi-dev) image to reduce vulnerabilities. When this was contributed, this alternative `Dockerfile` reduced 98.2% of vulnerabilities in the built Backstage docker image when compared with the image built from `packages/backend/Dockerfile`. -To reduce maintenance, the digest of the image has been removed from the `contrib/docker/secure-base-image/Dockerfile` file. A complete example with the digest would be `cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf` and it is suggested to update the `FROM` line in the `Dockerfile` to use a digest. Please do a docker pull on the image to get the latest digest. Using the digest allows tools such as Dependabot or Renovatebot to know exactly which image digest is being utilized and allows for Pull Requests to be triggered when a new digest is available. +To reduce maintenance, the digest of the image has been removed from the `contrib/docker/minimal-harded-image/Dockerfile` file. A complete example with the digest would be `cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf` and it is suggested to update the `FROM` line in the `Dockerfile` to use a digest. Please do a docker pull on the image to get the latest digest. Using the digest allows tools such as Dependabot or Renovatebot to know exactly which image digest is being utilized and allows for Pull Requests to be triggered when a new digest is available. It is suggested to setup Dependabot/Renovatebot or a smiliar tool to ensure the image is kept up to date so that vulnerability fixes that have been addressed are pulled in frequently. From 28a267a65daf125eec7a1e53453fa1552bf371d1 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Thu, 14 Mar 2024 10:07:31 -0400 Subject: [PATCH 9/9] add disclaimer on maintance of contrib images Signed-off-by: Karl Haworth --- docs/deployment/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 424d471a1a..d8194c51fe 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -341,7 +341,7 @@ docker image build . -f packages/backend/Dockerfile --tag backstage --progress=p ## Community Contributed Dockerfile Alternatives -The `Dockerfile` mentioned above located in `packages/backend` is maintained by the maintainers of Backstage, however there are also community contributed Dockerfile alternatives located in `contrib/docker`. +The `Dockerfile` mentioned above located in `packages/backend` is maintained by the maintainers of Backstage, however there are also community contributed Dockerfile alternatives located in `contrib/docker`. The `Dockerfile`s in `contrib/docker` are not maintained by the maintainers of Backstage and are not necessarily updated when the `Dockerfile` located in `packages/backend` is updated. ### Minimal Hardened Image