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(defaultadmin) - 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):
| Variable | Description |
|---|---|
PORT | HTTP port (default 8080) |
DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD | PostgreSQL connection |
DB_SSL | true for managed Postgres (e.g. RDS); false for local |
JWT_SECRET | Base64 secret decoded to the HS256 HMAC key |
JWT_ACTIVE_EXPIRATION_MS / JWT_REFRESH_EXPIRATION_MS | Access / refresh token lifetimes (ms) |
FRONTEND_URL | Public frontend base URL, used to build links in outbound emails |
SEED_ADMIN_PASSWORD | Password for the seeded admin@admin.admin user |
FILE_SYSTEM_ROOT_FOLDER | Root of local file storage (use an absolute path on a persistent, shared volume) |
MAIL_HOST / MAIL_PORT / MAIL_USERNAME / MAIL_PASSWORD | SMTP settings (nodemailer) |
ENGINE_WORKERS / ENGINE_POOL_SIZE / ENGINE_TIMEOUT_MS | Survey-engine Piscina worker pool tuning |