Development Guide
1. Angular Developer Quick Start
For Angular/frontend developers who just need to run the backend services, use Docker to start everything with a single command.
1.1. Prerequisites
-
Docker Desktop installed and running
-
Node.js 18.18.2 or later
1.2. Quick Start
# 1. Install npm dependencies
npm install
# 2. Start all backend services (MySQL, Admin Service, Gateway)
npm run docker:backend:up
# 3. Start Angular dev server with hot reload
npm start
Access the application at http://localhost:9001
The backend Gateway API is available at http://localhost:12505
1.3. What Gets Started
The docker:backend:up command starts three services:
| Service | Port | Description |
|---|---|---|
MySQL |
3306 |
Database for both services |
Admin Service |
12504 |
Core business logic and APIs |
Gateway (BFF) |
12505 |
Backend-for-Frontend, routes API calls |
1.4. Docker Commands Reference
| Command | Description |
|---|---|
|
Start all backend services |
|
Stop all backend services |
|
View logs from all services |
|
Restart all backend services |
|
Stop, remove volumes, and restart (fresh database) |
1.5. Interactive Setup Script
For guided setup with port conflict detection and troubleshooting:
# Windows (PowerShell)
.\scripts\setup-backend.ps1
# macOS / Linux
./scripts/setup-backend.sh
The script will:
-
Check Docker is installed and running
-
Detect port conflicts
-
Offer to use local MySQL if one is already running
-
Pull latest images and start services
-
Display access URLs when ready
1.6. Using Local MySQL
If you have MySQL running locally and prefer to use it instead of Docker MySQL:
docker compose -f src/main/docker/dev.yml -f src/main/docker/dev-local-mysql.yml up -d --wait
Ensure your local MySQL has the required setup:
CREATE DATABASE IF NOT EXISTS `registration-ui`;
CREATE DATABASE IF NOT EXISTS `admin-service`;
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
FLUSH PRIVILEGES;
1.7. Troubleshooting
| Services won’t start |
Check Docker Desktop is running. Run |
| Port already in use |
Another service is using a required port. Use the interactive setup script for guidance. |
| Connection refused |
Wait for services to be healthy. Check status with |
| Database errors |
Reset with |
2. Prerequisites
Before building this project, install and configure the following dependencies:
2.1. Node.js and npm
Node.js is used to run a development web server and build the project. Install Node either from source or as a pre-packaged bundle for your system.
Angular CLI with Webpack is used as the build system.
npm manages CSS and JavaScript dependencies. Upgrade dependencies by specifying newer versions in package.json.
npm update
npm install
Run npm run to list all available scripts for this project.
3. Installing Dependencies
After installing Node, run the following command to install dependencies and development tools:
npm install
Run this command again when dependencies change in package.json.
3.1. Adding New Dependencies
To add a runtime dependency (example: Leaflet library):
npm install --save --save-exact leaflet
To add TypeScript type definitions from DefinitelyTyped:
npm install --save-dev --save-exact @types/leaflet
Then import the JS and CSS files in your application:
import 'leaflet/dist/leaflet.js';
@import 'leaflet/dist/leaflet.css';
4. Using Angular CLI
Use Angular CLI to generate custom client code:
ng generate component my-component
This generates:
create src/main/webapp/app/my-component/my-component.component.html
create src/main/webapp/app/my-component/my-component.component.ts
update src/main/webapp/app/app.module.ts
5. PWA Support
This application includes Progressive Web App (PWA) support, disabled by default.
To enable the service worker, uncomment the following in src/main/webapp/app/app.module.ts:
ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
6. Building for Production
6.1. Packaging as JAR
Build the optimized production JAR:
./mvnw -Pprod clean verify
This concatenates and minifies client CSS and JavaScript files and updates index.html to reference them.
Run the built application:
java -jar target/*.jar
Navigate to http://localhost:12505 in your browser.
See Using JHipster in production for more details.
7. Using Docker
Docker configurations are available in src/main/docker to launch required services.
7.1. Full Development Stack
Start all backend services (MySQL, Admin Service, Gateway) using pre-built images from Docker Hub:
npm run docker:backend:up
Or directly with docker compose:
docker compose -f src/main/docker/dev.yml up -d --wait
See Angular Developer Quick Start for more details on the available commands.
7.2. Admin Service Only (Local Gateway Development)
When developing the Java Gateway locally, you can run just the Admin Service and MySQL in Docker while running the Gateway from your IDE:
# Start Admin Service and MySQL only
npm run docker:admin-service:up
# Run Gateway locally (from IDE or command line)
./mvnw
This setup is useful when you need to:
-
Debug the Gateway code in your IDE
-
Make changes to the Gateway without rebuilding Docker images
-
Test Gateway configuration changes quickly
| Command | Description |
|---|---|
|
Start Admin Service and MySQL |
|
Stop Admin Service and MySQL |
|
Restart Admin Service and MySQL |
|
Reset and restart (fresh database) |
The Admin Service API will be available at http://localhost:12504
7.3. Individual Services
Start only the MySQL database:
npm run docker:db:up
# or: docker compose -f src/main/docker/mysql.yml up -d
Stop and remove the container:
npm run docker:db:down
# or: docker compose -f src/main/docker/mysql.yml down
7.4. Dockerizing the Application
Build a Docker image:
npm run java:docker
For ARM64 processors (e.g., Apple M1):
npm run java:docker:arm64
Run the dockerized application:
docker compose -f src/main/docker/app.yml up -d
|
On macOS Big Sur or later with Docker Desktop, enable "Use the new Virtualization framework" for better processing performance. |
See Using Docker and Docker-Compose for more information.
8. JHipster Control Center
Start a local JHipster Control Center (accessible at http://localhost:7419):
docker compose -f src/main/docker/jhipster-control-center.yml up
9. Continuous Integration
Configure CI using the JHipster ci-cd sub-generator:
jhipster ci-cd
See Setting up Continuous Integration for more information.
10. Multi-Tenant Development Testing
The Registration Portal supports multi-tenancy, where each tenant is identified by the domain name used to access the application. During development, you can test tenant resolution using custom hostnames.
10.1. How Tenant Resolution Works
The TenantResolutionFilter resolves tenants in the following priority order:
-
Domain match - The full hostname is matched against the
domaincolumn in thetenanttable -
X-TENANT-ID header - Falls back to the
X-TENANT-IDHTTP header if no domain match is found
Localhost and IP addresses are excluded from domain resolution to allow standard development access.
10.2. Setting Up Custom Hostnames
To test tenant resolution locally, configure your system’s hosts file to map custom hostnames to localhost.
10.3. Configuring Tenants in the Database
Insert or update records in the tenant table to match your custom hostnames:
-- Example: Create a tenant for hostname 'reg1'
INSERT INTO tenant (name, domain, registration_system_id)
VALUES ('Test Registration Site 1', 'reg1', 1);
-- Example: Create a tenant for hostname 'runningclub'
INSERT INTO tenant (name, domain, registration_system_id)
VALUES ('Running Club Portal', 'runningclub', 2);
The domain column must contain the exact hostname (without port) that will be used to access the application.
10.4. Accessing the Application
With the hosts file configured and tenants in the database, access the application using the custom hostname:
http://reg1:9000/membership/register/1
http://runningclub:9000/membership/register/1
The tenant context will be automatically resolved based on the hostname, and the TenantContext will be populated with the corresponding tenantId and registrationSystemId.
10.5. Verifying Tenant Resolution
Check the application logs for tenant resolution messages:
TenantResolutionFilter : Attempting to resolve tenant by domain: reg1
TenantResolutionFilter : Resolved tenant by domain: tenantId=1, registrationSystemId=1
If no tenant is found, you will see:
TenantResolutionFilter : No tenant resolved for request to: /membership/register/1 (this may be intentional for public endpoints)
10.6. Troubleshooting
| Hostname not resolving |
Verify the hosts file entry is correct and flush DNS cache if needed ( |
| "Invalid Host header" error |
Ensure the webpack dev server is configured with |
| Tenant not found |
Verify the |
| BrowserSync not accessible |
Ensure BrowserSync is configured with |