From acfcf895fb9a9fbae59b8628a628f8977035f4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 6 Sep 2022 21:29:23 +0200 Subject: [PATCH] feat: enable Corepack (pnpm support, unbundle yarn) This patch enables Corepack, allowing to use pnpm directly and unbundling yarn from the default image. Removing yarn also simplifies the image and the maintainance. This change as been discussed in https://github.com/nodejs/docker-node/issues/777. Closes #777, #1645, #1755. --- .github/workflows/build-test.yml | 3 ++ CONTRIBUTING.md | 4 +-- Dockerfile-alpine.template | 22 +----------- Dockerfile-debian.template | 21 +----------- Dockerfile-slim.template | 34 +----------------- README.md | 9 +++-- docs/BestPractices.md | 59 ++++++++------------------------ keys/yarn.keys | 1 - update.sh | 35 +++++-------------- 9 files changed, 35 insertions(+), 153 deletions(-) delete mode 100644 keys/yarn.keys diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 99559c506d..6b03abdc3f 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -94,3 +94,6 @@ jobs: - name: Test for yarn run: docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} yarn --version + + - name: Test for pnpm + run: docker run --rm node:${{ matrix.version }}-${{ matrix.variant }} pnpm --version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e1e87158c..ac3b7ff895 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,9 +6,7 @@ Thank you for your contribution. Here are a set of guidelines for contributing t New **Node.js** releases are released as soon as possible. -New **NPM** releases are not tracked. We simply use the NPM version bundled in the corresponding Node.js release. - -**Yarn** is updated to the latest version only when there is a new Node.js SemVer PATCH release (unless Yarn has received a security update), and it's updated only in the branch with the new release, preferably in the same PR. The `update.sh` script does this automatically when invoked with a specific branch, e.g. `./update.sh 6.10`. +New package manager releases are not tracked. We simply use the versions provided by [Corepack](https://github.com/nodejs/corepack). ### Submitting a PR for a version update diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index c2e2c5a5a9..b839a99dd8 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -57,31 +57,11 @@ RUN addgroup -g 1000 node \ fi \ && rm -f "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" \ && apk del .build-deps \ + && corepack enable \ # smoke tests && node --version \ && npm --version -ENV YARN_VERSION 0.0.0 - -RUN apk add --no-cache --virtual .build-deps-yarn curl gnupg tar \ - && for key in \ - "${YARN_KEYS[@]}" - ; do \ - gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ - done \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \ - && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - && mkdir -p /opt \ - && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ - && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - && apk del .build-deps-yarn \ - # smoke test - && yarn --version - COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template index 17962567fa..debd2ab6eb 100644 --- a/Dockerfile-debian.template +++ b/Dockerfile-debian.template @@ -30,30 +30,11 @@ RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \ && tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \ && rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ + && corepack enable \ # smoke tests && node --version \ && npm --version -ENV YARN_VERSION 0.0.0 - -RUN set -ex \ - && for key in \ - "${YARN_KEYS[@]}" - ; do \ - gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ - done \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \ - && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - && mkdir -p /opt \ - && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ - && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - # smoke test - && yarn --version - COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/Dockerfile-slim.template b/Dockerfile-slim.template index aa7816d963..17d13b153d 100644 --- a/Dockerfile-slim.template +++ b/Dockerfile-slim.template @@ -41,43 +41,11 @@ RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \ | xargs -r apt-mark manual \ && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ + && corepack enable \ # smoke tests && node --version \ && npm --version -ENV YARN_VERSION 0.0.0 - -RUN set -ex \ - && savedAptMark="$(apt-mark showmanual)" \ - && apt-get update && apt-get install -y ca-certificates curl wget gnupg dirmngr --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* \ - && for key in \ - "${YARN_KEYS[@]}" - ; do \ - gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ - done \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ - && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \ - && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - && mkdir -p /opt \ - && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ - && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ - && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ - && apt-mark auto '.*' > /dev/null \ - && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; } \ - && find /usr/local -type f -executable -exec ldd '{}' ';' \ - | awk '/=>/ { print $(NF-1) }' \ - | sort -u \ - | xargs -r dpkg-query --search \ - | cut -d: -f1 \ - | sort -u \ - | xargs -r apt-mark manual \ - && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ - # smoke test - && yarn --version - COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/README.md b/README.md index ee6b4b97d6..44c06377f7 100644 --- a/README.md +++ b/README.md @@ -146,11 +146,10 @@ $ docker run node npm --loglevel=warn ... ## Image Variants The `node` images come in many flavors, each designed for a specific use case. -All of the images contain pre-installed versions of `node`, -[`npm`](https://www.npmjs.com/), and [`yarn`](https://yarnpkg.com). For each -supported architecture, the supported variants are different. In the file: -[versions.json](./versions.json), it lists all supported variants for all of -the architectures that we support now. +All of the images contain pre-installed versions of `node`. +For each supported architecture, the supported variants are different. +In the file: [versions.json](./versions.json), it lists all supported variants +for all of the architectures that we support now. ### `node:` diff --git a/docs/BestPractices.md b/docs/BestPractices.md index d15c0964e4..4510fc7dfe 100644 --- a/docs/BestPractices.md +++ b/docs/BestPractices.md @@ -27,62 +27,33 @@ Run with `NODE_ENV` set to `production`. This is the way you would pass in secre -e "NODE_ENV=production" ``` -## Global npm dependencies - -If you need to install global npm dependencies, it is recommended to place those dependencies in the [non-root user](#non-root-user) directory. To achieve this, add the following line to your `Dockerfile` +## Package Managers -```Dockerfile -ENV NPM_CONFIG_PREFIX=/home/node/.npm-global -ENV PATH=$PATH:/home/node/.npm-global/bin # optionally if you want to run npm global bin without specifying path -``` +Just use your package managers as you usually would. +They will be automatically installed by [Corepack](https://github.com/nodejs/corepack), which is enabled by default. -## Upgrading/downgrading Yarn +Corepack downloads your package managers the first time you use them. +It honors the [`packageManager` field of your `package.json`](https://nodejs.org/api/packages.html#packagemanager) +if defined. -### Local - -If you need to upgrade/downgrade `yarn` for a local install, you can do so by issuing the following commands in your `Dockerfile`: - -> Note that if you create some other directory which is not a descendant one from where you ran the command, you will end up using the global (dated) version. If you wish to upgrade `yarn` globally follow the instructions in the next section. - -> When following the local install instructions, due to duplicated yarn the image will end up being bigger. - -```Dockerfile -FROM node:6 +As many production environments don't have network access, +you probably want to bundle your package managers in your Docker image. -ENV YARN_VERSION 1.16.0 +To do so, add the following line to your `Dockerfile`: -RUN yarn policies set-version $YARN_VERSION ``` - -### Global - -```Dockerfile -FROM node:6 - -ENV YARN_VERSION 1.16.0 - -RUN curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ - && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ - && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ - && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ - && rm yarn-v$YARN_VERSION.tar.gz +RUN corepack prepare ``` -If you're using an Alpine-based image, `curl` won't be present, so you'll need to make sure it's installed while using it: +## Global npm dependencies -```Dockerfile -FROM node:6-alpine +If you need to install global npm dependencies, it is recommended to place those dependencies in the [non-root user](#non-root-user) directory. To achieve this, add the following line to your `Dockerfile`: -ENV YARN_VERSION 1.5.1 +```Dockerfile +ENV NPM_CONFIG_PREFIX=/home/node/.npm-global -RUN apk add --no-cache --virtual .build-deps-yarn curl \ - && curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ - && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ - && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ - && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ - && rm yarn-v$YARN_VERSION.tar.gz \ - && apk del .build-deps-yarn +ENV PATH=$PATH:/home/node/.npm-global/bin # optionally if you want to run npm global bin without specifying path ``` ## Handling Kernel Signals diff --git a/keys/yarn.keys b/keys/yarn.keys deleted file mode 100644 index 6b0feed13c..0000000000 --- a/keys/yarn.keys +++ /dev/null @@ -1 +0,0 @@ -6A010C5166006599AA17F08146C2130DFD2497F5 diff --git a/update.sh b/update.sh index 799f4afce2..9b8a12a9ab 100755 --- a/update.sh +++ b/update.sh @@ -12,15 +12,15 @@ function usage() { Examples: - update.sh # Update all images - - update.sh -s # Update all images, skip updating Alpine and Yarn + - update.sh -s # Update all images, skip updating Alpine - update.sh 8,10 # Update all variants of version 8 and 10 - - update.sh -s 8 # Update version 8 and variants, skip updating Alpine and Yarn + - update.sh -s 8 # Update version 8 and variants, skip updating Alpine - update.sh 8 buster-slim,buster # Update only buster's slim and buster variants for version 8 - - update.sh -s 8 stretch # Update only stretch variant for version 8, skip updating Alpine and Yarn + - update.sh -s 8 stretch # Update only stretch variant for version 8, skip updating Alpine - update.sh . alpine # Update the alpine variant for all versions OPTIONS: - -s Security update; skip updating the yarn and alpine versions. + -s Security update; skip updating alpine version. -b CI config update only -h Show this message @@ -67,7 +67,6 @@ arch=$(get_arch) if [ "${SKIP}" != true ]; then alpine_version=$(get_config "./" "alpine_version") - yarnVersion="$(curl -sSL --compressed https://yarnpkg.com/latest-version)" fi function in_versions_to_update() { @@ -135,21 +134,16 @@ function update_node_version() { sed -Ei -e 's/^FROM (.*)/FROM '"$fromprefix"'\1/' "${dockerfile}-tmp" sed -Ei -e 's/^(ENV NODE_VERSION ).*/\1'"${nodeVersion}"'/' "${dockerfile}-tmp" - currentYarnVersion="$(grep "ENV YARN_VERSION" "${dockerfile}" | cut -d' ' -f3)" - sed -Ei -e 's/^(ENV YARN_VERSION ).*/\1'"${currentYarnVersion}"'/' "${dockerfile}-tmp" - # shellcheck disable=SC1004 new_line=' \\\ ' # Add GPG keys - for key_type in "node" "yarn"; do - while read -r line; do - pattern='"\$\{'$(echo "${key_type}" | tr '[:lower:]' '[:upper:]')'_KEYS\[@\]\}"' - sed -Ei -e "s/([ \\t]*)(${pattern})/\\1${line}${new_line}\\1\\2/" "${dockerfile}-tmp" - done < "keys/${key_type}.keys" - sed -Ei -e "/${pattern}/d" "${dockerfile}-tmp" - done + while read -r line; do + pattern='"\$\{'$(echo "node" | tr '[:lower:]' '[:upper:]')'_KEYS\[@\]\}"' + sed -Ei -e "s/([ \\t]*)(${pattern})/\\1${line}${new_line}\\1\\2/" "${dockerfile}-tmp" + done < "keys/node.keys" + sed -Ei -e "/${pattern}/d" "${dockerfile}-tmp" if is_alpine "${variant}"; then alpine_version="${variant#*alpine}" @@ -169,17 +163,6 @@ function update_node_version() { sed -Ei -e "s/(debian:)name-slim/\\1${variant}/" "${dockerfile}-tmp" fi - if diff -q "${dockerfile}-tmp" "${dockerfile}" > /dev/null; then - echo "${dockerfile} is already up to date!" - else - if [ "${SKIP}" = true ]; then - # Get the currently used Yarn version - yarnVersion="$(grep "ENV YARN_VERSION" "${dockerfile}" | cut -d' ' -f3)" - fi - sed -Ei -e 's/^(ENV YARN_VERSION ).*/\1'"${yarnVersion}"'/' "${dockerfile}-tmp" - echo "${dockerfile} updated!" - fi - # Required for POSIX sed if [ -f "${dockerfile}-tmp-e" ]; then rm "${dockerfile}-tmp-e"