pm2 is the recommended supervision method for bare-metal or VM deployments where Docker is not used. It restarts Hashboard on crash, persists the process list across reboots, and reads configuration fromDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/cryguy/hashboard/llms.txt
Use this file to discover all available pages before exploring further.
ecosystem.config.cjs checked into the repository. Migrations are applied automatically at boot — there is no separate migration step.
Deployment
Install Node.js and pm2
Hashboard requires Node.js 24 or later. Install pm2 globally and run the startup hook once so pm2 survives reboots:
pm2 startup prints a command to run as root (or with sudo) that registers pm2 with your init system. Run that command before continuing.Clone the repository and configure .env
.env and set the values for your deployment. At minimum, set ORIGIN to your public URL and uncomment ADDRESS_HEADER and XFF_DEPTH if you are behind a reverse proxy:.env.example for all available options.Install dependencies and build
build/ and prunes dev dependencies. The compiled better-sqlite3 native binding is kept in place.Start under pm2
ecosystem.config.cjs, starts build/index.js with --env-file=.env, and begins supervising the process. Migrations are applied on first boot and on every subsequent restart where new migration files are present.ecosystem.config.cjs reference
Theecosystem.config.cjs file checked into the repository is the authoritative pm2 configuration for Hashboard:
cwd: __dirname ensures that a relative DATABASE_URL in .env (such as local.db) resolves to the repository root, not wherever pm2 was invoked from. Do not change this to an absolute path unless you also update DATABASE_URL.
Health check endpoint:
GET /api/v1/health is unauthenticated by design and always returns 200 OK when the process is up. Use it as the target for uptime monitors, load balancer health checks, or any external watchdog. It does not require a session cookie or bearer token.Deploying an update
A production deploy consists of the following files — copy them to the target and runnpm ci --omit=dev there. Migrations apply automatically when the process restarts.
drizzle/ directory contains the committed SQL migration files. The runtime migrator reads them at boot, so the production install carries its own migrations without needing dev dependencies like drizzle-kit.
Monitoring and logs
pm2 save, the process is automatically restarted by the init system on reboot. If the process crashes more than max_restarts times in a short window (default: 10), pm2 stops restarting it and marks the process as errored — check pm2 logs hashboard to diagnose the cause before restarting manually with pm2 restart hashboard.