Self-hosting requirements
What it takes to run the full Obexal stack on your own EU infrastructure: components, honest sizing, prerequisites and the Terraform option.
Obexal is also delivered as a self-hostable stack. You run every component on servers you control, and the identity of your organization never depends on a third-party operator.
What self-hosting means
Self-hosting Obexal means running the complete platform on your own infrastructure, in the European Union if sovereignty is your goal. Nothing in the request path calls a third-party service: breached password checks and GeoIP resolution are performed against local files, and email goes through the SMTP relay you choose. Hosted on your infrastructure, the platform sits outside the reach of extraterritorial non-EU legislation such as the US CLOUD Act: no vendor holds your data or your keys.
In exchange, you take on the operator duties: TLS, configuration, backups, key rotation and updates. This section covers each of them.
The components
| Component | Role | Image |
|---|---|---|
| auth-service | The Go API: OIDC/OAuth 2.1, SAML, SCIM, sessions, admin API, embedded SQL migrations | Distroless static, non-root |
| admin | The administration console (Next.js, standalone output) | node:20-slim, non-root |
| login-ui | The sign-in UI, a static export | nginx-unprivileged |
| PostgreSQL | The only durable state: accounts, credentials, encrypted secrets, audit log | postgres:16 or a managed EU PostgreSQL |
| Redis | Sessions and rate limiting, volatile by design | redis:7 or a managed EU Redis |
| MinIO (optional) | S3-compatible object storage for tenant logos | minio, or any EU S3-compatible bucket |
| Caddy | Reverse proxy: HTTPS termination, ACME, on-demand TLS for tenant custom domains | caddy:2.8 |
In production, prefer a managed EU PostgreSQL and Redis and remove those two services from the Compose file. The stack works identically either way.
Sizing guidance
Honestly: a small VPS is enough to start. The auth-service is a single static Go binary, the login UI is static files, and the admin console is one Node.js process. An instance with 2 vCPU, 4 GB of RAM and 40 GB of SSD runs the whole stack comfortably.
What actually grows with usage:
- Memory during logins: password hashing uses argon2id with 64 MiB per hash by default (
ARGON2_MEMORY_KIB), so many strictly concurrent logins are the main memory spike. - Disk: the PostgreSQL volume, dominated over time by the audit log (bounded by
AUDIT_RETENTIONif you set one).
The Compose stack is deliberately single-host. If you need more, split PostgreSQL and Redis out to managed services first: they hold all the state.
Prerequisites
- A Linux host with Docker Engine and the Compose v2 plugin.
- A domain you control, with DNS records for the API, the admin console and the sign-in UI (see Deploy with Docker Compose).
- An EU SMTP relay: the service refuses to start in production with the debug
logmail transport. - Ports 80 and 443 reachable from the Internet, and outbound HTTPS for ACME certificate issuance.
- Optional: a
.mmdbGeoIP database for country-based conditional access, and a local breached password corpus.
The Scaleway Terraform module
The repository ships an infrastructure module under deploy/terraform/scaleway/. It provisions, entirely in the fr-par region: a private network, a managed PostgreSQL, a managed Redis with TLS, one compute instance running the Compose stack behind Caddy, an object bucket for encrypted backups (35-day lifecycle), and a firewall where only ports 80 and 443 are public and SSH is restricted to a CIDR you set. Secrets never transit through Terraform: they live in a secrets vault and are pulled at boot.
Its limits, stated plainly:
- It is a single-host module: one compute instance runs the application. The managed database can be provisioned in high availability, the application layer cannot.
- There is no multi-region or multi-datacenter failover.
terraform applycreates billed resources: always reviewterraform planfirst.
The same pattern declines to OVHcloud or Outscale (the latter if end-to-end SecNumCloud qualification is a contractual requirement).
Next steps
- Deploy with Docker Compose: DNS, environment, first launch.
- Configuration reference: every important variable, family by family.
- Backups and restore: before you go to production, not after.