* Roll Node.js floor back to >= 24 (Active LTS) Closes #7779. #7779 originally proposed bumping past the Node 25 stop-gap to Node 26. After re-checking the release schedule, the cleaner LTS target is actually Node 24: - Node 24 (Krypton) is currently in Active LTS, supported until ~May 2028. - Node 25 hit end-of-life on April 10 2026 — the floor merged in #7752 / #7749 / #7754 a day ago ships an already-EOL major. - Node 26 was released May 5 2026 and does not enter Active LTS until October 2026. So this PR reverts the Node 25 ratchet from those three PRs and lands on Node 24 — Etherpad's runtime floor stays on a supported LTS for the next ~2 years. Runtime / infra - `package.json` + `src/package.json`: `engines.node` `>=25.0.0` -> `>=24.0.0` - `bin/functions.sh`, `bin/installer.sh`, `bin/installer.ps1`: `REQUIRED_NODE_MAJOR` 25 -> 24 - `Dockerfile`: `node:25-alpine` -> `node:24-alpine` (both stages). Corepack-via-npm workaround is intentionally kept: it works on Node 24 (which still ships corepack) and on Node 25+ (which doesn't), so the same recipe survives the next LTS bump without churn. Comments reworded accordingly. - `snap/snapcraft.yaml`: pinned `NODE_VERSION` 25.9.0 -> 24.15.0; design notes + corepack comment adjusted - `packaging/nfpm.yaml`: `nodejs (>= 25)` -> `nodejs (>= 24)` in top-level depends + deb/rpm overrides - `packaging/bin/etherpad`: comment matches the new pin - `packaging/README.md`: build prereqs + apt install snippet point at `node_24.x`; the long-stale "engines.node floor is 20" line is fixed while we're here - `.github/workflows/*.yml`: setup-node `node-version` 25 -> 24 across every workflow; backend / frontend-admin / upgrade matrices `[25]` -> `[24]` - `.github/workflows/deb-package.yml`: `NODE_MAJOR=25` + `node_25.x` smoke-test installer -> 24 - `bin/plugins/lib/npmpublish.yml`: 25 -> 24 (template propagates to the ~80 ether/* plugins via update-plugins workflow) Docs - `README.md`: install one-liner + Requirements -> Node.js >= 24 - `doc/npm-trusted-publishing.md`: runner requirement -> Node 24 - `doc/plugins.md` / `doc/plugins.adoc`: plugin metadata example `engines.node` -> `">=24.0.0"` @types/node is left at ^25.8.0 — newer type definitions cover Node 24 runtime fine and avoid an unnecessary lockfile churn. Companion homepage one-liner change to follow on ether/ether.github.com. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(plugins): example engines.node = ">=22.0.0", not core's floor Plugin code is overwhelmingly ace-hook glue and rarely uses Node-version- specific APIs, so plugin engines.node should reflect the plugin's own requirements, not track core. Showing core's 24-floor in the example encouraged plugin authors to blindly copy a tighter pin than necessary and locked plugins out of being installable on older Etherpad/Node deployments. Use the most-recent Node LTS that has actually reached EOL (20 -> EOL April 2026) as the example floor, i.e. >=22. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
Etherpad Debian / RPM packaging
Produces native .deb (and, with the same manifest, .rpm / .apk)
packages for Etherpad using nfpm.
Layout
packaging/
nfpm.yaml # nfpm package manifest
bin/etherpad # /usr/bin launcher
scripts/ # preinst / postinst / prerm / postrm
systemd/etherpad.service
systemd/etherpad.default
etc/settings.json.dist # populated in CI from settings.json.template
Built artefacts land in ./dist/.
Building locally
Prereqs: Node 24 (current LTS; matches engines.node floor), pnpm 11.1.2+, nfpm.
pnpm install --frozen-lockfile
pnpm run build:etherpad
# Stage the tree the way CI does:
STAGE=staging/opt/etherpad
mkdir -p "$STAGE"
cp -a src bin package.json pnpm-workspace.yaml README.md LICENSE \
node_modules "$STAGE/"
printf 'packages:\n - src\n - bin\n' > "$STAGE/pnpm-workspace.yaml"
cp settings.json.template packaging/etc/settings.json.dist
VERSION=$(node -p "require('./package.json').version") \
ARCH=amd64 \
nfpm package --packager deb -f packaging/nfpm.yaml --target dist/
End-to-end test (Docker, no real systemd needed)
packaging/test-local.sh builds the .deb and runs the same smoke
test the CI workflow does, inside a throwaway systemd-enabled
container:
packaging/test-local.sh # build + smoke + purge
packaging/test-local.sh --shell # leave the container up so you can poke around
packaging/test-local.sh --build-only # just produce dist/*.deb
This is the fastest way to validate that the systemd hardening, plugin path symlinks, and tsx wrapper actually work together before pushing.
Installing via the Etherpad apt repository (recommended)
The release workflow publishes a signed apt repository at
https://etherpad.org/apt/ on every tagged release. Three lines on
any Debian/Ubuntu/Mint:
curl -fsSL https://etherpad.org/key.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/etherpad.gpg
echo "deb [signed-by=/usr/share/keyrings/etherpad.gpg] https://etherpad.org/apt stable main" \
| sudo tee /etc/apt/sources.list.d/etherpad.list
sudo apt update && sudo apt install etherpad
apt upgrade works going forward. Repo metadata is signed with the
GPG keypair documented in packaging/apt/key.asc (long key id
AF0CD687D51A6E63).
Installing a single .deb directly
The release page publishes both versioned and stable filenames per arch:
# Stable URL — always points at the most recent release:
curl -fsSL -o etherpad-latest_amd64.deb \
https://github.com/ether/etherpad/releases/latest/download/etherpad-latest_amd64.deb
sudo apt install ./etherpad-latest_amd64.deb
# Or pin to a specific version:
sudo apt install ./dist/etherpad_<version>_amd64.deb
sudo systemctl start etherpad
curl http://localhost:9001/health
apt will pull in nodejs (>= 24) (matches Etherpad's engines.node).
If your distro's repos still ship a pre-Node-24 nodejs package, add
NodeSource's node_24.x apt repo before apt install:
KEYRING=/usr/share/keyrings/nodesource.gpg
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| sudo gpg --dearmor --yes -o "${KEYRING}"
echo "deb [signed-by=${KEYRING}] https://deb.nodesource.com/node_24.x nodistro main" \
| sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update
Configuration
- Edit
/etc/etherpad/settings.json, thensudo systemctl restart etherpad. - Environment overrides:
/etc/default/etherpad. - Logs:
journalctl -u etherpad -f. - Data (sqlite default):
/var/lib/etherpad/etherpad.db.
The shipped settings template defaults to dbType: "dirty", which the
template itself warns is for testing only. postinstall rewrites the
seeded /etc/etherpad/settings.json to sqlite and points it at
/var/lib/etherpad/etherpad.db so fresh installs get an ACID-safe DB
out of the box. Existing /etc/etherpad/settings.json is never touched
on upgrade.
Upgrading
dpkg --install etherpad_<new>.deb (or apt install) replaces the app
tree under /opt/etherpad while preserving /etc/etherpad/* and
/var/lib/etherpad/*. The service is restarted automatically.
Removing
sudo apt remove etherpad— keeps config and data.sudo apt purge etherpad— also removes config, data, and theetherpadsystem user.
Publishing to an APT repository (follow-up)
Out of scope here — requires credentials and ownership decisions. Recipes once a repo is picked:
- Cloudsmith (easiest, free OSS tier):
cloudsmith push deb ether/etherpad/any-distro/any-version dist/*.deb - Launchpad PPA: requires signed source packages (a
debian/tree), which nfpm does not produce — usedebuildseparately. - Self-hosted reprepro:
reprepro -b /srv/apt includedeb stable dist/*.deb
Wire the chosen option into .github/workflows/deb-package.yml after
the release job.