Skip to Content
Edit on GitHub

Supporting Services

LearnHouse relies on several supporting services that run alongside the main applications. In both development and production, these services are managed via Docker (configuration in the community-edition/ directory).

PostgreSQL

PostgreSQL 16 (Alpine) is the primary database for LearnHouse. It stores all persistent application data including:

  • Organizations and their configurations
  • User accounts and authentication records
  • Courses, chapters, and activities
  • Collections, trails, and progress tracking
  • AI vector embeddings (via the pgvector extension)

The backend connects to PostgreSQL through SQLModel. In development, the LearnHouse CLI automatically starts a PostgreSQL container.

Default port: 5432

Redis

Redis 7.2.3 (Alpine) serves as the caching, session management, and collaboration persistence layer:

  • Caching — Reduces database load by storing frequently accessed data in memory.
  • Session storage — Manages user session data for fast access.
  • Collaboration state — Stores Yjs document state from the Collab server with a 1-hour TTL before it is persisted to PostgreSQL.
  • Pub/Sub — Enables communication between services when needed.

Default port: 6379

Hocuspocus (Collaboration Server)

The Hocuspocus server, located at apps/collab, provides real-time collaborative editing capabilities. It is a Node.js + TypeScript application (run via tsx) built on Hocuspocus  ^3.0.0, which uses the Yjs CRDT library under the hood. It connects to Redis via ioredis ^5.9.3.

Default port: 4000 (configurable via COLLAB_PORT env var)

Authentication

The Collab server performs JWT verification using the same secret as the API backend. On connection, it verifies board membership by making a request to the API.

Persistence

Document state follows a two-tier persistence strategy:

  1. Redis — Yjs state is first stored in Redis with a 1-hour TTL for fast access.
  2. PostgreSQL — State is persisted to the database via the API with a 5-second debounce to avoid excessive writes.

Rate Limiting and Capacity

  • Max 10 concurrent users per board
  • Rate limiting of 30 connections per IP per minute

Key Features

  • Real-time document synchronization — Multiple users can edit the same activity simultaneously.
  • Conflict resolution — Yjs CRDTs handle concurrent edits without conflicts.
  • Durable persistence — Document state survives server restarts through Redis and PostgreSQL.

The frontend connects to Hocuspocus directly over WebSocket using the @hocuspocus/provider client for low-latency collaborative editing.

nginx (Reverse Proxy)

In production deployments, nginx (Alpine) acts as the reverse proxy that routes incoming traffic to the appropriate service:

  • Frontend requests go to the Next.js application
  • API requests are forwarded to the FastAPI backend
  • WebSocket connections for collaboration are routed to the Hocuspocus server

nginx also handles TLS termination and static asset serving in production environments.

Service Communication

All services communicate over a shared Docker network. The typical request flow is:

Client
  └── nginx (reverse proxy)
        ├── web (Next.js frontend, port 3000)
        ├── api (FastAPI backend, port 9000)
        │     ├── PostgreSQL (port 5432)
        │     └── Redis (port 6379)
        └── collab (Hocuspocus, port 4000)
              ├── Redis (port 6379)
              └── api (port 9000, for persistence & auth)

The frontend makes HTTP requests to the backend API. The collaboration server authenticates connections via JWT (shared secret with the API), verifies board membership through the API, and persists document state to both Redis and PostgreSQL (via the API). PostgreSQL is accessed directly only by the backend.