Skip to main content

Getting Started

How to set up and run the backend locally for development. All commands are run from the backend/ directory of the Qlarr monorepo.

Prerequisites

  • Node.js 20+
  • Docker — for PostgreSQL (and optionally Mailhog for email testing)

Running Locally

1. Start the database:

The simplest path is the local Docker stack, which brings up PostgreSQL (and Mailhog):

cd deploy
docker compose -f docker-compose.local.yml up -d postgres-db mailhog

This starts PostgreSQL at localhost:5432 (database qlarr, user qlarr, password qlarr) and Mailhog at http://localhost:8025.

2. Configure environment:

cd ../backend
cp .env.example .env

At minimum set DB_*, JWT_SECRET (base64, decoded to the HS256 key — generate with openssl rand -base64 32), and FRONTEND_URL.

3. Run the application:

npm install
npm run start:dev # watch mode on PORT (default 8080)

Check it is up:

curl http://localhost:8080/health

4. Default admin account:

On first startup, when the users table is empty, a default admin is seeded:

  • Email: admin@admin.admin
  • Password: the value of SEED_ADMIN_PASSWORD (default admin)
  • Roles: all roles

Disable the seeder with SEED_ADMIN_USER=false.

5. (Optional) Email testing with Mailhog:

With MAIL_HOST=localhost / MAIL_PORT=1025 (the defaults in .env.example), outbound mail is captured by Mailhog and viewable at http://localhost:8025. Leave MAIL_HOST empty to log emails instead of sending them.

Building

npm run build

Running Tests

npm run test:unit # fast, no Docker
npm run test:int # integration — spins up a real Postgres via Testcontainers (needs Docker)
npm run test:e2e # end-to-end app boot

test:int and test:e2e require a running Docker daemon — Testcontainers throws away a real Postgres per run, the only faithful coverage for the SQL-level parts (native queries, JSONB, the response-index trigger).

Configuration Reference

Key environment variables (see .env.example for the full list):

VariableDescription
PORTHTTP port (default 8080)
DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORDPostgreSQL connection
DB_SSLtrue for managed Postgres (e.g. RDS); false for local
JWT_SECRETBase64 secret decoded to the HS256 HMAC key
JWT_ACTIVE_EXPIRATION_MS / JWT_REFRESH_EXPIRATION_MSAccess / refresh token lifetimes (ms)
FRONTEND_URLPublic frontend base URL, used to build links in outbound emails
SEED_ADMIN_PASSWORDPassword for the seeded admin@admin.admin user
FILE_SYSTEM_ROOT_FOLDERRoot of local file storage (use an absolute path on a persistent, shared volume)
MAIL_HOST / MAIL_PORT / MAIL_USERNAME / MAIL_PASSWORDSMTP settings (nodemailer)
ENGINE_WORKERS / ENGINE_POOL_SIZE / ENGINE_TIMEOUT_MSSurvey-engine Piscina worker pool tuning