Skip to content

Commit

Permalink
containers: switch to official node binaries
Browse files Browse the repository at this point in the history
NodeSource, while handy, does not support version pinning. As such it
would be impossible for us to ensure that the image can be reproduced.

See nodesource/distributions#33.

Included is also a script to update the containers version of NodeJS
automatically, pending integration with CI.
  • Loading branch information
alaviss committed Dec 7, 2021
1 parent 7c52517 commit a351e6e
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 15 deletions.
93 changes: 78 additions & 15 deletions containers/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,85 @@
# This file is licensed under the terms of the MIT license. See "license.txt"
# included in this distribution for more information.

# --- Image used for building the compiler

# The name of the Debian release being used.
#
# This image tracks LTS releases.
# These images tracks LTS releases.
ARG debian_release=buster

FROM docker.io/debian:$debian_release-slim as builder
# Update this monthly
#
# If you alter this line formatting or move it away from the top, update
# check-node-updates.sh to do update checking/fixing properly.
ARG node_version=16.13.1

# --- Builder image to download NodeJS for other images

# Respecified here so that the variable can be used by this image
ARG debian_release
FROM docker.io/debian:${debian_release}-slim as node-downloader

# Add the NodeSource keyring to APT
ADD --chmod=644 https://deb.nodesource.com/gpgkey/nodesource.gpg.key /etc/apt/trusted.gpg.d/nodesource.asc
# Inherit this from global environment
ARG node_version

# Install ca-certificates in order to download from NodeSource.
# Update APT and install tools to download nodejs
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
curl \
ca-certificates \
# Add the NodeSource sources to APT
&& echo "deb [signed-by=/etc/apt/trusted.gpg.d/nodesource.asc] https://deb.nodesource.com/node_16.x $debian_release main" > /etc/apt/sources.list.d/nodesource.list \
# Update APT then install compiler build dependencies
&& apt-get update \
gnupg \
xz-utils \
&& rm -rf /var/lib/apt/lists/*

# Download and extract nodejs
RUN set -eux \
&& dpkg_arch=$(dpkg --print-architecture) \
&& node_arch= \
&& case "$dpkg_arch" in \
amd64) node_arch="x64";; \
arm64) node_arch="arm64";; \
armhf) node_arch="armv7l";; \
*) echo "Error: unsupported nodejs architecture"; exit 1;; \
esac \
# Import trusted release keys
# https://github.com/nodejs/node#release-keys
&& gpg --keyserver keyserver.ubuntu.com \
--keyserver keys.openpgp.org \
--recv-keys \
4ED778F539E3634C779C87C6D7062848A1AB005C \
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
74F12602B6F1C4E913FAA37AD3A89613643B6201 \
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
A48C2BEE680E841632CD4E44F07496B3EB3C1762 \
108F52B48DB57BB0CC439B2997B01419BD92F80A \
B9E2F5981AA6E0CD28160D9FF13993A75599653C \
# Download the tarball
&& release_name=node-v${node_version}-linux-${node_arch} \
&& tarball_name=${release_name}.tar.xz \
&& curl -LO "https://nodejs.org/dist/v${node_version}/${tarball_name}" \
# Download the checksums
&& curl -LO "https://nodejs.org/dist/v${node_version}/SHASUMS256.txt.asc" \
# Verify the signatures
&& gpg -o SHASUMS256.txt --decrypt SHASUMS256.txt.asc \
# Verify the checksums
#
# It would be better if we have pipefail here, but sha256sum knows to bail
# when there is an empty input, so all is well.
&& grep -F "${tarball_name}" SHASUMS256.txt | sha256sum -c - \
# Extract the tarball
&& mkdir -p "/node-${node_version}" \
&& tar -C "/node-${node_version}" --strip-components=1 -xf "${tarball_name}" \
# Remove artifacts to save space (even though this is just a builder image)
&& rm SHASUMS256.txt* "$tarball_name"

# --- Image used for building the compiler

FROM docker.io/debian:${debian_release}-slim as builder

# Update APT then install compiler build dependencies
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
# Required for building the compiler
Expand All @@ -40,14 +95,22 @@ RUN apt-get update \
git \
# Required for running build script
python3 \
# Required for building docs
nodejs \
# Required for sharing artifacts in CI
ca-certificates \
curl \
# Required to build archives
zstd \
&& rm -rf /var/lib/apt/lists/*

# Inherit the variable to this image
ARG node_version

# Install NodeJS
COPY --from=node-downloader /node-${node_version} /opt/node-${node_version}

# Add Node to PATH
ENV PATH="/opt/node-${node_version}/bin:${PATH}"

# --- Image used for testing the compiler

FROM builder as tester
Expand Down
37 changes: 37 additions & 0 deletions containers/check-node-updates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash

# Set safety bash features
set -eu -o pipefail

scriptDir=$(dirname "$(realpath "${BASH_SOURCE[0]}")")

# Grab the containers NodeJS version
containerVer=$(grep -m 1 -F "node_version=" "$scriptDir/Containerfile" | cut -d'=' -f 2)

echo "Containers version: $containerVer"

# Look for the latest LTS in NodeJS index
latestLts=$(curl -sL https://nodejs.org/dist/index.json | jq -r 'first(.[] | select(.lts != false) | .version | ltrimstr("v"))')

echo "Latest LTS version: $latestLts"

if [[ $latestLts == "$containerVer" ]]; then
echo "Containers' NodeJS is up-to-date"
else
echo "Containers' NodeJS is outdated, performing update"
temporary=$(mktemp "$scriptDir/Containerfile.tmp.XXXXXXXXXX")
# Write the update to a temporary
#
# This sed script captures everything up to `node_version=`, then change the
# portion after the `=` to the latest version
sed 's/\(.*node_version=\).*/\1'"$latestLts"'/' "$scriptDir/Containerfile" > "$temporary"
# Show the diff
diff -u "$scriptDir/Containerfile" "$temporary" || {
# Diff returns either 1 or 0 on success, so exit failure otherwise
if [[ $? -ne 1 && $? -ne 0 ]]; then
exit "$?"
fi
}
# Then replace the original file
mv -v "$temporary" "$scriptDir/Containerfile"
fi

0 comments on commit a351e6e

Please sign in to comment.