> For the complete documentation index, see [llms.txt](https://docs.authgear.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.authgear.com/deployment/architecture-guides/docker-compose-reference-architecture.md).

# Docker Compose Reference Architecture

Highly available reference architecture for running Authgear on virtual machines with Docker Compose or Podman Compose.

This page describes a highly available reference architecture for running Authgear on conventional virtual machines with Docker Compose or Podman Compose. It suits deployments where a Kubernetes cluster is unavailable, or not worth operating for a single application. For the Kubernetes-based architecture, see [K8S Cluster Reference Architecture](/deployment/architecture-guides/on-premises-reference-architecture.md).

For development, see [Run locally with Docker Compose](/deployment/local.md).

## Components

The system has three parts.

1. **Authgear**: the application services and their ingress (a reverse proxy), run under Compose on two Authgear VMs.
2. **Monitoring stack**: Prometheus and Grafana, run under Compose on a separate monitor VM. Option 1 can omit this VM, at the cost of monitoring.
3. **Datastores**: PostgreSQL, Redis, and S3-compatible object storage.

## Choosing a Datastore Option

* [**Option 1: Your Own Datastores**](#option-1-your-own-datastores). You supply PostgreSQL, Redis, and object storage from services you already operate. Choose this when your platform team already runs them. It is the preferred option, because backup, patching, and failover stay with the team that already handles them. Two VMs, plus an optional monitor VM.
* [**Option 2: Included Datastores**](#option-2-included-datastores). The datastores are installed on dedicated datastore VMs as part of the deployment. Choose this when no managed datastores are available, such as air-gapped sites and bare-metal data centres, or when you want a self-contained environment. Five VMs: two for Authgear, two for the datastores, and a monitor VM.

VM counts exclude the load balancer, which you provide.

## Option 1: Your Own Datastores

The deployment adds only the VMs that run Authgear and the monitoring stack, and uses datastores you already operate. Authgear runs on two VMs behind a load balancer, so either can be rebooted or upgraded without an outage. The monitoring stack runs on an optional monitor VM. Without that VM, the setup has no monitoring.

```mermaid
architecture-beta
  service user(internet)[User]
  service admin(internet)[Admin]
  service firewall(server)[Firewall]
  service lb(server)[Load Balancer]

  group Datastore(cloud)["Your Datastores"]
    service db(database)["PostgreSQL"] in Datastore
    service redis(database)["Redis"] in Datastore
    service s3(disk)["S3-Compatible Storage"] in Datastore
    junction j_datastore in Datastore
    j_datastore:T -- L:db
    j_datastore:R -- L:redis
    j_datastore:B -- L:s3

  group MonitorVM(cloud)["Monitor VM"]
    group ComposeMonitor(cloud) in MonitorVM
      service prometheus(server)[Prometheus] in ComposeMonitor
      service grafana(server)[Grafana] in ComposeMonitor
      prometheus:L -- R:grafana

  group AuthgearVM(cloud)["Authgear VM x2"]
    group ComposeAuthgear(cloud) in AuthgearVM
      service ingress(server)[Ingress] in ComposeAuthgear
      service authgear(server)[Authgear] in ComposeAuthgear
      ingress:R --> L:authgear
      authgear:R -- L:j_datastore
      authgear:T --> B:prometheus

  group External(cloud)[External Services]
    service mailer(server)[Mailer] in External
    service sms(server)["SMS Gateway"] in External
    service whatsapp(server)["WhatsApp"] in External
    service captcha(server)[CAPTCHA] in External
    junction j_mailer in External
    junction j_whatsapp in External
    junction j_sms in External
    junction j_captcha in External
    j_mailer:B -- T:mailer
    j_whatsapp:B -- T:whatsapp
    j_sms:B -- T:sms
    j_captcha:B -- T:captcha
    j_sms:L -- R:j_mailer
    j_sms:R -- L:j_whatsapp
    j_captcha:R -- L:j_mailer

user:R --> L:firewall
firewall:R --> L:lb
lb:R --> L:ingress
admin:R --> L:grafana
authgear:B -- T:j_mailer
```

### Inventory

In addition to the [common inventory](#common-inventory), you provide the following.

| Item           | Minimum                         | Recommended                      | Quantity | Remarks                                                                                                                                                             |
| -------------- | ------------------------------- | -------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Load balancer  |                                 |                                  | 1        | <ul><li>For example HAProxy, Apache, or a managed service.</li><li>Must be highly available.</li><li>Can terminate TLS or pass it through to the ingress.</li></ul> |
| Authgear VM    | 2 CPU / 16 GB / 40 GB Data Disk | 4 CPU / 16 GB / 100 GB Data Disk | 2        | For failover, not capacity.                                                                                                                                         |
| Monitor VM     | 1 CPU / 8 GB / 40 GB Data Disk  | 1 CPU / 8 GB / 40 GB Data Disk   | 1        | Optional.                                                                                                                                                           |
| PostgreSQL     | 2 CPU / 16 GB / 40 GB Data Disk | 4 CPU / 16 GB / 100 GB Data Disk | 1        | Size the disk for user data and audit logs.                                                                                                                         |
| Redis          | 1 CPU / 4 GB / 10 GB Data Disk  | 1 CPU / 8 GB / 10 GB Data Disk   | 1        | About 30 kB per session.                                                                                                                                            |
| Object storage | 40 GB Storage                   | 80 GB Storage                    | 1        | Holds user profile pictures and other assets.                                                                                                                       |

## Option 2: Included Datastores

PostgreSQL, Redis, and S3-compatible object storage ([RustFS](https://rustfs.com)) are installed on two dedicated datastore VMs, a primary and a replica, as part of the deployment. This is the only option that needs no managed datastore from you, at the cost of more VMs. Authgear runs on two further VMs behind the load balancer. Each Authgear VM runs its own HAProxy, which routes database and Redis connections to the current primary. The monitor VM runs the monitoring stack and the failover controllers: [pg\_auto\_failover](https://github.com/hapostgres/pg_auto_failover) (PAF) for PostgreSQL and Sentinel for Redis. Object storage replication copies objects to the second datastore VM, which gives a redundant copy rather than automatic failover.

```mermaid
architecture-beta
  service user(internet)[User]
  service admin(internet)[Admin]
  service firewall(server)[Firewall]
  service lb(server)[Load Balancer]

  group DatastoreVM(cloud)["Datastore VM x2"]
    group Datastore(cloud) in DatastoreVM
      service db(database)["PostgreSQL"] in Datastore
      service redis(database)["Redis"] in Datastore
      service s3(disk)["S3-Compatible Storage"] in Datastore
      junction j_datastore in Datastore
      j_datastore:T -- L:db
      j_datastore:R -- L:redis
      j_datastore:B -- L:s3

  group MonitorVM(cloud)["Monitor VM"]
    group ComposeMonitor(cloud) in MonitorVM
      service prometheus(server)[Prometheus] in ComposeMonitor
      service grafana(server)[Grafana] in ComposeMonitor
      service paf(server)[PAF] in ComposeMonitor
      service sentinel(server)[Sentinel] in ComposeMonitor
      prometheus:L -- R:grafana
      prometheus:R -- L:paf
      paf:R -- L:sentinel

  group AuthgearVM(cloud)["Authgear VM x2"]
    group ComposeAuthgear(cloud) in AuthgearVM
      service ingress(server)[Ingress] in ComposeAuthgear
      service authgear(server)[Authgear] in ComposeAuthgear
      ingress:R --> L:authgear
      authgear:R -- L:j_datastore
      authgear:T --> B:prometheus

  group External(cloud)[External Services]
    service mailer(server)[Mailer] in External
    service sms(server)["SMS Gateway"] in External
    service whatsapp(server)["WhatsApp"] in External
    service captcha(server)[CAPTCHA] in External
    junction j_mailer in External
    junction j_whatsapp in External
    junction j_sms in External
    junction j_captcha in External
    j_mailer:B -- T:mailer
    j_whatsapp:B -- T:whatsapp
    j_sms:B -- T:sms
    j_captcha:B -- T:captcha
    j_sms:L -- R:j_mailer
    j_sms:R -- L:j_whatsapp
    j_captcha:R -- L:j_mailer

user:R --> L:firewall
firewall:R --> L:lb
lb:R --> L:ingress
admin:R --> L:grafana
authgear:B -- T:j_mailer
```

### Inventory

In addition to the [common inventory](#common-inventory), you provide the following. The datastores are installed on the datastore VMs as part of the deployment.

| Item          | Minimum                          | Recommended                      | Quantity | Remarks                                                                                                                                                             |
| ------------- | -------------------------------- | -------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Load balancer |                                  |                                  | 1        | <ul><li>For example HAProxy, Apache, or a managed service.</li><li>Must be highly available.</li><li>Can terminate TLS or pass it through to the ingress.</li></ul> |
| Authgear VM   | 2 CPU / 16 GB / 40 GB Data Disk  | 4 CPU / 16 GB / 100 GB Data Disk | 2        | For failover, not capacity. Each runs its own HAProxy for database and Redis routing.                                                                               |
| Datastore VM  | 2 CPU / 16 GB / 100 GB Data Disk | 4 CPU / 16 GB / 200 GB Data Disk | 2        | Primary and replica. Size the disk for user data and audit logs.                                                                                                    |
| Monitor VM    | 1 CPU / 8 GB / 40 GB Data Disk   | 1 CPU / 8 GB / 40 GB Data Disk   | 1        | Runs the monitoring stack and the PAF and Sentinel failover controllers.                                                                                            |

## Requirements

### Common Inventory

Both options need the following, in addition to the VMs listed in their inventories.

| Item             | Quantity          | Remarks                                                                                                                                                                                                                                    |
| ---------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| IP address       | 1                 | For the load balancer.                                                                                                                                                                                                                     |
| Domain           | 2 + 1 per project | Two system domains for the Authgear Portal and Portal Login, for example `portal.example.com` and `accounts.example.com`, plus one Authgear Endpoint domain per [project](/get-started/5-minute-guide.md), for example `auth.example.com`. |
| Certificate      | 1                 | Wildcard certificate covering the domains above. Install it on the ingress, or on the load balancer if that terminates TLS.                                                                                                                |
| Grafana hostname | 1                 | Internal hostname and certificate. Grafana is not exposed to the internet, so it does not use the public domains or the wildcard certificate. Not needed when Option 1 omits the monitor VM.                                               |
| Firewall         | 1                 | In front of the load balancer.                                                                                                                                                                                                             |
| Mailer           | 1                 | Optional. SMTP server or SendGrid.                                                                                                                                                                                                         |
| SMS              | 1                 | Optional. Gateway account for SMS delivery.                                                                                                                                                                                                |
| WhatsApp         | 1                 | Optional. Business account for WhatsApp delivery.                                                                                                                                                                                          |
| CAPTCHA          | 1                 | Optional. Google reCAPTCHA or Cloudflare Turnstile.                                                                                                                                                                                        |

### Datastore Requirements

The versions below are the ones Authgear is tested against, on both a cloud-managed service and the included datastores. Option 2 installs exactly these versions. With Option 1, match them where you can. Other releases have not been tested.

| Datastore      | Version                                        |
| -------------- | ---------------------------------------------- |
| PostgreSQL     | 16.14, with the `pg_partman` extension 16.5.1. |
| Redis          | 6.2.20.                                        |
| Object storage | Any S3-compatible implementation.              |

### Expected Capacity

With 100 concurrent users logging in, the Minimum and Recommended specifications in the inventories above are expected to sustain:

| Specification | Logins per second |
| ------------- | ----------------- |
| Minimum       | 5                 |
| Recommended   | 15                |

The figures hold for both options, provided the datastores you supply under Option 1 match the specifications in the inventories.

Throughput is bound by the database, not by the number of Authgear VMs, so the second Authgear VM adds availability, not capacity. The architecture therefore fixes Authgear at two VMs, enough for failover and rolling upgrades. A third would add nothing.

### Datastore High Availability

With Option 1, datastore availability is your responsibility. With Option 2, the PAF, Sentinel, and HAProxy components described under [Option 2](#option-2-included-datastores) provide it. The [High Availability](/deployment/architecture-guides/on-premises-reference-architecture.md#high-availability) section of the K8S Cluster Reference Architecture describes how they fail over. That page places them in Kubernetes. Here they run on the monitor VM and the Authgear VMs.

Object storage uses [bucket replication](https://docs.rustfs.com/en/administration/data/bucket/replication) to keep a copy of every object on the second datastore VM. Replication is asynchronous and provides a redundant copy rather than automatic failover.

## Network, Monitoring, and Backups

The firewall rules, hostnames, WAF paths, and backup guidance in [K8S Cluster Reference Architecture](/deployment/architecture-guides/on-premises-reference-architecture.md) apply to this architecture too. Where that page says Kubernetes, read the Authgear VMs. Administrators reach Grafana over your internal network, not through the public path that serves users.

Metrics are collected by the Prometheus and Grafana instances that ship with the deployment. Access logs come from the ingress on each Authgear VM. Audit logs are persisted in PostgreSQL, so include the database in your backup policy.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.authgear.com/deployment/architecture-guides/docker-compose-reference-architecture.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
