Architecture
High-level architecture overview for MatrixEasyMode and its current self-hosted deployment model.
This page explains the current MatrixEasyMode runtime model, the major components, and why the platform is structured this way.
If you want installation steps, start with Get Started and the Installation Guide. If you want traffic and connectivity detail, see Network Behavior.
MatrixEasyMode is designed as a self-hosted platform for deploying and operating Matrix + Element on infrastructure you control.
The architecture intentionally keeps the deployment model understandable rather than hiding everything behind a fully managed abstraction layer.
At a high level, the current deployment consists of:
- PostgreSQL
- Nginx Proxy Manager
- MatrixEasyMode API
- MatrixEasyMode web frontend
These components are intentionally separated into infrastructure services and application services rather than bundled into a single opaque runtime.
Architectural goals
The current architecture is shaped around a few practical goals:
- make Matrix deployment easier without hiding the underlying infrastructure
- support real public hostnames and HTTPS ingress
- keep runtime behavior understandable
- separate foundational services from application services
- support both published images and local builds
- provide a base for future platform capabilities
- keep local development and deployed environments aligned
MatrixEasyMode is still early, but the architecture is already aiming for a clean and extensible deployment model rather than a temporary demo setup.
High-level runtime shape
The standard runtime has two layers.
Infrastructure layer
The infrastructure layer provides the services the application depends on:
postgresnpm(Nginx Proxy Manager)
These are the foundational services.
PostgreSQL provides durable application state. Nginx Proxy Manager provides the HTTPS ingress layer and public routing model.
Application layer
The application layer provides the MatrixEasyMode platform itself:
apiweb
The API acts as the main platform and provisioning service. The web frontend provides the browser-facing experience.
This layer depends on the infrastructure layer already being present and healthy.
Why the staged startup model exists
MatrixEasyMode is intentionally started in stages:
- infrastructure first
- application second
This follows directly from the platform dependencies.
The MatrixEasyMode API integrates with Nginx Proxy Manager to bootstrap and reconcile public ingress routes. That means NPM must already be reachable, and the required wildcard certificate must already exist, before the application layer starts.
Public ingress is therefore part of the architecture itself, not an afterthought.
Component responsibilities
PostgreSQL
PostgreSQL is the persistent state store for MatrixEasyMode.
It exists as a separate infrastructure service because database durability, lifecycle, and backup posture should be treated deliberately.
In the current deployment model, PostgreSQL is bundled for convenience, but it is still foundational infrastructure rather than a disposable app container.
Nginx Proxy Manager
Nginx Proxy Manager is the public ingress layer in the current deployment model.
Its role is not only to terminate HTTPS, but also to provide the managed route layer that MatrixEasyMode integrates with.
The architecture assumes:
- the operator controls NPM
- the operator manages or confirms certificate availability
- MatrixEasyMode authenticates against the NPM API using operator-provided credentials
- MatrixEasyMode can create or reconcile the main public platform routes for web and API access
This keeps ingress explicit and visible to the operator.
MatrixEasyMode API
The API is the primary backend service of the platform.
In the current architecture, it is responsible for:
- serving the backend for the web frontend
- binding to environment-driven configuration
- integrating with Nginx Proxy Manager
- participating in provisioning and bootstrap flows
- coordinating platform-level runtime behavior
The API therefore acts as part of the platform control plane rather than as a thin CRUD-only service.
MatrixEasyMode web frontend
The web frontend is the browser-facing surface of MatrixEasyMode.
It depends on:
- correct public URL configuration
- correct internal API connectivity over the Docker network
- correct auth and callback configuration
- correct public ingress configuration through NPM
The frontend therefore sits between the public internet and the internal Docker service network.
Public and internal addressing model
The architecture deliberately separates:
- public browser-facing URLs
- internal container-to-container URLs
Typical examples are:
- public web URL:
https://admin.your-domain.com - public API URL:
https://api.your-domain.com - internal web service URL:
http://web:3000 - internal API service URL:
http://api:7000
This separation matters because MatrixEasyMode must work correctly in both of these contexts:
- from the browser over public HTTPS routes
- from container to container over the internal Docker network
That is also why environment values such as NEXTAUTH_URL, NEXTAUTH_URL_INTERNAL, NEXT_PUBLIC_API_URL, and API_URL are important.
Ingress is part of the platform
A useful way to think about MatrixEasyMode is this:
it is not just an application sitting behind a reverse proxy.
Instead, ingress is part of the platform architecture itself.
That means:
- public hostnames matter
- DNS matters
- certificate state matters
- NPM credentials matter
- route reconciliation matters
This is one reason the documentation focuses heavily on deployment clarity and infrastructure visibility.
Image modes and architectural consistency
MatrixEasyMode currently supports two application image modes:
- registry mode
- local mode
These change how application images are sourced, but they do not change the architecture itself.
Registry mode
Registry mode uses published images.
This is the normal deployment path for most installations.
The architecture remains the same:
- infrastructure layer first
- application layer second
- same public and internal routing model
- same ingress expectations
Local mode
Local mode uses locally built application images.
This is mainly intended for contributors and development workflows, but it still runs against the same overall runtime shape:
- PostgreSQL
- Nginx Proxy Manager
- API
- web frontend
That consistency is intentional because it keeps development and deployment aligned.
Persistent data posture
The architecture assumes persistent state matters.
That appears in multiple places:
- PostgreSQL data persistence
- operator-managed environment configuration via
.env - persistent instance data paths used by platform workflows
- certificate and ingress state managed outside the app containers
MatrixEasyMode is therefore designed around long-running operator-owned infrastructure rather than disposable demo environments.
Why the current architecture is infrastructure-visible
MatrixEasyMode could have been packaged as a more opaque all-in-one runtime.
That is not the current approach.
The architecture instead favors:
- explicit infrastructure boundaries
- transparent ingress behavior
- clear runtime dependencies
- operator control over certificates, hostnames, and DNS
- helper scripts that simplify workflows without hiding the deployment model
For self-hosters, hidden behavior usually reduces confidence. Explicit behavior improves understanding and troubleshooting.
Architectural trade-offs
The current architecture is deliberate, but it also involves trade-offs.
What this architecture does well
It gives MatrixEasyMode:
- a realistic self-hosted deployment model
- separation between infrastructure and application services
- compatibility with real HTTPS and public routing
- a clean place for ingress bootstrap and route reconciliation
- a path for future platform growth
- a consistent model across registry and local image modes
What it asks of the operator
It also expects some familiarity with:
- Docker Compose basics
- public DNS and hostnames
- Nginx Proxy Manager
- certificate management
- environment-driven deployment
- staged startup and log-based troubleshooting
That is intentional. MatrixEasyMode currently targets users who prefer visibility and control over highly abstracted deployment flows.
Internal application structure
From an operator perspective, the most important architectural reality is the runtime shape described above.
Internally, MatrixEasyMode is also being developed with structure intended to support future platform growth rather than a throwaway prototype approach.
That is part of why the API is treated as a platform service and why the documentation focuses heavily on architecture, operations, and runtime behavior.
This page intentionally focuses on the deployment and runtime architecture operators need to understand first.
MatrixEasyMode in one sentence
A simple mental model is:
MatrixEasyMode is a self-hosted Matrix deployment platform composed of a web frontend and control-plane API running on top of PostgreSQL and Nginx Proxy Manager, with public ingress treated as a first-class architectural concern.
Related documentation
Final note
The current MatrixEasyMode architecture is intentionally explicit and infrastructure-visible.
The goal is to help users understand:
- what is running
- what depends on what
- what is public
- what is internal
- what the platform manages
- what still belongs to the operator
That clarity is part of the product, not just part of the documentation.
