Run it on your computer
This page gets the API, the database and the web app running on your own machine for development. You need the source code (the repository, or the source/ folder of the source package).
What you need
- Docker with Compose v2. Enough for the database and, if you like, the API.
- Node.js and npm, for the React app.
- JDK 21 and Maven 3.9+, only if you run the API outside Docker (on macOS:
brew install openjdk@21 maven).
1. Configure the API
cd spring-admin
cp .env.example .env
Edit spring-admin/.env and set at least:
DB_PASSWORD=choose-a-local-database-password
BOOTSTRAP_EMAIL=admin@example.com
BOOTSTRAP_PASSWORD=choose-a-long-password-with-at-least-12-characters
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
BOOTSTRAP_EMAIL and BOOTSTRAP_PASSWORD create the first super administrator on first start, but only while no super administrator exists. They never overwrite an existing password. Set APP_ENCRYPTION_KEY too if you want to test password recovery, mail or payment gateway keys. All variables are listed in Environment variables.
Note:
.envis read by Docker Compose and byrun-dev.sh, not by Java or Maven on their own.
2. Start the database and API
Pick one of these ways.
Dev stack in Docker (recommended)
Runs PostgreSQL and the API from your source code, without rebuilding images:
cd spring-admin
docker compose -f compose.dev.yaml up -d # Postgres + API (dependencies downloaded once)
docker compose -f compose.dev.yaml restart api # after changing Java, SQL migrations or i18n files (~30 s)
docker compose -f compose.dev.yaml logs -f api # API log
The dev stack is its own Compose project (infotech-dev) with its own network and database. PostgreSQL is exposed on 127.0.0.1:5433 for database tools (change it with DEV_DB_PORT in .env). Stop it with docker compose -f compose.dev.yaml down; add -v only if you want to delete the dev database.
Database in Docker, API on your machine
The quickest restarts:
docker compose -f compose.dev.yaml up -d postgres
./run-dev.sh # reads .env, connects to 127.0.0.1:5433; Ctrl+C and run again after changes
Production image
docker compose up --build builds and runs the production image. Use it only to test the final container. It also uses port 8080, so stop it (docker compose down) before starting the dev stack, and the other way round.
Your own PostgreSQL
Create an empty database, then:
cd spring-admin
export DB_URL=jdbc:postgresql://localhost:5432/pos_admin
export DB_USERNAME=pos_admin
export DB_PASSWORD='your-local-database-password'
export BOOTSTRAP_EMAIL='admin@example.com'
export BOOTSTRAP_PASSWORD='your-long-local-password'
mvn spring-boot:run
The database user that runs migrations must be allowed to install the standard pg_trgm extension.
In every case Flyway creates the schema on start and the API answers on http://localhost:8080. Check it with curl http://localhost:8080/actuator/health.
3. Start the web app
In another terminal:
cd infotech-admin-web
npm install
npm run dev
Open http://127.0.0.1:5173 and sign in with BOOTSTRAP_EMAIL and BOOTSTRAP_PASSWORD. Vite proxies /api and /actuator (including the live-updates WebSocket) to http://127.0.0.1:8080, so no frontend .env is needed. Changes reload instantly.
To point the dev server at an API hosted elsewhere, copy infotech-admin-web/.env.example to .env and set VITE_API_URL=https://api.example.com.
Note: Sign-in tokens live in memory only, so a browser refresh signs you out. This is by design.
Setup wizard and license on localhost
localhost, *.test, *.local and private IP addresses count as development hosts: the license step of the setup wizard is skipped and the license guard does not lock the console. If you set BOOTSTRAP_EMAIL/BOOTSTRAP_PASSWORD, the wizard does not appear at all.
Try shop sign-up without email
Start the API with OTP_LOG_CODES=true and mail disabled. The 6-digit sign-up code is then written to the API log (docker compose -f compose.dev.yaml logs -f api) instead of being emailed. Use this only on your own machine.
Demo data
With the dev stack running:
python3 tools/seed_demo.py # separate demo shop: owner@demo.test / Demo@1234
python3 tools/seed_demo.py --email you@example.com --password 'your-password' # fill your own shop
It adds a café with menus, sizes, modifiers, stocked products with a posted opening stock, suppliers, purchases and customers. Running it again only adds what is missing. It uses psql if installed, otherwise the dev Postgres container.
For load testing, DEMO_DATA_ENABLED=true adds a Demo data button for super administrators (on every shop in Shops) and for shop owners (in the POS header). It can create a large catalogue and up to two million test sales. Never enable it in production.
Tests and formatting
API:
mvn spotless:apply # format (Google Java Format)
mvn verify # format check + tests
Integration tests need a disposable PostgreSQL database whose name ends in _test (the suite refuses any other name, because it truncates tables):
export DB_TEST_URL=jdbc:postgresql://localhost:5432/infotech_test
export DB_TEST_USERNAME=infotech_test
export DB_TEST_PASSWORD='test-database-password'
mvn verify
Without DB_TEST_URL the integration tests are skipped and the domain tests still run.
Web app:
npm run build
npm run lint
npm run format
API types for the web app are generated from the OpenAPI snapshot in spring-admin with npm ci, npm run generate:types and npm run check:types.
Kitchen printers
To test network kitchen printing, run the print agent from print-agent/ (Node.js 22) with an agent key created under Restaurant Management › Kitchen printers › Print agents:
POS_SERVER=https://pos.example.com POS_AGENT_KEY=pa_… node src/agent.mjs
Its tests run with npm test and use a fake printer and a fake server. See Kitchen stations and printers.
Related pages
Last updated 17 Oct 2026