feat(packaging): add Debian (.deb) build via nfpm with systemd unit#7559
feat(packaging): add Debian (.deb) build via nfpm with systemd unit#7559JohnMcLear wants to merge 2 commits intoether:developfrom
Conversation
First-class Debian packaging for Etherpad, producing signed-ready etherpad-lite_<version>_<arch>.deb artefacts for amd64 and arm64 from a single nfpm manifest. Installing the package gives users: - /opt/etherpad-lite with a prebuilt, self-contained node_modules/ — no pnpm required at runtime, just `nodejs (>= 20)`. - etherpad system user/group, created via `adduser` in preinst. - /etc/etherpad-lite/settings.json seeded from the template on first install, preserved across upgrades, removed on `purge`. - /var/lib/etherpad-lite owned by etherpad:etherpad, with the default dirty-DB retargeted there so ProtectSystem=strict works. - /lib/systemd/system/etherpad-lite.service — hardened unit (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, RestrictAddressFamilies) with Restart=on-failure. - /usr/bin/etherpad-lite CLI wrapper running `node --import tsx/esm`. CI (.github/workflows/deb-package.yml) triggers on v* tags, builds both arches via native runners (ubuntu-latest + ubuntu-24.04-arm), smoke-tests the amd64 package end-to-end (install → systemctl start → curl /health → purge → confirm user removed), and attaches the artefacts to the GitHub Release. Publishing to an APT repo (Cloudsmith, Launchpad PPA, self-hosted reprepro) is intentionally out of scope — needs a governance decision on who holds the signing key. Recipes are documented in packaging/README.md. Refs ether#7529 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review Summary by QodoAdd Debian (.deb) packaging via nfpm with systemd service
WalkthroughsDescription• Add first-class Debian (.deb) packaging via nfpm for amd64 and arm64 • Create systemd service with hardened security settings and auto-restart • Implement Debian lifecycle scripts (preinst/postinst/prerm/postrm) • Add CI workflow for automated package building and smoke testing Diagramflowchart LR
A["Source Code<br/>+ node_modules"] -->|Stage| B["staging/<br/>opt/etherpad-lite"]
B -->|nfpm package| C[".deb Artifact<br/>amd64/arm64"]
D["nfpm.yaml<br/>manifest"] -->|Configure| C
E["Lifecycle Scripts<br/>preinst/postinst/prerm/postrm"] -->|Package| C
F["systemd Unit<br/>+ Hardening"] -->|Include| C
C -->|CI Workflow| G["GitHub Release<br/>Assets"]
C -->|Smoke Test| H["Install → Start<br/>→ Health Check"]
File Changes1. packaging/nfpm.yaml
|
Code Review by Qodo
1.
|
…rms, 2-space indent Addresses Qodo review feedback on ether#7559: 1. Smoke test false-positive: the `for` loop polling /health never failed the job if the endpoint stayed down — `curl && break || sleep 2` keeps returning 0 from the trailing `sleep`, so `set -e` never trips. CI could attach a broken .deb to a release. Fix: track success explicitly and exit 1 (plus dump journald logs for diagnostics) when the service never becomes healthy. 2. /etc/default/etherpad-lite was world-readable (0644). systemd loads it via `EnvironmentFile=…`, and Etherpad supports ${ENV_VAR}-substitution for secrets (DB_PASSWORD etc.), so any local user could read anything admins drop there. Fix: install the conffile as root:etherpad 0640 — only root and the service user can read it. 3. Indentation: reflow maintainer scripts from 4-space to 2-space to match the repo style rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
First-class Debian packaging for Etherpad. Produces
etherpad-lite_<version>_<arch>.debfor amd64 and arm64 from a singlenfpmmanifest. Installing the package gives users:/opt/etherpad-litewith a prebuilt, self-containednode_modules/— no pnpm required at runtime, onlynodejs (>= 20).etherpadsystem user/group, created viaadduserinpreinst./etc/etherpad-lite/settings.json(seeded from the template on first install; preserved across upgrades; removed onpurge)./var/lib/etherpad-liteowned byetherpad:etherpad, with the default dirty-DB path retargeted there soProtectSystem=strictworks./lib/systemd/system/etherpad-lite.service— hardened unit (NoNewPrivileges,ProtectSystem=strict,ProtectHome,PrivateTmp,RestrictAddressFamilies) withRestart=on-failure./usr/bin/etherpad-liteCLI wrapper runningnode --import tsx/esm.Part of #7529 — top-3 deployment targets (Snap #7558, Apt, Home Assistant).
CI
.github/workflows/deb-package.ymltriggers onv*tags, builds both arches via native runners (ubuntu-latest+ubuntu-24.04-arm), and smoke-tests the amd64 package end-to-end:dpkg -iinstallssystemctl start etherpad-litecurl /healthreturns 200dpkg --purgeremoves config + userArtefacts are attached to the GitHub Release.
Not included (follow-up)
Publishing to an APT repo (Cloudsmith / Launchpad PPA / self-hosted reprepro) is out of scope — needs a governance decision on who holds the signing key. Recipes are in
packaging/README.mdto be wired in once that's decided.Legacy
bin/buildDebian.shandbin/deb-src/are stale (Etherpad v1.3, init-based, unmaintained). Flagged for removal in a follow-up PR so this one stays mechanical.Test plan
pnpm install --frozen-lockfile && pnpm run build:etherpadsucceedsnfpm package --packager debproduces a well-formed.deb(dpkg-deb -I/-c)/healthreturns OK/etc/etherpad-lite/settings.jsonuntouched; service restartedapt removekeeps/etcand/var/lib;apt purgeremoves them plus theetherpaduserRefs #7529
🤖 Generated with Claude Code