Warum SOGo selbst hosten?
SOGo (Scalable OpenGroupware.org) ist eine Open-Source-Groupware-Lösung mit Webmail, Kalender (CalDAV), Kontakten (CardDAV) und ActiveSync-Unterstützung. Perfekt als selbst-gehosteter Ersatz für Google Workspace oder Microsoft 365 – komplett unter eigener Kontrolle.
In dieser Anleitung baust du SOGo komplett von Source auf einem ARM64-Server (z.B. Raspberry Pi 5, Ampere, AWS Graviton) und integrierst es mit ISPConfig und deinem eigenen Mailserver – alles als Docker-Compose-Stack.
Architektur
┌──────────────┐
│ Nginx │ (SSL, Reverse Proxy)
│ :443 │
└──────┬───────┘
│
┌──────▼───────┐
│ Apache │ (SOGo VirtualHost)
│ :80 │
└──┬───────┬──┘
│ │
┌─────────────▼─┐ ┌──▼─────────────┐
│ SOGo (sogod) │ │ Static Files │
│ Port 20000 │ │ /WebServerRes. │
└───────┬───────┘ └────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌───▼────┐ ┌────▼────┐ ┌─────▼──────┐
│PostgreSQL│ │Memcached│ │ Sphinx │
│DB :5432 │ │ :11211 │ │ Fulltext │
└──────────┘ └─────────┘ │ :9306/9312 │
└────────────┘
1. Voraussetzungen
- ARM64-Server mit Ubuntu 24.04 LTS (Raspberry Pi 5, VPS, etc.)
- Docker & Docker Compose installiert
- ISPConfig (für Mailserver-Integration und User-Verwaltung)
- Mailserver mit IMAP/SMTP/Sieve (z.B. Dovecot + Postfix)
- Mindestens 5 GB freier Speicher
2. Multi-Stage Dockerfile (Source Build für ARM64)
Da es keine offiziellen SOGo ARM64-Binaries gibt, kompilieren wir SOPE und SOGo selbst. Das Multi-Stage-Dockerfile hält das finale Image schlank:
FROM ubuntu:24.04 AS builder
RUN apt-get update && apt-get install -y --no-install-recommends
build-essential gobjc gobjc++ gnustep-make gnustep-base-runtime
gnustep-base-common libgnustep-base-dev libxml2-dev libldap2-dev
libpq-dev default-libmysqlclient-dev libssl-dev libcurl4-openssl-dev
libsbjson-dev zlib1g-dev libsodium-dev libzip-dev uuid-dev
libmemcached-dev libytnef0-dev wget ca-certificates pkg-config
WORKDIR /build
# SOPE Framework
RUN wget -q https://packages.sogo.nu/sources/SOPE-5.12.9.tar.gz -O SOPE.tar.gz
&& tar xzf SOPE.tar.gz
&& cd SOPE-5.12.9
&& . /usr/share/GNUstep/Makefiles/GNUstep.sh
&& ./configure && make -j$(nproc) && make install && ldconfig
# SOGo Application
RUN wget -q https://packages.sogo.nu/sources/SOGo-5.12.9.tar.gz -O SOGo.tar.gz
&& tar xzf SOGo.tar.gz
&& cd SOGo-5.12.9
&& . /usr/share/GNUstep/Makefiles/GNUstep.sh
&& ./configure && make -j$(nproc) && make install
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends
gnustep-base-runtime gnustep-base-common libgnustep-base-dev
libxml2-dev libpq-dev libssl-dev libcurl4-openssl-dev libmemcached-dev
apache2 cron curl sudo ca-certificates tzdata netcat-openbsd
# Copy compiled libs from builder
COPY --from=builder /usr/local/sbin/ /usr/local/sbin/
COPY --from=builder /usr/local/lib/ /usr/local/lib/
RUN ldconfig
# Fix DNS resolution for linked containers
COPY fix_bind.c /tmp/fix_bind.c
RUN gcc -shared -fPIC -o /usr/local/lib/fix_bind.so /tmp/fix_bind.c -ldl
# Enable Apache modules
RUN a2enmod proxy proxy_http rewrite headers expires setenvif
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
3. docker-compose.yml – Der Komplett-Stack
services:
postgresql:
image: postgres:15-alpine
environment:
POSTGRES_USER: sogo
POSTGRES_PASSWORD: DEIN_SICHERES_PASSWORT
POSTGRES_DB: sogo
POSTGRES_INITDB_ARGS: --encoding=UTF8 --locale=en_US.UTF-8
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sogo"]
interval: 10s
retries: 5
restart: always
sogo:
image: sogo:5.12.9-ubuntu24
depends_on:
postgresql: { condition: service_healthy }
volumes:
- ./sogo.conf:/etc/sogo/sogo.conf:ro
- ./apache-sogo.conf:/etc/apache2/sites-enabled/sogo.conf:ro
- sogo_lib:/var/lib/sogo
- sogo_log:/var/log/sogo
ports:
- "8080:80"
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:80/SOGo/"]
interval: 15s
retries: 5
memcached:
image: memcached:alpine
command: memcached -m 256 -t 4 -c 1024
restart: always
sphinx:
build:
context: .
dockerfile: sphinx-build/Dockerfile
volumes:
- sphinx_data:/var/lib/sphinx
ports:
- "9312:9312"
- "9306:9306"
restart: always
volumes:
postgres_data: {}
sogo_lib: {}
sogo_log: {}
sphinx_data: {}
4. SOGo Konfiguration (sogo.conf)
Die zentrale Konfigurationsdatei. Hier die wichtigsten Abschnitte:
Datenbank (PostgreSQL)
SOGoProfileURL = "postgresql://sogo:DEIN_PASSWORT@postgresql:5432/sogo"; OCSFolderInfoURL = "postgresql://sogo:DEIN_PASSWORT@postgresql:5432/sogo"; OCSSessionsFolderURL = "postgresql://sogo:DEIN_PASSWORT@postgresql:5432/sogo";
Wichtig: Der Connection-String endet auf /sogo (Datenbankname), nicht auf /sogo/table. Letzteres ist ein FATALER Fehler, der zum Crash führt!
IMAP und SMTP
SOGoIMAPServer = "imaps://mail.DEINE-DOMAIN.de:993"; SOGoSMTPServer = "smtp://mail.DEINE-DOMAIN.de:25"; SOGoSieveServer = "sieve://mail.DEINE-DOMAIN.de:4190"; SOGoForceExternalLoginWithEmail = YES;
Memcached und Performance
SOGoMemcachedHost = "memcached:11211"; WOWorkersCount = 10; SOGoMaximumMessageSizeLimit = 102400; WOMaxUploadSize = 102400;
ActiveSync (für Smartphones)
SOGoEnableActiveSync = YES; SOGoMaximumPingInterval = 10; SOGoMaximumSyncInterval = 30; SOGoMaximumSyncWindowSize = 100;
Sicherheit
SOGoEncryptionKey = "DEIN_32_ZEICHEN_ZUFALLSSTRING"; SOGoXSRFValidationEnabled = YES; SOGoEnableCookieSecure = YES; WOSessionTimeout = 3600;
Generiere den Encryption Key mit: openssl rand -hex 16
Volltextsuche (Sphinx)
SOGoEnableFullTextSearch = YES; SOGoFullTextSearchServer = "sphinx://sphinx:9306";
Optionale Features
SOGoEnableGroupware = YES; // Kalender, Kontakte, Aufgaben SOGoEnableSharedFolders = YES; // Freigegebene Ordner SOGoEnableDelegation = YES; // Rechte delegieren SOGoEnableEMailReceipts = YES; // Lesebestätigungen SOGoEnableTasksSupport = YES; // Aufgabenverwaltung SOGoVacationEnabled = YES; // Abwesenheitsnotizen SOGoForwardEnabled = YES; // E-Mail-Weiterleitung SOGoSieveScriptsEnabled = YES; // Server-seitige Filter SOGoMailComposeMessageType = html; // HTML-E-Mails SOGoLanguage = German; SOGoTimeZone = "Europe/Berlin";
5. ISPConfig Integration – User aus MariaDB lesen
SOGo kann sich direkt mit der ISPConfig-Datenbank verbinden und User authentifizieren. Dazu musst du in ISPConfig einen MySQL-User mit Lesezugriff auf die dbispconfig-Datenbank anlegen:
CREATE USER 'sogoread'@'%' IDENTIFIED BY 'DEIN_PASSWORT'; GRANT SELECT ON dbispconfig.* TO 'sogoread'@'%'; FLUSH PRIVILEGES;
In sogo.conf:
SOGoUserSources = (
{
type = sql;
id = users;
viewURL = "mysql://sogoread:DEIN_PASSWORT@HOST_IP:3306/dbispconfig/sogo_users";
canAuthenticate = YES;
isAddressBook = YES;
userPasswordAlgorithm = "sha512-crypt";
loginFields = (c_uid);
mailFieldNames = (c_mail);
CNFieldName = c_cn;
UIDFieldName = c_uid;
displayName = "Benutzer";
}
);
ISPConfig-Host-Erreichbarkeit: Falls ISPConfig auf dem Docker-Host läuft, verwende host.docker.internal (Docker Desktop) oder die Docker-Gateway-IP 172.17.0.1. Falls ISPConfig in einem anderen Container läuft, verwende den Container-Namen.
6. Apache als interner SOGo-Reverse-Proxy
Innerhalb des Containers läuft Apache als Reverse-Proxy vor SOGo:
<VirtualHost *:80>
ServerName webmail.DEINE-DOMAIN.de
ServerAlias webmail.DEINE-ZWEITE-DOMAIN.de
Alias /SOGo/WebServerResources/ /usr/local/lib/GNUstep/SOGo/WebServerResources/
<Directory /usr/local/lib/GNUstep/SOGo/>
AllowOverride None
Require all granted
</Directory>
<Location /SOGo>
RequestHeader set "x-webobjects-server-port" "443"
RequestHeader set "x-webobjects-server-name" "%{HOST}e"
RequestHeader set "x-webobjects-server-url" "https://%{HOST}e"
RequestHeader unset "x-webobjects-remote-user"
</Location>
ProxyPreserveHost On
ProxyPass /Microsoft-Server-ActiveSync
http://127.0.0.1:20000/SOGo/Microsoft-Server-ActiveSync
retry=60 connectiontimeout=5 timeout=360
ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0 nocanon
ProxyPassReverse /SOGo http://127.0.0.1:20000/SOGo
# .well-known Redirects für CalDAV und CardDAV
RewriteEngine On
RewriteRule ^/.well-known/caldav/?$ /SOGo/dav [R=301]
RewriteRule ^/.well-known/carddav/?$ /SOGo/dav [R=301]
RedirectMatch ^/$ /SOGo
</VirtualHost>
7. Nginx Reverse Proxy (extern, vor dem Container)
Für SSL-Terminierung und Domain-Verwaltung setzt du einen Nginx-Reverse-Proxy VOR den Docker-Container. Beispiel-Serverblock:
server {
listen 443 ssl http2;
server_name webmail.DEINE-DOMAIN.de;
ssl_certificate /etc/ssl/DEINE-DOMAIN/fullchain.pem;
ssl_certificate_key /etc/ssl/DEINE-DOMAIN/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
client_max_body_size 100M;
}
}
8. Entrypoint-Skript
Das Skript startet Cron, Apache und sogod mit korrekten Umgebungsvariablen:
#!/bin/bash
set -e
# Pfade und Rechte
mkdir -p /var/spool/sogo
chown -R sogo:sogo /var/lib/sogo /var/log/sogo /var/run/sogo
chmod 750 /var/lib/sogo /var/log/sogo /var/run/sogo
# Services starten
service cron start
apachectl start
# LD_LIBRARY_PATH für selbst-kompilierte SOGo-Bibliotheken
export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib/sogo:/usr/local/lib/GNUstep"
export LD_PRELOAD="/usr/local/lib/fix_bind.so"
# sogod starten
exec gosu sogo /usr/local/sbin/sogod
-WOWorkersCount 10
-WOListenQueueSize 500
-WOPidFile /var/run/sogo/sogo.pid
-WOLogFile /var/log/sogo/sogo.log
-WONoDetach YES
-WOApplicationBaseURL "https://webmail.DEINE-DOMAIN.de/SOGo"
-WOPort 20000 2>&1
Das LD_PRELOAD mit fix_bind.so behebt ein bekanntes DNS-Problem in SOGo-Containern bei der Auflösung anderer Container-Namen.
9. Datenbank-Initialisierung
PostgreSQL wird mit einer init-db.sql gestartet, die die benötigten Tabellen anlegt. SOGo verwaltet seine Tabellen über die OCS*FolderURL-Parameter automatisch. Für ISPConfig-Benutzer brauchst du eine View sogo_users in der dbispconfig-Datenbank:
CREATE VIEW sogo_users AS
SELECT
email AS c_uid,
login AS c_uid,
CONCAT(vorname, ' ', nachname) AS c_cn,
email AS c_mail,
password AS c_password
FROM mail_user;
10. Bereit bekannte Fehler & Fixes
„PostgreSQL verbindet nicht“
✅ Prüfe, ob das Passwort in beiden Dateien identisch ist: sogo.conf und docker-compose.yml
SOGo startet, aber kein Login möglich
✅ Prüfe die ISPConfig-DB-Erreichbarkeit. Der SOGo-Container muss die MariaDB erreichen können. Teste mit: docker-compose exec sogo nc -zv HOST_IP 3306
„AH00558: Could not reliably determine“ Apache-Warnung
✅ Normal – Apache läuft hinter Nginx. Diese Warnung kann ignoriert werden.
sogod crasht direkt nach Start
✅ Häufigste Ursache: PostgreSQL-URL enthält einen Tabellennamen (z.B. /sogo/sogo_user_profile). Korrekt ist nur der Datenbankname: /sogo
ActiveSync funktioniert nicht
✅ Teste: curl -I https://webmail.DEINE-DOMAIN.de/Microsoft-Server-ActiveSync – sollte HTTP 200 liefern
CalDAV/CardDAV funktioniert nicht
✅ Teste: curl -I https://webmail.DEINE-DOMAIN.de/.well-known/caldav – sollte HTTP 301 Redirect liefern
11. Deployment-Checkliste
sogo.confmit echten Werten befüllen (Passwörter, Domains, ISPConfig-Host)docker-compose.yml: POSTGRES_PASSWORD mit sogo.conf abgleichen- SOGoEncryptionKey generieren:
openssl rand -hex 16 - ISPConfig-View
sogo_usersin MariaDB anlegen - MySQL-User
sogoreadmit SELECT-Rechten anlegen - Nginx-Serverblock für SSL + Reverse-Proxy erstellen
docker-compose up -ddocker-compose ps– alle Container healthy?curl -f https://webmail.DEINE-DOMAIN.de/SOGo/– HTTP 200?- 🎉 Login mit ISPConfig-Mailadresse testen!
12. Wartung & Monitoring
Täglich prüfen:
docker-compose ps docker-compose logs sogo --tail 20 | grep ERROR
Wöchentlich:
docker system df # Speicher-Check docker-compose logs --tail 200
Monatlich:
docker image prune -a # Alte Images entfernen docker volume prune # Ungenutzte Volumes
Backup:
# PostgreSQL-Dump docker-compose exec postgresql pg_dump -U sogo sogo > backup.sql # Volumes sichern tar -czf volumes-backup.tar.gz /var/lib/docker/volumes/sogo_*
Fazit
Du hast jetzt einen vollständigen Groupware-Server mit Webmail, Kalender, Kontakten, Aufgaben und ActiveSync – komplett unter eigener Kontrolle, auf ARM64, mit ISPConfig-Integration und Docker Compose.
Das Setup funktioniert produktiv mit: Ubuntu 24.04 LTS, SOGo 5.12.9 (Source Build), PostgreSQL 15, Memcached, Apache und Nginx als Reverse-Proxy.