seqdesk doctor
seqdesk doctor is a diagnostic subcommand of the seqdesk npm
launcher. It walks an installed SeqDesk
directory and prints a pass/warn/fail report covering the install layout, the
runtime configuration, the database connection, and (if a URL is supplied) a
small set of HTTP probes against the running app.
It does not modify anything. Run it as often as you like — after install, after an update, or whenever the app behaves oddly.
Usage
seqdesk doctor [--dir /path/to/seqdesk] [--url http://127.0.0.1:8000] \
[--timeout-ms 5000] [--json] [--help]| Flag | Default | Description |
|---|---|---|
--dir, -d | current directory | Installed SeqDesk directory |
--url, -u | inferred from config | Running SeqDesk base URL for HTTP probes |
--timeout-ms | 5000 | Timeout for PostgreSQL TCP and HTTP checks |
--json | off | Print machine-readable JSON instead of text |
--help, -h | — | Show usage and exit |
If --url is not supplied, doctor tries to derive one from
runtime.nextAuthUrl (or app.port) in seqdesk.config.json. If neither is
set, the HTTP checks are skipped with a warning.
Checks
Install layout
| Check | Notes |
|---|---|
| Install directory | Path resolves and exists |
package.json | Parseable; reports name@version |
settings.json / seqdesk.config.json | Uses settings.json when present, with seqdesk.config.json as the legacy fallback; the selected file must contain valid JSON |
start.sh | Present and executable |
node_modules | Present in the active current/ release (or install root for legacy/source installs) |
.next/static | Present in the active release (warns if .next exists without static assets) |
Pass the installation root to --dir, not the current/ symlink. Distribution
installs keep shared configuration at the root and immutable application files
under current/; doctor checks both locations automatically.
Runtime configuration
Read from seqdesk.config.json (runtime.* section, with flat-key fallbacks):
| Check | Status logic |
|---|---|
runtime.databaseUrl | Must parse as a valid PostgreSQL URL |
| PostgreSQL TCP | TCP connect to the URL’s host:port (default port 5432) |
runtime.directUrl | Optional; warns if missing (falls back to databaseUrl) |
runtime.nextAuthUrl | Warns if missing |
runtime.nextAuthSecret | Fails if missing |
telemetry | Pass when telemetry.enabled === true, warn otherwise (informational only) |
Known limitation: socket-only databases
The PostgreSQL TCP check opens a TCP socket to the URL’s host and port. It has
no Unix-socket mode, so it cannot verify a database reached through a socket
directory — which is exactly what an install with a SeqDesk-managed cluster (or
a reused local socket) uses. Those installs carry a URL such as:
postgresql://seqdesk:...@localhost:5432/seqdesk?schema=public&host=%2FUsers%2Fyou%2F.seqdesk%2Fpostgres%2FsocketDoctor probes localhost:5432, finds no listener, and reports
error PostgreSQL TCP - localhost:5432 unreachable, which makes the whole run
exit 1 even though the installation is healthy. Verify a socket-based database
directly instead:
PGROOT="${SEQDESK_PG_HOME:-$HOME/.seqdesk/postgres}"
pg_ctl -D "$PGROOT/data" status
pg_isready -h "$PGROOT/socket"Every other check in the same report — layout, configuration, and the HTTP
probes, including /api/setup/status, which exercises the real application
database connection — stays meaningful. Do not treat this single failure as a
reason to recreate the database or reinstall. Because of it, do not gate CI on
doctor’s exit code for socket-based installs; use --json and inspect the
individual checks, or gate on /api/setup/status.
HTTP probes (when a URL is available)
| Check | What it expects |
|---|---|
GET /api/auth/providers | JSON response with a credentials provider |
GET /api/setup/status | configured: true (passes); exists: true warns; otherwise fails |
When a URL was inferred (not passed via --url), an unreachable endpoint is
reported as a warn, since the app may simply not be running. When --url
was passed explicitly, the same failure is reported as a fail.
What doctor does not check
A clean doctor report means “the layout is intact, the configuration parses, and the app answers” — not “this installation is fit for production”. The full list of checks is above; everything below is outside it and needs its own verification.
| Not covered | Verify instead with |
|---|---|
Database credentials and write access. The PostgreSQL TCP probe opens a socket and closes it. It never authenticates, never runs a query, and never checks that the role can write. | The HTTP /api/setup/status line, which exercises the real application connection — but only when a URL is available. |
| Whether migrations were applied. Doctor does not inspect the schema. | GET /api/setup/status, which reports schema-missing and not_seeded phases. |
Whether anyone can sign in. GET /api/auth/providers proves the credentials provider is wired up, not that a single account exists or that you know its password. | Sign in. If you cannot, see Reset a password. |
| Sequencing data storage. Doctor does not inspect path accessibility, mount identity, or free capacity. | Run seqdesk storage status or use Settings → Infrastructure → Open Data Storage to verify path access and reported writability. Confirm the intended mount and available capacity separately with host tools such as findmnt/mount and df -h. |
The pipeline toolchain. Conda, Java, Nextflow, and Slurm reachability are not probed at all, even on a --with-pipelines install. | Settings → Infrastructure → Open Pipeline Runtime, and a small test run — see Running a pipeline. |
| ENA credentials. Webin username, password, and broker permissions are never contacted. | The connection test on ENA credentials. |
| Network exposure. The bind address, reverse proxy, TLS, and firewall are not inspected; a passing local HTTP probe says nothing about what is reachable from elsewhere. | curl from another host, plus your own firewall review. |
| Backups. Nothing about backup existence or restorability. | Updates & Maintenance. |
Doctor is also read-only by design: it never repairs, migrates, restarts, or rewrites anything it finds wrong.
Output
Text (default)
SeqDesk doctor
Version: 1.1.x
Directory: /opt/seqdesk
URL: http://127.0.0.1:8000
Checks
Install directory: /opt/seqdesk
package.json: seqdesk@1.1.x
settings.json: parseable
start.sh: executable
node_modules: present in current release
.next/static: present in current release
runtime.databaseUrl: postgresql://seqdesk@127.0.0.1:5432/seqdesk
PostgreSQL TCP: 127.0.0.1:5432 reachable
warning runtime.directUrl - missing; databaseUrl will be used as fallback
runtime.nextAuthUrl: http://127.0.0.1:8000
runtime.nextAuthSecret: set
warning telemetry - disabled
HTTP /api/auth/providers: credentials auth available
HTTP /api/setup/status: database configured
Summary
Passed: 12
Warnings: 2
Errors: 0Pass checks render as name: detail. Warnings render as
warning name - detail and failures render as error name - detail.
JSON (--json)
The same data, structured for scripts:
{
"version": "1.1.x",
"installDir": "/opt/seqdesk",
"appUrl": "http://127.0.0.1:8000",
"checks": [
{ "name": "Install directory", "status": "pass", "detail": "/opt/seqdesk" }
],
"summary": { "pass": 12, "warn": 2, "fail": 0 }
}Exit codes
| Code | Meaning |
|---|---|
0 | No failed checks (warnings allowed) |
1 | At least one check failed |
2 | Invalid command-line arguments |
This makes doctor safe to run in CI and post-install hooks — wire it as a
non-zero gate without parsing the text output, except on an installation whose
database is reached over a Unix socket, where the
TCP-check limitation makes exit 1
the normal result. Gate those on --json plus a per-check inspection instead.
Acting on failures
Doctor is read-only and identifies the failing layer; it does not repair or migrate the installation.
| Failed check | Next action |
|---|---|
Install directory, package.json, start.sh, node_modules, or .next/static | Confirm --dir is the installation root, not current/. Inspect the active symlink and release directory before replacing anything. Do not delete the working previous release. |
settings.json / seqdesk.config.json | Validate the selected JSON and reapply known-good values with --reconfigure. Do not print the file when collecting logs because it can contain database and authentication secrets. |
runtime.databaseUrl or runtime.directUrl | Correct the PostgreSQL URL shape. For pooled providers, keep a separate direct migration URL. |
| PostgreSQL TCP | First confirm the URL is not socket-based: if databaseUrl carries an absolute host= parameter, this failure is the known limitation, not a fault. Otherwise check the database service, hostname, port, DNS, firewall, and routing. This probe checks TCP reachability, not credentials or write permission; use the installer or /api/setup/status for the full application connection. |
| HTTP endpoints | Check the process manager and application logs, then retry curl locally. A local success with a remote failure points to bind, proxy, firewall, or routing configuration. |
runtime.nextAuthSecret | Restore the secret from your secret store and reapply the configuration. Do not generate a replacement casually on an active shared instance because it invalidates existing sessions. |
After correcting the reported layer, rerun the same doctor command. Use the Quickstart troubleshooting checklist for host installs, or the platform-specific sections for Linux, macOS, and AWS EC2.
When to run it
- After a fresh install — confirm the layout is intact and the database is reachable before logging in for the first time.
- After an update — see Automatic Updates. If the app fails to come back up, doctor narrows the failure to layout, DB, or HTTP.
- In CI — run
seqdesk doctor --jsonagainst a freshly provisioned instance to validate the install pipeline. - When troubleshooting — failures point at exact files and ports, which is usually faster than reading the app logs from scratch.
Manual install checklist
The seqdesk npm tarball ships a
MANUAL_INSTALL.md
checklist that walks through provisioning a fresh Linux machine, installing
SeqDesk, starting the app, running doctor, verifying telemetry, and cleaning
up. Use it for end-to-end manual smoke tests
before relying on a new host.