Deployment
The local deployment uses four services:
postgres: PostgreSQL 17 with a persistent named volume;api: Spring Boot application published on port8989;backend: static Vite build served by Nginx on port5173.docs: MkDocs site published on port8000.
Start the Stack
make docker-up
After startup:
- Documentation:
http://localhost:8000 - API health:
http://localhost:8989/actuator/health - Swagger UI:
http://localhost:8989/swagger-ui.html - Management console:
http://localhost:5173
The local Compose file supplies a development administrator account and JWT secret. The default console login is admin / admin.
Inspect service logs with:
make docker-logs
Stop containers while retaining PostgreSQL data:
make docker-down
Persistence Behavior
The API persists BadgeEntity rows in badges. The Compose volume is named from the project and the declared postgres-data volume; Docker Compose resolves the final volume name automatically.
The API also persists local authentication data in auth_roles, auth_users, and auth_user_roles. At startup it seeds the ADMIN and USER roles, then forces the administrator account from APP_ADMIN_USERNAME and APP_ADMIN_PASSWORD. If that username already exists, the account is enabled, its password hash is replaced from the environment value, and the ADMIN role is guaranteed.
Hibernate uses ddl-auto: update. This is convenient for the example because it initializes badges, but it does not remove obsolete schema objects. A volume created by an earlier version may therefore still contain badge_records. That table is unused and its presence does not indicate that the current application writes to it.
Reset the Demo Database
Reset the volume when you want to remove all demo data and obsolete tables. This operation is destructive.
docker compose -f docker/compose.yml down --volumes
make docker-up
The second command creates a fresh PostgreSQL volume and Hibernate recreates badges on API startup.
Build Documentation and Slides
make docs-build
make presentation-build
Production Considerations
Keep the API, database, console, and documentation as independently deployable units. Replace ddl-auto: update with versioned migrations, provide managed PostgreSQL credentials through secrets, terminate TLS at the platform edge, and set the console API base URL to the public API origin.
Provide these security variables through the deployment secret store:
| Variable | Required | Purpose |
|---|---|---|
APP_ADMIN_USERNAME |
Yes | Forced administrator username. |
APP_ADMIN_PASSWORD |
Yes | Forced administrator password, stored only as a BCrypt hash. |
APP_JWT_SECRET |
Yes | JWT HMAC signing secret, at least 32 characters. |
APP_JWT_EXPIRATION_SECONDS |
No | Access token lifetime; defaults to 3600 seconds. |