@nexploy/cli
v0.2.1
Published
Recovery CLI for self-hosted Nexploy instances — acts directly on the server database using the recovery key generated at install time.
Downloads
471
Readme
@nexploy/cli
Recovery CLI for self-hosted Nexploy instances.
It runs on the server, as root, and talks directly to the instance's Postgres database — not through the Nexploy web app. This means it still works if the app itself is down, misconfigured, or its admin password is lost.
Install
npm install -g @nexploy/cliSetup
Nothing to configure: nexploy-cli reads the Postgres password and address
directly from the running nexploy_postgres container via docker inspect
— nothing is stored on disk for that. Requires Docker access (it runs as
root on the same machine as Nexploy).
The only thing read from disk is /etc/nexploy/cli.env, written by
Nexploy's install.sh, which holds just the recovery key hash (a
non-reversible SHA-256, not a plaintext secret). Override its location with
NEXPLOY_DIR if Nexploy was installed elsewhere.
Every command requires the recovery key shown once when Nexploy was
installed (or after running rotate-cli-key, if it was lost). You'll be
prompted for it, or pass it non-interactively via the NEXPLOY_CLI_KEY
environment variable.
If you lost the recovery key, generate a new one on the server:
curl -fsSL https://nexploy.app/install.sh | sh -s rotate-cli-keyCommands
nexploy admin reset-password [--email <email>]
Resets a user's password to a freshly generated random one, and revokes all
of their active sessions. Without --email, targets the single user with the
admin role — pass --email if there's more than one admin, or to target a
non-admin account.
sudo nexploy admin reset-passwordnexploy security unpublish-database [--dry-run] [--skip-backup] [-y]
Instances installed before v0.1.9 published Postgres on 127.0.0.1:5432.
The binding is loopback-only, so it was never reachable from the network, but
nothing needs it: the app connects over the Docker network
(nexploy_postgres:5432) and this CLI connects to the container's bridge IP.
This command removes the published port by recreating nexploy_postgres with
the exact same image, environment, networks, labels, healthcheck and restart
policy — minus the --publish. The named volume is reattached, so no data
is lost. nexploy_app is stopped before and started again after.
sudo nexploy security unpublish-database --dry-run # show the plan only
sudo nexploy security unpublish-databaseA pg_dump is written to <NEXPLOY_DIR>/<db>-pre-unpublish-<timestamp>.dump
(0600) first, unless --skip-backup is passed. The command aborts before
touching anything if the dump fails, if the data lives in an anonymous
volume, or if the container is managed by Docker Compose — in that last case
it prints the docker compose up -d --force-recreate steps to use instead.
Re-running it once the port is gone is a no-op.
Audit log
Every admin and security action (success or failure — invalid key, user not found, etc.)
is appended as a JSON line to <NEXPLOY_DIR>/cli-audit.log (default
/etc/nexploy/cli-audit.log), root-only (0600). Each entry records a
timestamp, host, OS user, action, outcome, and target — never the generated
password itself.
Development
Reads and writes go through a Prisma client, but
prisma/schema.prisma declares no models — this package doesn't own the
Nexploy schema and must not duplicate it. It only uses $queryRaw/
$executeRaw (tagged templates, so values are parameterized, not
string-concatenated) against the same database.
npm install # also runs `prisma generate` via postinstall
npm run dev -- admin reset-password
npm run build # regenerates the Prisma client, then bundles with tsupReleasing
Publishing to npm happens in CI (.github/workflows/publish.yml) via trusted
publishing (OIDC, no stored token) whenever a v* tag is pushed:
npm version patch # or minor/major
git push --follow-tags