Skip to content

Installer

The Parako.ID installer is a single bash script published at https://get.parako.id. It verifies the release artifact, stages it, preserves operator-owned runtime files, and atomically switches the application release pointer.

Important: Infrastructure, database backups, database migrations, process management, reverse proxy, TLS, secrets, and production configuration remain operator responsibilities. The installer never performs any of these. The next-steps card it prints after every install or update names each operator action and links to the per-release migration command.

Source: installer/install.sh.

Terminal window
# Fresh install (system-wide)
curl --proto '=https' --tlsv1.2 -fsSL https://get.parako.id | sudo bash
# Pinned version
curl --proto '=https' --tlsv1.2 -fsSL https://get.parako.id | sudo bash -s -- --version v0.2.0
# Update / rollback / gc / doctor — see parako CLI for the helper
parako update
parako rollback
parako gc --keep 3 --yes
parako doctor

Full upgrade runbook: Upgrades. Operator CLI reference: parako CLI.

PhaseAction
VerifyOS / arch check, download tarball + SHA256SUMS + cosign signature + certificate, verify SHA256, verify the cosign keyless signature against Sigstore.
StageExtract into INSTALL_DIR/releases/.staging.<tag>.<pid>/, smoke-check dist/src/index.js, atomically promote to releases/<tag>/.
PreserveOn first install only, populate INSTALL_DIR/runtime/ with the shipped locales/ and views/ subtrees. Replace releases/<tag>/runtime with a relative symlink back to the shared INSTALL_DIR/runtime/.
SwitchAtomic mv -T swap of the INSTALL_DIR/current symlink to the new release. Record metadata in INSTALL_DIR/.parako-state (mode 0644, no secrets).
Hand offInstall /usr/local/bin/parako (non-fatal). Print the next-steps card.

Escape hatch: --insecure-no-signature --reason "<text>" when Sigstore is unreachable (reason is logged). See Installer Security.

Operator-owned, never performed by the installer:

  • Database — connections, migrations, backups, restores, schema rollbacks.
  • Services — start, stop, restart, supervisor configuration (systemd, PM2, docker, runit, …).
  • Reverse proxy — nginx, Caddy, Traefik, HAProxy configuration and reloads.
  • TLS — certbot, Let’s Encrypt, internal CA, certificate renewal.
  • Secretsruntime/.env, signing keys (runtime/jwks/), API tokens, admin passwords.
  • OS packages — Node.js, pnpm, openssl, database client tooling, cosign.
  • Bootstrap admin — create the first administrator via /auth/register, then promote.

The release notes for every version list the exact migration command (if any) and any breaking changes.

/opt/parako-id/
├── current → /opt/parako-id/releases/v0.2.0/ (atomic mv -T swap)
├── releases/
│ └── v0.2.0/
│ ├── dist/, node_modules/, package.json, public/, contrib/
│ └── runtime → ../../runtime (relative symlink)
├── runtime/ (operator-managed)
│ ├── .env (you create from contrib/.env.sample)
│ ├── jwks/ (only for file-backed key storage)
│ ├── parako-rp.jsonc (your OIDC client registry)
│ ├── data/, uploads/, logs/, backups/, config-backups/ (operator data)
│ └── locales/, views/ (populated on first install only)
├── .parako-state (0644, no secrets)
└── .install-lock

Point your supervisor’s WorkingDirectory (systemd) or cwd (PM2) at /opt/parako-id/current.

Copy the shipped samples into your operator-owned runtime/ tree, edit .env, and (for file-backed key storage only) generate runtime/jwks/jwks.json with jose/openssl. The default DB-backed key store does not require it. See Configuration and Deployment for env-var and supervisor/nginx/TLS reference.

Terminal window
sudo cp /opt/parako-id/current/contrib/.env.sample /opt/parako-id/runtime/.env
sudo cp /opt/parako-id/current/contrib/parako-rp.sample.jsonc /opt/parako-id/runtime/parako-rp.jsonc
sudo $EDITOR /opt/parako-id/runtime/.env
Terminal window
parako update # latest stable
parako update --version v0.2.1 # pin

See Upgrades for the full operator runbook (read notes → backup DB → dry-run → apply → migrate → restart → verify → rollback). Pre-change-window rehearsals:

ModeNetworkDownload + verifyINSTALL_DIR writes
parako update --plannonono
parako update --dry-runyesyesno
parako update (real)yesyesyes (after confirmation)
Terminal window
parako rollback # previous release
parako rollback --to v0.1.5 # specific release

Atomic re-aim of the current symlink. Application files revert.

Warning: Database migrations are NOT reversed. See Upgrades → Rollback for the decision tree.

Terminal window
parako gc # preview
parako gc --keep 3 --yes # apply

Two releases are protected unconditionally: the currently-pointed release and the previous one. --keep N (default 3) retains N more from the deletable set. GC never touches runtime/ — including runtime/backups/, runtime/logs/, and runtime/uploads/.

Terminal window
parako doctor # human-readable
parako doctor --json # structured output

Reports file/config sanity only: resolves current, confirms dist/src/index.js exists, warns on missing runtime/.env, lists the releases on disk. Doctor does NOT call systemctl, pm2, curl /health, or any database client. Use your own tooling for service / DB / health probing.

The installer itself must already be on the air-gapped host. On a connected machine:

Terminal window
VERSION=v0.2.0
curl --proto '=https' --tlsv1.2 -fsSL https://get.parako.id/install.sh -o install.sh
gh release download "$VERSION" -R Dahkenangnon/Parako.ID \
-p "parako-id-${VERSION}.tar.gz" \
-p "parako-id-${VERSION}.tar.gz.sig" \
-p "parako-id-${VERSION}.tar.gz.pem" \
-p SHA256SUMS
# Also fetch a cosign binary for the air-gapped host's arch:
# https://docs.sigstore.dev/cosign/system_config/installation/

Transfer all files plus the cosign binary to the air-gapped host. On that host, with cosign on PATH:

Terminal window
sudo bash ./install.sh \
--offline --version v0.2.0 \
--tarball ./parako-id-v0.2.0.tar.gz \
--checksum ./SHA256SUMS \
--signature ./parako-id-v0.2.0.tar.gz.sig \
--certificate ./parako-id-v0.2.0.tar.gz.pem

Under --offline: --version is required; cosign must be preinstalled (the installer refuses to fetch it); cosign verification still runs against the supplied files.

Terminal window
curl --proto '=https' --tlsv1.2 -fsSL https://get.parako.id -o /tmp/install.sh
EXPECTED="<sha256 from the release notes>"
[ "$(sha256sum /tmp/install.sh | awk '{print $1}')" = "$EXPECTED" ] \
&& bash /tmp/install.sh --help \
|| echo "MISMATCH — DO NOT RUN"

Full chain-of-trust: Installer Security.

RequirementVersionNotes
Linuxx86_64 or aarch64Other OS / arch fails fast in preflight
bash≥ 4.0Alpine: apk add bash
GNU coreutilsany recentFor mv -T. Alpine: apk add coreutils
util-linuxany recentFor flock. Alpine: apk add util-linux
curl OR wgetany recentTLS 1.2 capable
openssl, tarany recentFor checksum verification + extraction
Free disk space≥ 2 GBVerified by preflight
Node.js, pnpmper release notesOperator-provisioned; the installer does not install them
Databaseper release notesOperator-provisioned (PostgreSQL, MongoDB, or SQLite)
Supervisorsystemd / PM2 / docker / …Operator-managed

If a preflight check fails, the installer exits with code 2 before any download or filesystem write.