Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Eine gründliche Evaluierung von SOGo 6, der Next.js/Flask-Groupware-Suite, bereitgestellt mit dem Stalwart-Mailserver und OpenLDAP via Docker Compose. Behandelt Architektur, Feature-Implementierung, SSO, MFA und über 1.800 bestandene Tests.
SOGo 6 ist eine komplette Neuentwicklung der SOGo Groupware-Suite. Nach 20 Jahren mit AngularJS und Objective-C in SOGo 5 liefert die neue Version ein Python/Flask REST API Backend, ein Next.js 16 Frontend, PostgreSQL für die Persistenz, Redis für Caching und Task-Queues sowie eine vollwertige Admin-API, die das alte sogo-tool CLI ersetzt. Die erste öffentliche Beta ist für den Sommer 2026 geplant.
Dieser Artikel führt durch einen produktionsnahen Docker Compose Stack, der SOGo 6 mit Stalwart (einem All-in-One IMAP/SMTP/Sieve Mailserver) und OpenLDAP (für die Benutzerauthentifizierung) verbindet. Der vollständige Quellcode befindet sich unter github.com/tobias-weiss-ai-xr/sogo6-stalwart-openldap-dockerized.
Der Stack betreibt acht Dienste in einem einzigen Docker-Netzwerk:
Ein Nginx Reverse Proxy terminiert TLS auf den Ports 80/443 und routet /api/ an das Flask-Backend und alles andere an das Next.js-Frontend. Ein MailDev-Container fängt ausgehende E-Mails für die Inspektion während der Tests ab.
Jeder Dienst verfügt über Ressourcenlimits, Health Checks und eine Abhängigkeitsreihenfolge, die in docker-compose.yaml definiert sind. Der gesamte Speicherbedarf liegt bei etwa 2 GB.
Das Backend ist eine Gunicorn/Flask-Anwendung, die eine RESTful API bereitstellt. Sie verbindet sich mit PostgreSQL für die Datenpersistenz (Kalender, Adressbücher, Benutzereinstellungen), Redis für Session-Caching und die Celery Task-Queue sowie OpenLDAP für die Authentifizierung.
Zentrale Umgebungsvariablen:
SOGO_DB_URI: postgresql://sogo:sogo@sogo6-postgres:5432/sogo
SOGO_REDIS_URI: redis://sogo6-redis:6379/0
SOGO_LDAP_URI: ldap://sogo6-ldap:389
SOGO_LDAP_BASE_DN: dc=example,dc=org
SOGO_LDAP_BIND_DN: cn=admin,dc=example,dc=org
SOGO_SMTP_SERVER: sogo6-stalwart
SOGO_SMTP_PORT: 20025
SOGo 6 unterteilt seine Konfiguration in zwei Ebenen:
process.conf Datei bereitgestellt werden. Der Container mountet diese schreibgeschützt unter /etc/sogo/process.conf.Der Server bietet zwei API-Schnittstellen:
| API | Basis-Pfad | Zweck |
|---|---|---|
| User API | /api/user/v1/ | Mail, Kalender, Kontakte für authentifizierte Benutzer |
| Admin API | /api/admin/v1/ | Systemkonfiguration, Verwaltung der Benutzerquellen, Domain-Einstellungen |
Das Frontend ist eine Next.js 16 Anwendung (React 19, TypeScript, Tailwind CSS). Die einzige Konfiguration ist die API-Basis-URL – alle Datenanfragen werden an das Flask-Backend proxied. Der UI-Container ist zustandslos und kann unabhängig skaliert werden.
Stalwart ist ein in Rust geschriebener All-in-One Mailserver. Er ersetzt den traditionellen Stack aus Postfix + Dovecot + Rspamd durch ein einziges Binary, das jedes Standard-Mailprotokoll unterstützt:
In diesem Stack nutzt Stalwart PostgreSQL als Storage-Backend (separate Datenbank von SOGo). Die Konfiguration erfolgt über eine einzige JSON-Datei:
{
"@type": "PostgreSql",
"host": "sogo6-postgres",
"port": 5432,
"database": "stalwart",
"authUsername": "stalwart",
"authSecret": {
"@type": "Value",
"secret": "stalwart_sogo6_2026"
}
}
Stalwart v0.16 (hier verwendet) führte eine vereinheitlichte JMAP-basierte Management-API und einen stalwart-cli apply Befehl für die deklarative Konfiguration ein – was sich natürlich in Infrastructure-as-Code-Workflows einfügt.
Die Port-Mappings legen alle Mailprotokolle für Client-Tests auf dem Host offen:
| Interner Port | Host Port | Protokoll |
|---|---|---|
| 25 | 20025 | SMTP |
| 465 | 20465 | SMTPS |
| 587 | 20587 | Submission |
| 143 | 20143 | IMAP |
| 993 | 20993 | IMAPS |
| 4190 | 24190 | ManageSieve |
OpenLDAP stellt das Benutzerverzeichnis bereit. Das Docker-Image ist benutzerdefiniert und enthält bereits Seed-Daten – drei Testbenutzer (zwei Standard, ein Admin), die beim ersten Start aus einer LDIF-Datei geladen werden.
dn: uid=testuser@example.org,ou=users,dc=example,dc=org
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: testuser@example.org
cn: Test User
sn: User
mail: testuser@example.org
userPassword: password123
The health check runs an LDAP search against the base DN to verify slapd is responsive.
One caveat: OpenLDAP's `ch_calloc` assertion fails when Docker sets a high `ulimit -n`. The custom entrypoint script works around this by clamping to `ulimit -n 1024` before starting slapd.
### Nginx Reverse Proxy
Nginx terminates TLS (self-signed certificates generated by the included `gen-certs.sh` script) and routes traffic:
- `/api/*` → `sogo6-server:5000` (Flask backend)
- `/*` → `sogo6-ui:3000` (Next.js frontend)
- HTTP on port 80 redirects to HTTPS
The configuration supports WebSocket upgrade headers for Server-Sent Events and future real-time features.
---
## How the Components Interact
### Authentication Flow
1. User enters credentials in the Next.js UI
2. Frontend POSTs to `/api/user/v1/auth/login`
3. Flask backend binds to OpenLDAP with the configured `SOGO_LDAP_BIND_DN` and verifies the user's password against the `inetOrgPerson` entry
4. On success, the backend returns a JWT token
5. Subsequent API calls include the JWT in the `Authorization: Bearer` header
### Mail Flow
1. User composes an email in the SOGo UI
2. Flask backend submits via SMTP to Stalwart (`sogo6-stalwart:25`)
3. In production, Stalwart delivers to external recipients. In this test stack, MailDev catches all outbound mail on port 25 and exposes a web UI at `http://localhost:1080` for inspection
4. Incoming mail (in production) is stored by Stalwart and served via IMAP to the SOGo backend
### Calendar and Contacts
SOGo 6 implements CalDAV and CardDAV servers. Calendar events and address book entries are stored in PostgreSQL. LDAP contacts are read from OpenLDAP in real-time.
---
## Deployment
### Prerequisites
- Docker and Docker Compose v2.20+
- Git
- ~2 GB free RAM (tested on a 1 GB DigitalOcean droplet)
### Step 1: Clone and Build
```bash
git clone https://github.com/tobias-weiss-ai-xr/sogo6-stalwart-openldap-dockerized.git
cd sogo6-stalwart-openldap-dockerized
bash sogo6/scripts/setup.sh
The setup script:
secrets/sogo6.vault.env, gitignored)sogo6/nginx/certs/)docker compose up -d
Docker Compose starts services in dependency order — PostgreSQL, Redis, LDAP, and Stalwart become healthy before the Flask backend starts, and the backend must be healthy before the Next.js frontend launches.
bash sogo6/scripts/init-sogo6.sh
This script calls the Admin API to configure:
example.orgdocker compose ps # Alle 8 Services sind healthy
curl http://localhost:3000/env # Next.js Frontend antwortet
curl http://localhost:5001/api/user/v1/system # Flask API antwortet
curl http://localhost:1080 # MailDev Web-UI
| Service | URL |
|---|---|
| SOGo 6 UI | http://localhost:3000 |
| User API | http://localhost:5001/api/user/v1/system |
| Admin API | http://localhost:5001/api/admin/v1/auth/login |
| Swagger (User) | http://localhost:5001/swagger-basic |
| Swagger (Admin) | http://localhost:5001/swagger-admin |
| MailDev | http://localhost:1080 |
| Nginx (TLS) | https://localhost |
| Benutzername | Passwort | Rolle |
|---|---|---|
testuser@example.org | password123 | Standard-Benutzer |
testadmin@example.org | password123 | Admin (sogoAdminRole) |
testuser2@example.org | password123 | Standard-Benutzer |
Das Repository enthält 129 shell-basierte Integrationstests, die außer bash, curl und openssl keine weiteren Voraussetzungen haben. Diese decken Folgendes ab:
| Suite | Checks | Was validiert wird |
|---|---|---|
docker-test.sh | 6 | Container-Health, Neustarts, Uptime, Netzwerkverbindung |
api-test.sh | 15 | API-Health, Swagger, Auth (alle 3 Benutzer), Negativtests |
smtp-test.sh | 14 | SMTP EHLO, Submission, IMAP-Login, Sieve, TLS-Protokoll |
ldap-test.sh | 6 | LDAP-Erreichbarkeit, vorhandene Benutzer, Mail-Attribute |
postgres-test.sh | 6 | DB-Konnektivität, Schema, Serverversion |
nginx-test.sh | 8 | HTTP/HTTPS-Proxy, TLS-Zertifikat, Security-Header |
redis-test.sh | 7 | PING, SET/GET, Speicher, verbundene Clients |
integration-test.sh | 9 | Cross-Service Token-Flow, CORS, DNS-Auflösung |
security-test.sh | 12 | Port-Exposition, Container-User, TLS-Validität, Secrets-Leakage |
script-test.sh | 15 | Konfigurationsintegrität, Shebangs, JSON-Validität, Cert-Key-Match |
Führen Sie alles mit bash tests/run-all-tests.sh aus. Python-Integrationstests (pytest + psycopg2) und Playwright E2E-Tests sind als optionale Extras verfügbar.
bash sogo6/scripts/manage-secrets.sh # Generate vault
bash sogo6/scripts/manage-secrets.sh --list # List masked secrets
bash sogo6/scripts/manage-secrets.sh --env-file # Export for docker-compose
bash sogo6/scripts/backup.sh
Erstellt ein mit Zeitstempel versehenes Archiv aller Docker-Volumes (PostgreSQL, Redis, Stalwart, LDAP-Daten und Konfiguration) unter ./backups/.
docker compose down -v
docker compose up -d
bash sogo6/scripts/init-sogo6.sh
Ersetzen Sie für Produktionstests die selbstsignierten Zertifikate in sogo6/nginx/certs/ durch echte Zertifikate und generieren Sie diese neu:
bash sogo6/scripts/gen-certs.sh
| Aspekt | SOGo 5 | SOGo 6 |
|---|---|---|
| Frontend | AngularJS | Next.js 16, React 19, TypeScript |
| Backend | Objective-C / GNUstep | Python 3.10+, Flask, Gunicorn |
| Konfiguration | sogo.conf Datei | Prozesseinstellungen (env/file) + dynamische Einstellungen (DB + Admin API) |
| Cache | Memcached | Redis (Session-Cache + Celery Task-Queue) |
| Datenbank | MySQL/MariaDB/PostgreSQL | PostgreSQL erforderlich |
| Admin-Tool | sogo-tool CLI | RESTful Admin API + Web-UI |
| Mobile Sync | ActiveSync | MAPI over HTTP (ActiveSync für nach dem Release geplant) |
| Architektur | Monolithisch | Modular (API → Interface → Module → Manager) |
| Deployment | Einzelner Container | Mindestens drei Container (UI, Server, Agent) |
| Migration | — | Skripte vorhanden; alte sogo.conf via Admin API importierbar |
Das SOGo-Team gab auf der FOSDEM 2026 bekannt, dass die öffentliche Beta für den Sommer 2026 geplant ist. Das erste Release umfasst die vollständige Web-Applikation (Mail, Kalender, Kontakte), wird jedoch anfangs keinen Desktop-Sync-Server enthalten.
Der gesamte Code ist unter der MIT-Lizenz Open Source: