5

I'm currently trying to install node18 on a amazoncorretto:11 base image. I'm getting the error

#6 11.04 Error: Package: 2:nodejs-18.16.0-1nodesource.x86_64 (nodesource)
#6 11.04            Requires: libc.so.6(GLIBC_2.28)(64bit)
#6 11.04 Error: Package: 2:nodejs-18.16.0-1nodesource.x86_64 (nodesource)
#6 11.04            Requires: libm.so.6(GLIBC_2.27)(64bit)

which is described here: https://github.com/nodesource/distributions/issues/1381

I think I need to update glibc to a version which will support node18, but is this possible on amazonlinux2?

3
  • I'd like to know too!
    – Rich
    Jun 16 at 21:38
  • As commented at repost.aws/questions/QUNO13SFKYS2eiCt3f0lwP4Q/… -- "the nodejs 18 aws lambda runtime ... includes nodejs 18 in an amazonlinux2 image. That obviously means that there must be a way to run both of them together"
    – Rich
    Jun 16 at 21:39
  • You can use the public.ecr.aws/lambda/nodejs:18 Docker image, which is a amazonlinux2 image with node18
    – Rich
    Jun 16 at 21:51

5 Answers 5

4
+25

The answer at:
Node.js 18 is compiled for glibc 2.28
is certainly correct although highly unsatisfying.

You cannot run the binary on your system because it relies on a version of glibc which is not available on your system.

$ docker run -it amazoncorretto:11 bash
bash-4.2# cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
bash-4.2# rpm -q --provides glibc|grep -i libc.so
libc.so.6()(64bit)
libc.so.6(GLIBC_2.10)(64bit)
libc.so.6(GLIBC_2.11)(64bit)
libc.so.6(GLIBC_2.12)(64bit)
libc.so.6(GLIBC_2.13)(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.16)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.18)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.2.6)(64bit)
libc.so.6(GLIBC_2.22)(64bit)
libc.so.6(GLIBC_2.23)(64bit)
libc.so.6(GLIBC_2.24)(64bit)
libc.so.6(GLIBC_2.25)(64bit)
libc.so.6(GLIBC_2.26)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.2)(64bit)
libc.so.6(GLIBC_2.3.3)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.5)(64bit)
libc.so.6(GLIBC_2.6)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
libc.so.6(GLIBC_2.8)(64bit)
libc.so.6(GLIBC_2.9)(64bit)

It supports only up to GLIBC_2.26.

Also amazoncorretto:latest only supports up to glibc 2.26:

$ docker run -it amazoncorretto bash
bash-4.2# cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
bash-4.2# rpm -q --provides glibc|grep -i libc.so
libc.so.6()(64bit)
libc.so.6(GLIBC_2.10)(64bit)
libc.so.6(GLIBC_2.11)(64bit)
libc.so.6(GLIBC_2.12)(64bit)
libc.so.6(GLIBC_2.13)(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.16)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.18)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.2.6)(64bit)
libc.so.6(GLIBC_2.22)(64bit)
libc.so.6(GLIBC_2.23)(64bit)
libc.so.6(GLIBC_2.24)(64bit)
libc.so.6(GLIBC_2.25)(64bit)
libc.so.6(GLIBC_2.26)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.2)(64bit)
libc.so.6(GLIBC_2.3.3)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.5)(64bit)
libc.so.6(GLIBC_2.6)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
libc.so.6(GLIBC_2.8)(64bit)
libc.so.6(GLIBC_2.9)(64bit)

You cannot update your glibc library because it is part of the Linux Kernel. It will be upgraded when you migrate to a newer Operating System Version.

The way to get it running on your system would be to rebuild it from the Source Code for your system and ideally package it for easily reproducible installation.

You might setup a docker image from amazoncorretto Base Image with the Packaging Environment set up.

An Package build on the Packaging Docker Host will be installable on all amazoncorretto:11 Systems.

Useful will be the pre-built .spec file which can be found at:
NodeJS .spec file
Then you only need to build your rpmbuild environment to create your installable NodeJS .rpm package.

AWS NodeJS Lambda Runner:

@Rich mentioned the public.ecr.aws/lambda/nodejs:18 AWS Lambda Runner image.
This is an image which is designed to run NodeJS tasks with the CMD dockerfile instruction at startup.
This actually might be fine for some single shot task (what it is designed for) or to startup directly a ExpressJS web app.
A downside is that you cannot independently update the NodeJS engine without upgrading the whole base image because the NodeJS engine is not installed as a system package.


$ docker run -it public.ecr.aws/lambda/nodejs:18 
19 Jun 2023 09:53:51,148 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)


^C19 Jun 2023 09:54:26,776 [INFO] (rapid) Received signal signal=interrupt
19 Jun 2023 09:54:26,776 [INFO] (rapid) Shutting down...
19 Jun 2023 09:54:26,776 [WARNING] (rapid) Reset initiated: SandboxTerminated
19 Jun 2023 09:54:26,776 [INFO] (rapid) Stopping runtime domain
19 Jun 2023 09:54:26,776 [INFO] (rapid) Waiting for runtime domain processes termination
19 Jun 2023 09:54:26,776 [INFO] (rapid) Stopping operator domain
19 Jun 2023 09:54:26,776 [INFO] (rapid) Starting runtime domain
$ docker run --entrypoint bash -it public.ecr.aws/lambda/nodejs:18
bash-4.2# rpm -qa|grep -i node|wc -l
0
bash-4.2# node --version
v18.16.0
bash-4.2# npm --version
9.5.1
bash-4.2# cat /lambda-entrypoint.sh
#!/bin/sh
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.

if [ $# -ne 1 ]; then
  echo "entrypoint requires the handler name to be the first argument" 1>&2
  exit 142
fi
export _HANDLER="$1"

RUNTIME_ENTRYPOINT=/var/runtime/bootstrap
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
  exec /usr/local/bin/aws-lambda-rie $RUNTIME_ENTRYPOINT
else
  exec $RUNTIME_ENTRYPOINT
fi
bash-4.2# ls -lah /usr/local/bin/aws-lambda-rie
-rwxr-xr-x 1 root root 5.6M Jun 12 13:21 /usr/local/bin/aws-lambda-rie
bash-4.2# ls -lah /etc/yum.repos.d
total 12K
drwxr-xr-x 2 root root 4.0K Jun 23  2022 .
drwxr-xr-x 1 root root 4.0K Jun 19 09:57 ..
-rw-r--r-- 1 root root 1003 Oct 26  2021 amzn2-core.repo
2
  • Thanks for this! Please could you comment on how this relates to the public.ecr.aws/lambda/nodejs:18 Docker image, which is a amazonlinux2 image with node18. Can I re-use any parts of that to achieve my goal?
    – Rich
    Jun 18 at 21:42
  • @Rich of course you can use the images that AWS has created with the NodeJS runtime for its Lambda runners as described at: Images based on AWS Lambda NodeJS Runner with FROM instruction like FROM public.ecr.aws/lambda/nodejs:18. The difference would be that you are fixed on NodeJS Version 18 and cannot independently update it to the next version because it is not installed as system package. Jun 19 at 10:04
3

Building up on the answer by Bodo Hugo Barwich and the comment by Rich:

If you do not want to use the Docker image public.ecr.aws/lambda/nodejs:18 directly, you can copy node from that image to your own image via multi-stage build:

FROM public.ecr.aws/lambda/nodejs:18 as nodesource

FROM amazonlinux:2
ENV PATH="$PATH:/var/lang/bin"
COPY --from=nodesource /var/lang /var/lang

RUN npm i whatever
2

NodeJS v18 and v20 can be compiled on RHEL7 and Amazon Linux 2 from source using the following script:

#!/bin/bash

# install YUM package preques
sudo yum -y update
sudo yum groupinstall -y "Development Tools"
sudo yum install -y git libffi-devel openssl-devel openssl-devel \
  dbus-devel p11-kit-devel \
  python3-devel pip3 rust cargo clang llvm-devel readline-devel \
  libcurl-devel expat-devel libarchive-devel libpng-devel \
  libspectre-devel bzip2-devel brotli-devel gperf libjpeg-turbo-devel \
  openjpeg2-devel libtiff-devel lcms2-devel \
  gcc10-c++ gcc10-gdb-plugin gcc10-plugin-devel gcc10 gcc10-binutils \
  gcc10-binutils-devel gcc10-binutils-gold clang-devel clang-tools-extra

# Python script helps fetch the most current version of NodeJS v18 or v20
cat << "EOL" > "nodejs_version.py"
import sys
import re
import urllib.request

def usage():
    sys.stderr.write(f'usage: {sys.argv[0]} <node-ver: 18 or 20>')
    sys.exit(1)

def node_version_fetch(url, src_re):
    with urllib.request.urlopen(url) as response:
        html = response.read().decode('utf-8')
        return src_re.search(html)

try:
    node_ver = sys.argv[1]
except (IndexError):
    usage()

nver_src_mo = node_version_fetch(
    f'https://nodejs.org/download/release/latest-v{node_ver}.x/',
    re.compile(f'node-v{node_ver}\.(\d+)\.(\d+)\.tar\.gz', re.M)
)
node_full_ver = f'{node_ver}.{nver_src_mo.group(1)}.{nver_src_mo.group(2)}'
print(node_full_ver)
EOL

# fetch most current version of NodeJS
NODE_MAJOR_VERSION=20
NODE_VERSION=$(python3 nodejs_version.py ${NODE_MAJOR_VERSION})
echo "BUILDING NODEJS VERSION=${NODE_VERSION}"

# prepare envionment
BUILDDIR=build-v${NODE_VERSION}
NODE_DIR=node-v${NODE_VERSION}
SOURCE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_DIR}.tar.gz"
PREFIX=/opt/node/${NODE_DIR}
NPROC=$(nproc)
CC=gcc10-gcc
CXX=gcc10-g++
export CC CXX

# build, test, install
rm -rf ${BUILDDIR}
mkdir -p ${BUILDDIR}
pushd ${BUILDDIR}
wget "${SOURCE_URL}"
tar xf ${NODE_DIR}.tar.gz
pushd ${NODE_DIR}
./configure --prefix=${PREFIX}
make clean
make -j${NPROC}
make -j${NPROC} test-only
sudo make -j${NPROC} install
popd
popd
1

You can custom compile on an AL2 instance which will put into the directory from where you downloaded under node/out/Release:

# Needs libfortran
sudo yum-config-manager --add-repo http://mirror.centos.org/centos/7/sclo/x86_64/rh/
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libgfortran5-8.3.1-2.1.1.el7.x86_64.rpm
sudo yum install libgfortran5-8.3.1-2.1.1.el7.x86_64.rpm -y

# Requires gcc and g++ 8.3 or greater
sudo yum install -y devtoolset-8 --nogpgcheck
scl enable devtoolset-8 bash

cd ~/
git clone [email protected]:nodejs/node.git
git checkout tags/v18.18.0
./configure

# Skip cctest as it fails on AL2
make -C out node BUILDTYPE=Release -j4

If you want to also fix when using nvm...

nvm install v18.18.0
cd ~/.nvm/versions/node/v18.18.0/bin/
mv node node-GLIBC_2.27
ln -s ~/node/out/Release/node node 
nvm alias default v18.18.0

Also found that you can alternatively skip devtools-8 if you install gcc10 and use that before the configure:

sudo yum install gcc10-c++ libgfortran10
CC=gcc10-cc CXX=gcc10-c++ ./configure
1

Multiple AWS teams have compiled binaries for NodeJS v18.x for Amazon Linux 2. You can find them in the CloudWatch logs related to ElasticBeanstalk and Cloud9 resources.

Borrowing the binary from the Cloud9 team, you can install the NodeJS version on your Amazon Linux 2 based host.

wget -nv https://d3rnber7ry90et.cloudfront.net/linux-x86_64/node-v18.17.1.tar.gz
mkdir /usr/local/lib/node
tar -xf node-v18.17.1.tar.gz
mv node-v18.17.1 /usr/local/lib/node/nodejs
### Unload NVM, use the new node in the path, then install some items globally.
echo "export NVM_DIR=''" >> /home/ec2-user/.bashrc
echo "export NODEJS_HOME=/usr/local/lib/node/nodejs" >> /home/ec2-user/.bashrc
echo "export PATH=\$NODEJS_HOME/bin:\$PATH" >> /home/ec2-user/.bashrc
### Reload environment
. /home/ec2-user/.bashrc
### Verify NodeJS v18.x is operating
node -e "console.log('Running Node.js ' + process.version)"
1
  • +1 and if you get a chance, could you please update this with a working link for v18.18.2 from the same environment? It fixes some critical CVEs and will be greatly appreciated! Thank you!
    – Amit Naidu
    Nov 16 at 3:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .