From d63ac2c9d3d0b2718f2310e8de8e74fe716a3c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9C=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=BA=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 18 May 2026 15:49:47 +0700 Subject: [PATCH] init --- README.md | 49 +++++++++++++++++++++++++++++++ install-offline.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++ prepare-online.sh | 59 +++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 README.md create mode 100755 install-offline.sh create mode 100755 prepare-online.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bb3de7 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Offline Node.js 22 setup for Ubuntu 20.04 + +This folder contains scripts to prepare and install fresh Node.js 22 without internet on target host. + +## Files + +- `prepare-online.sh` - run on internet-connected Linux machine +- `install-offline.sh` - run on offline Ubuntu 20.04 machine + +## 1) On online machine + +```bash +cd nodejs-offline-ubuntu2004 +chmod +x prepare-online.sh install-offline.sh + +# x64, latest v22 +./prepare-online.sh x64 + +# OR arm64, latest v22 +./prepare-online.sh arm64 + +# Optional: pin exact version +./prepare-online.sh x64 22.15.0 +``` + +You will get directory like: +- `bundle-node-v22.15.0-linux-x64` + +Copy this directory **and** `install-offline.sh` to offline machine. + +## 2) On offline Ubuntu 20.04 + +```bash +chmod +x install-offline.sh +sudo ./install-offline.sh ./bundle-node-v22.15.0-linux-x64 +source /etc/profile.d/nodejs.sh +node -v +npm -v +``` + +## Notes + +- Default install path: `/opt/nodejs` +- Active symlink: `/opt/nodejs/current` +- To install into custom path: + +```bash +sudo INSTALL_PREFIX=/srv/nodejs ./install-offline.sh ./bundle-node-v22.15.0-linux-x64 +``` diff --git a/install-offline.sh b/install-offline.sh new file mode 100755 index 0000000..b6a4886 --- /dev/null +++ b/install-offline.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Usage on offline machine: +# sudo ./install-offline.sh /path/to/bundle-node-v22.x.y-linux-x64 +# +# Optional: +# INSTALL_PREFIX=/opt/nodejs sudo ./install-offline.sh /path/to/bundle + +BUNDLE_DIR="${1:-}" +INSTALL_PREFIX="${INSTALL_PREFIX:-/opt/nodejs}" + +if [[ -z "${BUNDLE_DIR}" ]]; then + echo "Usage: sudo ./install-offline.sh /path/to/bundle-node-v22.x.y-linux-{x64|arm64}" + exit 1 +fi + +if [[ ! -d "${BUNDLE_DIR}" ]]; then + echo "Bundle directory not found: ${BUNDLE_DIR}" + exit 1 +fi + +if [[ ! -f "${BUNDLE_DIR}/INSTALL_ARGS.txt" ]]; then + echo "Missing INSTALL_ARGS.txt in bundle." + exit 1 +fi + +# shellcheck disable=SC1091 +source "${BUNDLE_DIR}/INSTALL_ARGS.txt" + +if [[ -z "${ARCHIVE:-}" || -z "${VERSION:-}" ]]; then + echo "INSTALL_ARGS.txt is invalid." + exit 1 +fi + +if [[ ! -f "${BUNDLE_DIR}/${ARCHIVE}" ]]; then + echo "Archive not found: ${BUNDLE_DIR}/${ARCHIVE}" + exit 1 +fi + +if [[ ! -f "${BUNDLE_DIR}/SHASUMS256.txt" ]]; then + echo "SHASUMS256.txt not found in bundle." + exit 1 +fi + +echo "Verifying checksum..." +( + cd "${BUNDLE_DIR}" + sha256sum -c SHASUMS256.txt --ignore-missing | awk "/${ARCHIVE}: OK/" +) + +echo "Installing to ${INSTALL_PREFIX}..." +sudo mkdir -p "${INSTALL_PREFIX}" +sudo tar -xJf "${BUNDLE_DIR}/${ARCHIVE}" -C "${INSTALL_PREFIX}" +sudo ln -sfn "${INSTALL_PREFIX}/node-v${VERSION}-linux-${ARCH}" "${INSTALL_PREFIX}/current" + +PROFILE_FILE="/etc/profile.d/nodejs.sh" +LINE='export PATH=/opt/nodejs/current/bin:$PATH' + +if [[ "${INSTALL_PREFIX}" != "/opt/nodejs" ]]; then + LINE="export PATH=${INSTALL_PREFIX}/current/bin:\$PATH" +fi + +echo "Writing ${PROFILE_FILE}..." +echo "${LINE}" | sudo tee "${PROFILE_FILE}" >/dev/null +sudo chmod 0644 "${PROFILE_FILE}" + +echo +echo "Done. Re-login or run:" +echo " source ${PROFILE_FILE}" +echo "Check:" +echo " node -v" +echo " npm -v" diff --git a/prepare-online.sh b/prepare-online.sh new file mode 100755 index 0000000..b1b8ebe --- /dev/null +++ b/prepare-online.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Usage: +# ./prepare-online.sh [x64|arm64] [22.15.0] +# +# If version is omitted, script resolves the latest v22 release. + +ARCH="${1:-x64}" +VERSION="${2:-}" + +case "${ARCH}" in + x64) NODE_ARCH="x64" ;; + arm64) NODE_ARCH="arm64" ;; + *) + echo "Unsupported arch: ${ARCH}. Use x64 or arm64." + exit 1 + ;; +esac + +if [[ -z "${VERSION}" ]]; then + # Pick latest v22 from official index without triggering pipefail/SIGPIPE. + INDEX_FILE="$(mktemp)" + curl -fsSL "https://nodejs.org/dist/index.tab" -o "${INDEX_FILE}" + VERSION="$(awk 'NR>1 && $1 ~ /^v22\./ {print substr($1,2); exit}' "${INDEX_FILE}")" + rm -f "${INDEX_FILE}" +fi + +if [[ -z "${VERSION}" ]]; then + echo "Unable to resolve Node.js v22 version." + exit 1 +fi + +NODE_DIR="node-v${VERSION}-linux-${NODE_ARCH}" +ARCHIVE="${NODE_DIR}.tar.xz" +BASE_URL="https://nodejs.org/dist/v${VERSION}" +OUT_DIR="bundle-node-v${VERSION}-linux-${NODE_ARCH}" + +mkdir -p "${OUT_DIR}" + +echo "Downloading Node.js v${VERSION} (${NODE_ARCH})..." +curl -fL "${BASE_URL}/${ARCHIVE}" -o "${OUT_DIR}/${ARCHIVE}" +curl -fL "${BASE_URL}/SHASUMS256.txt" -o "${OUT_DIR}/SHASUMS256.txt" + +echo "Verifying checksum..." +( + cd "${OUT_DIR}" + sha256sum -c SHASUMS256.txt --ignore-missing | awk "/${ARCHIVE}: OK/" +) + +cat > "${OUT_DIR}/INSTALL_ARGS.txt" <