Architecture
This page describes the system architecture of Ops Atlas, including how the frontend, backend, database, and external systems interact.
High-Level Overview
┌─────────────┐ REST API ┌──────────────────┐
│ Frontend │ ───────────────────── │ Backend │
│ Angular 17 │ (JSON) │ Spring Boot 3.2 │
│ Port 3000 │ ◄──── SSE ────────── │ Port 8090 │
└─────────────┘ └────────┬─────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌─────▼─────┐
│ PostgreSQL │ │ Docker Hosts│ │ Redis │
│ Port 5432│ │ (via SSH) │ │ │
└───────────┘ └─────────────┘ └───────────┘Frontend
- Framework: Angular 17 with standalone components
- Routing: Lazy-loaded routes defined in
app.routes.ts - Port: 3000 (development), 80 (production via Nginx)
- Auth guard: All routes except
/loginand/setupare protected byauthGuard - Feature guard: Edition-gated routes are protected by
featureGuard
Key Services
| Service | Purpose |
|---|---|
api.service.ts | HTTP client for all backend communication |
auth.service.ts | JWT token management, login/logout |
deployment.service.ts | Deployment orchestration and SSE log streaming |
notification.service.ts | Real-time notification handling |
redis.service.ts | Redis key management |
database.service.ts | Database connections and schema operations |
Backend
- Framework: Spring Boot 3.2 on Java 17
- Security: Spring Security with JWT authentication
- Data: Spring Data JPA (PostgreSQL) + Spring Data Redis
- Boilerplate: Lombok for getters, setters, builders, and constructors
Package Structure
com.gcdf.opsdashboard/
├── config/ # Security, CORS, WebSocket, and app configuration
├── controller/ # REST API endpoints
├── model/
│ └── entity/ # JPA entities (User, Environment, License, etc.)
├── payload/ # Request/response DTOs
├── repository/ # Spring Data JPA repositories
└── service/ # Business logicConfiguration Files
| File | Purpose |
|---|---|
application.yml | Default configuration |
application-prod.yml | Production overrides |
Database
- Production: PostgreSQL 15
- Development / Testing: H2 (in-memory)
- ORM: Spring Data JPA with Hibernate
Key entities include User, Environment, ApplicationConfig, License, AuditLogEntry, and Notification.
Docker Compose
The production stack consists of three services on a shared bridge network (ops-dashboard-network):
| Service | Image | Purpose |
|---|---|---|
postgres | postgres:15 | Application database |
backend | Custom build | Spring Boot API server |
frontend | Custom build | Angular app served by Nginx |
Compose files:
| File | Use Case |
|---|---|
docker-compose.yml | Production |
docker-compose.dev.yml | Development (with hot reload) |
docker-compose.local.yml | Local overrides |
Authentication Flow
- User submits credentials to
POST /api/auth/login - Backend validates against BCrypt-hashed password in PostgreSQL
- On success, backend returns an access token (1 hour) and a refresh token (7 days)
- Frontend stores tokens and attaches the access token as a
Bearerheader on every request - When the access token expires, the frontend calls
POST /api/auth/refreshwith the refresh token - On logout, both tokens are invalidated server-side
SSH & Docker Integration
Ops Atlas manages containers on remote Docker hosts over SSH.
- SSH library: JSch (Java Secure Channel)
- Docker client: Docker Java client library
- Flow: Backend connects to configured hosts via SSH, then communicates with the Docker daemon to list, start, stop, deploy, and inspect containers
- Port: Docker API on port 2375 (unencrypted) or 2376 (TLS) on the remote host
WARNING
Ensure the SSH user on each Docker host has permission to run docker commands. Typically this means adding the user to the docker group.
Server-Sent Events (SSE)
Ops Atlas uses SSE for real-time streaming in two key areas:
- Deployment logs:
POST /api/deployment/deploy-streamopens a persistent connection that streams build and deployment output line by line - Notifications: Real-time alerts are pushed to connected clients without polling
Data Flow Summary
User action in browser
→ Angular service makes HTTP request
→ Spring Security validates JWT
→ Controller delegates to Service
→ Service interacts with PostgreSQL / SSH / Redis
→ Response returned as JSON (or SSE stream)