DL
Back to Blog
TechFebruary 2, 2026·5 min read

Getting Started with FhirHub

A step-by-step guide to running FhirHub locally with Docker Compose and Node.js. Clone the repo, start five services, seed clinical data, and log in to the dashboard in minutes.

D

David Le

Getting Started with FhirHub

#Part 3 of the FhirHub Series*

In Part 2, we examined the architecture. Now let's get FhirHub running on your machine.

Prerequisites

You'll need:

  • Docker Desktop (or Docker Engine + Compose) -- for running the infrastructure
  • Node.js 20+ -- for the frontend
  • Git -- to clone the repository

That's it. No .NET SDK needed locally since the API runs in Docker.

Clone and Start

# Clone the repository
git clone https://github.com/david-le/FhirHub.git
cd FhirHub

# Start the backend infrastructure
cd FhirHubServer
docker-compose up -d

# Start the frontend (in a separate terminal)
cd frontend
npm install
npm run dev

Docker Compose will pull and start five services:

  1. PostgreSQL (HAPI FHIR database)
  2. HAPI FHIR R4 server
  3. PostgreSQL (Keycloak database)
  4. Keycloak 26 identity provider
  5. FhirHub API (.NET 8 gateway)

Verify the Services

Once everything is running, verify each service:

HAPI FHIR Server

curl http://localhost:8080/fhir/metadata | jq '.fhirVersion'
# Expected: "4.0.1"

The /fhir/metadata endpoint returns the server's CapabilityStatement. If you see FHIR version 4.0.1, the server is ready.

Keycloak

Open http://localhost:8180 in your browser. You should see the Keycloak admin console. Log in with:

  • Username: admin
  • Password: admin

Navigate to the fhirhub realm to see the pre-configured clients and roles.

FhirHub API

curl http://localhost:5197/api/dashboard/metrics

The API should return dashboard metrics (or a 401 if authentication is enforced). You can also check the Swagger UI at http://localhost:5197/swagger.

Frontend

Open http://localhost:7002 in your browser. You'll be redirected to the Keycloak login page.

Login Page

First Login

Log in with one of the pre-configured test accounts. The available roles determine what you can see and do:

RoleCapabilities
adminFull access to all features including user management and audit logs
practitionerRead/write patients, vitals, conditions, medications, labs, exports
nurseRead patients/vitals/conditions/medications/labs, write vitals, manage alerts
front_deskRead patient demographics only
patientRead own data (vitals, conditions, medications, labs)

After logging in, you'll land on the dashboard:

Dashboard

Exploring the Application

Dashboard

The dashboard provides an overview of the system:

  • Metrics row -- Patient count, observation count, and other aggregate stats
  • Recent patients -- Quick access to recently viewed patients
  • Activity feed -- Latest clinical events across the system
  • Alerts panel -- Clinical alerts for abnormal values
  • System status -- Health of backend services

Patient List

Navigate to the patients page to see a searchable, filterable list of all patients:

Patient List

The patient list supports:

  • Text search by name or identifier
  • Grid and table view toggle
  • Pagination

Patient Detail

Click a patient to see their full clinical record:

Patient Detail

The patient detail page is organized into tabs:

  • Overview -- Demographics and summary
  • Vitals -- Chart and table of vital signs
  • Conditions -- Active and resolved diagnoses
  • Medications -- Current and discontinued medications
  • Labs -- Lab panels with reference ranges
  • Timeline -- Chronological view of all events

Project Structure

FhirHub/
├── frontend/                    # Next.js 16 frontend
│   ├── src/
│   │   ├── app/                # App Router pages
│   │   │   ├── (auth)/         # Login, register routes
│   │   │   └── (dashboard)/    # Protected dashboard routes
│   │   ├── components/         # React components (60+)
│   │   ├── hooks/              # Custom React hooks
│   │   ├── lib/                # Utilities, clinical rules
│   │   ├── repositories/       # API client layer
│   │   ├── services/           # Business logic
│   │   └── types/              # TypeScript types and DTOs
│   └── package.json
│
├── FhirHubServer/              # Backend infrastructure
│   ├── docker-compose.yml      # 5-service orchestration
│   ├── keycloak/
│   │   └── realm-export.json   # Pre-configured realm
│   └── src/
│       ├── FhirHubServer.Api/  # API gateway project
│       │   ├── Controllers/    # REST endpoints
│       │   ├── Authorization/  # RBAC policies
│       │   ├── Middleware/     # Security, error handling
│       │   └── Repositories/   # HAPI FHIR data access
│       └── FhirHubServer.Core/ # Shared domain logic
│           ├── DTOs/           # Data transfer objects
│           └── Services/       # Business services
│
└── blog/                       # This blog series

Troubleshooting

Services not starting? Check Docker logs:

cd FhirHubServer
docker-compose logs -f

HAPI FHIR takes a while? The HAPI FHIR container has a start_period of 60 seconds. It needs time to run database migrations on first boot.

Keycloak login redirect fails? Make sure the frontend is running on port 7002 -- the Keycloak realm is pre-configured to redirect to http://localhost:7002.

API returns 401? Your Keycloak token may have expired. Refresh the page to trigger a new login flow.

What's Next

In Part 4, we'll dive deep into the SMART on FHIR authentication flow, examining how Keycloak is configured for OIDC with PKCE and how roles are mapped to authorization policies.


Find the source code on GitHub Connect on LinkedIn

Related Projects

Featured

FhirHub

A healthcare data management platform built on the HL7 FHIR R4 standard, providing a comprehensive web interface for managing patient clinical data including vitals, conditions, medications, lab orders, and bulk data exports with role-based access control and full audit logging.

Next.js 16
React 19
Typescript
Tailwind CSS 4
+8