macOS Install
This path creates a local SeqDesk evaluation instance. SeqDesk reuses a
PostgreSQL server you already run, or creates and owns its own — Homebrew
PostgreSQL is not a prerequisite. It binds the app to 127.0.0.1, so the
bootstrap login is not reachable from other machines on your network.
Quick start
Install Node.js with Homebrew. You do not have to install or start PostgreSQL:
the installer reuses a healthy PostgreSQL 14 or newer server when it finds one,
and otherwise creates its own socket-only instance under ~/.seqdesk/postgres
(see SeqDesk manages its own PostgreSQL):
brew install node@24
export PATH="$(brew --prefix node@24)/bin:$PATH"SeqDesk supports Node.js 22.13.0 through 22.x and Node.js 24.x. The commands
above deliberately pin Node.js 24; unversioned Homebrew Node may move to an
unsupported future major. Do not run Homebrew PostgreSQL services with sudo.
Download the installer, then start the guided setup in a new directory:
curl -fsSLo /tmp/seqdesk-install.sh https://seqdesk.org/install.sh
SEQDESK_BIND_HOST=127.0.0.1 bash /tmp/seqdesk-install.sh --interactive \
--dir "$HOME/seqdesk"The wizard asks which PostgreSQL database to use and lets you create the first
administrator account. Fresh installs skip Conda/Nextflow and install the core
application only. Add --with-pipelines if this Mac should run bioinformatics
pipelines too. When pipelines are enabled, the installer reuses a working Conda
base at a standard user path even when conda is not on PATH; otherwise it
provisions Miniconda.
The install directory must not already exist. If ~/seqdesk is already an
installed instance, use --reconfigure; if it is unrelated, choose another
directory. --overwrite-existing backs up and replaces the directory and
should only be used intentionally.
Migrating from the previous macOS command
Older instructions installed Homebrew’s unversioned Node.js formula and started PostgreSQL manually. You do not need to uninstall PostgreSQL, recreate its database, or reinstall SeqDesk just because the recommended command changed.
First check which Node.js and PostgreSQL installations are actually active:
command -v node
node --version
npm --version
brew services list | grep postgresqlKeep an active Node.js >=22.13.0 <23 or 24.x installation, whether it comes
from Homebrew or a version manager such as nvm. Keep any healthy PostgreSQL
14 or newer service; the installer reuses it. If you have none, do nothing — the
installer no longer expects a Homebrew postgresql@16 service and will create
its own instance under ~/.seqdesk/postgres.
If SeqDesk is already installed, keep its current directory. The previous
installer defaulted to ./seqdesk relative to the directory where it was run,
so do not assume the existing path is ~/seqdesk. Upgrade the launcher, then
verify the existing installation:
npm i -g seqdesk@latest
seqdesk doctor --dir "/absolute/path/to/your/seqdesk"If you also need to apply the local-only bind or another configuration change, use reconfigure mode:
SEQDESK_BIND_HOST=127.0.0.1 seqdesk -y --reconfigure \
--dir "/absolute/path/to/your/seqdesk"
seqdesk doctor --dir "/absolute/path/to/your/seqdesk"--reconfigure reapplies configuration to the installed release; it
deliberately skips the release download and is not an application update. Update
the application from Admin → Settings → Software Updates. See
Manual Update & Rollback for
the application update and rollback flow. Do not run a fresh install over the
existing directory.
SeqDesk supports PostgreSQL 14–18, so changing PostgreSQL major versions is not required for this command migration. If you choose to change major versions, make and verify a database backup first, then follow PostgreSQL’s major-version upgrade guide . Do not delete or reinitialize the old data directory as a troubleshooting step.
Verify and sign in
The installer prints the exact browser and diagnostic URLs when it finishes. For the default port:
npx -y seqdesk@latest doctor --dir "$HOME/seqdesk" --url http://127.0.0.1:8000
open http://127.0.0.1:8000Sign in with the administrator account created by the wizard. If you used unattended defaults instead, change or remove the bootstrap accounts immediately before allowing another machine to reach the service.
SeqDesk manages its own PostgreSQL
SeqDesk never fights the database your Mac already runs. Before installing, it works down a ladder and stops at the first rung that works:
- A healthy PostgreSQL on the configured connection — reused untouched.
- A healthy PostgreSQL on a local Unix socket it can administer — reused untouched, even when loopback TCP is blocked.
- A Homebrew PostgreSQL service that is installed but idle — started once.
- Nothing usable — SeqDesk creates its own instance, provided you run the installer as your normal login user.
Run the installer as yourself, never with sudo: SeqDesk refuses to create a
PostgreSQL instance owned by root, because PostgreSQL would not start. The same
applies when a local server answers on a socket owned by another account — a
system PostgreSQL, for example. SeqDesk will not send generated credentials to a
server it does not own; supply an explicit --database-url instead.
The instance it creates is deliberately unobtrusive:
| Location | ~/.seqdesk/postgres (override with SEQDESK_PG_HOME; keep it short — macOS caps Unix-socket paths, so a socket directory over 85 characters stops the install with an error asking for a shorter path) |
| Network | None. It listens on a Unix socket only, so no TCP port is opened |
| Access | Your login account authenticates by peer; the application role uses a generated password |
| Service | Not registered with launchd. SeqDesk’s start.sh starts it, so it comes back with the app |
| Size | About 50 MB for a fresh, empty cluster |
Because it is socket-only, it is unaffected by VPNs or endpoint-security tools
that filter loopback traffic, and it cannot collide with a PostgreSQL you
already run on port 5432.
If you supply --database-url, none of this happens — SeqDesk uses the database
you named and never creates one behind your back.
Reinstalling SeqDesk reuses an existing instance rather than rebuilding it, so your data survives. To remove it completely after uninstalling SeqDesk:
pg_ctl -D "$HOME/.seqdesk/postgres/data" -m fast stop
rm -rf "$HOME/.seqdesk/postgres"Troubleshooting
Rerun the installer with --verbose (or SEQDESK_VERBOSE=1) to promote its
diagnostic narration from the log to the terminal — that is what shows each
PostgreSQL rung as it is tried. Either way the full transcript is written to
/tmp/seqdesk-install-<timestamp>.log (override with SEQDESK_LOG), and the
installer prints that path when it stops.
Miniconda reports that the prefix already exists
The current installer checks ~/miniconda3 directly, so a working installation
there is reused even when conda is not on PATH. If the directory exists but
is incomplete, it is preserved and Miniconda is installed into the separate
~/seqdesk-miniconda3 fallback. Do not delete the original directory merely to
retry.
"$HOME/miniconda3/bin/conda" --versionFor explicit-path recovery and the case where both locations already exist, see Conda-prefix recovery.
Homebrew prints Node.js Caveats
These messages are informational:
Single Executable Application is disabled as it doesn't work with shared libnode.
Temporal support is disabled as it doesn't work with shared ICU library.SeqDesk does not require either optional Node.js feature. Continue when
node --version reports a supported release and npm --version succeeds.
Homebrew says node, npm, or npx is shadowed
Homebrew found another Node.js installation earlier in PATH. Running those
commands will use the reported installation, not the newly installed Homebrew
formula. This is fine when the active version is supported—for example, an
nvm Node.js 24.x installation.
command -v node
node --version
npm --versionIf the active version is unsupported, either select Node.js 24 with your version manager:
nvm install 24
nvm use 24Or put Homebrew’s versioned Node.js first for the current shell:
brew install node@24
export PATH="$(brew --prefix node@24)/bin:$PATH"
hash -rHOMEBREW_NO_PATH_SHADOW_CHECK=1 only hides the warning; it does not change
which executable runs. Avoid brew link --force, which changes Homebrew links
globally.
Homebrew cleanup removed an older Node.js directory
Homebrew normally removes older versions of a formula during cleanup. This does
not remove Node.js versions managed under ~/.nvm, the SeqDesk installation, or
PostgreSQL data. Recheck command -v node and node --version; continue when
the active version is supported. Use node@24, not the unversioned node
formula, when installing Node.js specifically for SeqDesk.
PostgreSQL fails with launchctl bootstrap ... exited with 5
This is a generic macOS service-registration failure, not a request to run
PostgreSQL as root. Common causes include a stale root service from an older
sudo brew services start command, an already registered service, a root-owned
log, another PostgreSQL server on port 5432, or a data-directory error.
Inspect the current state first:
brew services list | grep postgresql
brew services info postgresql@16
"$(brew --prefix postgresql@16)/bin/pg_isready" -h 127.0.0.1 -p 5432
lsof -nP -iTCP:5432 -sTCP:LISTEN
tail -n 50 "$(brew --prefix)/var/log/postgresql@16.log"If the installer reports PostgreSQL 16 as a stale root service or Homebrew shows
it as root with error 78, unregister only that service:
sudo brew services stop postgresql@16
brew services stop postgresql@16If another PostgreSQL 14 or newer service is already healthy, keep using it and
rerun the SeqDesk command—the installer will reuse it. Otherwise just rerun the
SeqDesk command: when it finds no healthy, non-root server it starts an
already-registered Homebrew service or, failing that, creates and starts its own
socket-only instance under ~/.seqdesk/postgres with pg_ctl. You do not need
to run brew services start postgresql@16 yourself.
If Homebrew reports an older service as started and lsof shows a PostgreSQL
listener, test that exact version before changing any files:
"$(brew --prefix postgresql@14)/bin/pg_isready" -h 127.0.0.1 -p 5432
head -n 1 "$(brew --prefix)/var/postgresql@14/postmaster.pid"A postmaster.pid belonging to the live listener is not stale—do not delete it.
Also check the timestamps on log errors: old lock file "postmaster.pid" already exists lines may describe a previous restart attempt rather than the current
failure.
PostgreSQL Unix socket works but TCP does not
The installer handles this on its own — as long as you let it choose the
database. When loopback TCP does not answer but a local Unix socket does,
SeqDesk reuses that socket and writes a socket-based DATABASE_URL. It changes
no PostgreSQL configuration and starts no second server.
The one exception is an explicit --database-url (or SEQDESK_DATABASE_URL).
SeqDesk never silently retargets a URL you chose: it reports the problem and
stops, so that a database you named is never quietly swapped for another. To use
the working socket, name it yourself with a host= parameter:
postgresql://USER:PASSWORD@localhost:5432/DATABASE?schema=public&host=%2FtmpThis situation is common on managed Macs, where a VPN or endpoint-security tool intercepts loopback connections: the port accepts a TCP handshake, but the PostgreSQL protocol never completes. An open port is therefore not proof that PostgreSQL is healthy — compare the two probes:
"$(brew --prefix postgresql@14)/bin/pg_isready" -h 127.0.0.1 -p 5432 # may say: no response
"$(brew --prefix postgresql@14)/bin/pg_isready" -h /tmp -p 5432 # accepting connectionsThe rest of this section is for restoring TCP access when you want it for other tools. It is not a prerequisite for SeqDesk.
First identify which process and Homebrew service own port 5432. Do not start
a second PostgreSQL major version on the same port:
lsof -nP -iTCP:5432 -sTCP:LISTEN
brew services list | grep postgresqlUse the working Unix socket to ask that running server which configuration files
and TCP settings it actually uses. Replace postgresql@14 below if the listener
belongs to another supported version:
PG_BIN="$(brew --prefix postgresql@14)/bin"
"$PG_BIN/psql" -h /tmp -d postgres -Atc \
"show server_version; show port; show listen_addresses; show config_file; show hba_file;"The reported listen_addresses must include localhost, 127.0.0.1, or *.
The active pg_hba.conf must permit loopback clients. A local-only baseline is:
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256Keep these rules restricted to loopback; do not expose PostgreSQL port 5432
to the network. Restart the one active Homebrew service after changing
listen_addresses, or reload PostgreSQL after changing only pg_hba.conf.
Then require this probe to pass:
"$PG_BIN/pg_isready" -h 127.0.0.1 -p 5432If the active configuration is already correct, nc can open the port, and
pg_isready still says no response, a VPN or institutional endpoint-security
tool may be filtering PostgreSQL protocol traffic on loopback. Check its local
network policy or ask the system administrator to allow the active PostgreSQL
process on 127.0.0.1:5432; do not disable organization-managed protection or
weaken pg_hba.conf as a workaround.
None of this is required to install SeqDesk when you let it choose the database
— it reuses the working socket. With an explicit --database-url, either drop
the flag or point the URL at the socket as shown above. Fix TCP only if other
tools need it. The installer deliberately does not treat a successful TCP
handshake alone as database readiness.
Never use sudo brew services start for PostgreSQL. If SeqDesk identifies one
specific log file as non-writable, run only the exact chown command it prints;
do not recursively change ownership of Homebrew or PostgreSQL directories. The
installer stops before downloading SeqDesk or creating the target directory
when this preflight fails, so it is safe to repair the service and rerun the
same install command.
PostgreSQL is already listening on port 5432
The installer checks local PostgreSQL before downloading the SeqDesk application.
On a clean Mac it creates its own PostgreSQL instance under
~/.seqdesk/postgres, which listens on a private Unix socket only — it never
opens port 5432 and is never registered with launchd, so it cannot collide
with a PostgreSQL you already run. If a supported server is already ready, the
installer reuses it. You can also point it at an existing database with a
connection string. See
Prerequisites for the PostgreSQL options and
Quickstart for the full flow.
brew services list | grep postgresql
lsof -nP -iTCP:5432 -sTCP:LISTENDo not start a second PostgreSQL major on the same port. Keep the healthy supported service, or stop only the redundant formula after confirming it does not contain the database you need.
The target directory already exists
Use the update path above when the directory is an existing SeqDesk
installation. If it is unrelated, choose another directory. Use
--overwrite-existing only when you intentionally want the installer to back up
and replace the directory.
SeqDesk installed, but the browser does not open
Check the installation and process before reinstalling:
seqdesk doctor --dir "$HOME/seqdesk" --url http://127.0.0.1:8000
pm2 status
pm2 logs seqdesk --lines 100An instance bound to 127.0.0.1 is reachable only from the same Mac. Use the
exact install directory and URL printed by the installer if you changed either
default.
After a reboot
The completion summary tells you whether PM2 startup was enabled. Check the process and restart it when needed:
pm2 status
pm2 restart seqdeskA PostgreSQL instance SeqDesk created for itself is deliberately not a launchd
service. ~/seqdesk/start.sh starts it with pg_ctl before launching the app,
so PM2 restarting SeqDesk brings the database back too. Always start the app
through that wrapper rather than current/start.sh directly, or the database is
never started. If the app cannot reach its database after a reboot, check
~/.seqdesk/postgres/server.log — the wrapper names that file when pg_ctl
fails.
If startup is not enabled, follow the pm2 startup and pm2 save commands shown
by the installer. See First Login & Setup
before making the instance available to other users.