← All posts

2026-05-14

How to Host a Private Java/Angular Demo Recruiters Can Open in One Click

Spring BootAngularRailwayPostgreSQLPortfolioPRANI OPS

PRANI OPS Action templates catalog used in the hosted demo

Part of Building PRANI OPS — Technical Notes. See also the PRANI OPS case study.

Introduction

The hook

You built a serious stack: Spring Boot, Angular, Postgres, Flyway, JWT roles.

A recruiter has twelve minutes between calls. They will not clone your monorepo, install JDK 21, start Docker Compose, and fight port 5432.

If the only path is “run it locally,” the project dies in the inbox.

The objective

You will learn how PRANI OPS stays private on GitHub while still offering a one-click hosted demo:

  1. One Docker image that serves the Angular SPA and the API together.
  2. Managed Postgres + Flyway seeds so login works on first boot.
  3. Env vars that make CORS and cookies honest in production.
  4. A portfolio case study that links the live URL — source shared on request.

Prerequisites

  • A Spring Boot + frontend monorepo (or willingness to copy the pattern)
  • A Railway (or similar) account
  • Comfort with Docker and basic DNS later for a custom domain

Body

Step 1: Decide what “demo” means

For PRANI OPS, demo means:

Must workCan wait
Login with seeded rolesPublic GitHub
Real UI against real API + DBProduction ADP / Stripe wiring
HTTPS URL anyone can openPerfect custom domain on day one

Integrations that are stub or config-gated stay that way. Recruiters respect honesty more than a fake “connected to Workday” badge.

Step 2: One service, not three micro-deploys

Locally you might run Angular on :4200 and Spring on :8080. For a recruiter demo, that split is friction.

PRANI OPS builds Angular into Spring’s static classpath, then runs one container:

Browser  →  https://your-demo-host/
              ├─ /*           Angular SPA (Spring static)
              └─ /api/v1/**   REST API
                    └─ Postgres (Railway plugin)

Deploy from the repo root (Dockerfile + railway.toml), not from backend/ alone. Add a Postgres plugin and wire DATABASE_URL.

Step 3: Env vars that matter on day one

Minimum production-shaped set:

VariableWhy
SPRING_PROFILES_ACTIVE=prodProd security defaults
DATABASE_URLRailway Postgres (entrypoint can map URI → JDBC)
PRANIOPS_JWT_SECRET≥32 random chars
MFA_ENCRYPTION_KEY≥32 random chars
APP_URLPublic origin (Railway URL first)
PRANIOPS_CORS_ORIGINSSame origin(s) — comma-separate if you keep Railway + custom domain
MAIL_ENABLED=falseDemo does not need outbound mail
KAFKA_ENABLED=falseKeep the surface small

Smoke tests after deploy:

  1. GET /api/v1/health → 200
  2. Open /login → sign in with a seeded account
  3. Hit one authenticated page (inbox, actions, or enrollment)

Step 4: Seed accounts are product, not an afterthought

Flyway (or your migration tool) should create named demo users with a shared password documented on the case study — for example HR admin, employee, manager.

If the database is empty, the URL is a brick. Treat seed data as part of the deploy contract, same as the health check.

Step 5: Portfolio links the demo; GitHub can stay private

On the personal site:

  • Featured project card → case study
  • Primary CTA → Open live demo (hosted URL)
  • Secondary → lo-fi prototype or “source on request”

You do not need to flip the repo public to prove the work. You need a URL that survives a phone screen share.

Step 6 (optional): Custom domain later

When DNS is ready, add the Railway custom domain (CNAME + ownership TXT), then point APP_URL / CORS at https://demo.yourdomain.com. Keep the *.up.railway.app host as a fallback until certs are green.


Conclusion

Summary

  • Recruiters open links; they do not bootstrap JDKs.
  • Ship one container: SPA + API + managed Postgres.
  • Seeded logins and a health check are part of “done.”
  • Private source + public demo is a valid portfolio strategy.

Call to action

Try the live demo: demo.darrellkilo.com (fallback: Railway URL on the case study).
Password for seeded users is on the case study page.

Building a similar Spring + Angular portfolio piece? Start with health + one happy-path login before you polish DNS.

Series note

Next up in this series: how HR action templates actually mutate employee records on effective date — not just flip a status field.