Installationsbeispiel: Ubuntu 24.04¶
Dieser Leitfaden führt durch eine vollständige On-Premise-Installation auf einem einzelnen Ubuntu 24.04-Server, mit PostgreSQL auf dem Host, MinIO als S3-kompatibler Speicher und nginx als TLS-Reverse-Proxy. Er basiert auf einer realen, funktionierenden Bereitstellung.
Passen Sie ihn an Ihre Umgebung an — die Kernleitfäden Installation und Konfiguration bleiben die Referenz.
Bevorzugen Sie Automatisierung?
Ein Coding-AI-Agent kann diese gesamte Installation für Sie in einem einzigen Prompt ausführen. Siehe AI-gestützte Installation.
Architektur¶
Browser → nginx (:443, TLS) → Docker-Container (api :8080, web :8081)
→ PostgreSQL (:5432, auf Host)
→ MinIO (:9000, auf Host)
Alle Dienste laufen auf einem einzelnen Server. Container erreichen Host-Dienste über host.docker.internal.
1. Docker Engine¶
Installieren Sie Docker aus dem offiziellen Repository:
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
Fügen Sie Ihren Benutzer zur docker-Gruppe hinzu (melden Sie sich ab und wieder an, damit es wirksam wird):
2. PostgreSQL 16¶
Erstellen Sie die Datenbank, den Benutzer und die erforderlichen Erweiterungen:
sudo -u postgres psql <<'SQL'
CREATE DATABASE kanap;
CREATE USER kanap WITH PASSWORD 'your-secure-password' NOSUPERUSER NOBYPASSRLS;
GRANT ALL PRIVILEGES ON DATABASE kanap TO kanap;
SQL
sudo -u postgres psql -d kanap <<'SQL'
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
GRANT ALL ON SCHEMA public TO kanap;
SQL
Verbindungen von Docker-Containern zulassen¶
Bearbeiten Sie /etc/postgresql/16/main/postgresql.conf:
Bearbeiten Sie /etc/postgresql/16/main/pg_hba.conf — fügen Sie vor den Standard-Host-Regeln hinzu:
Dies erlaubt Verbindungen vom Docker-Bridge-Netzwerk. Verwenden Sie für höhere Sicherheit das exakte Docker-Subnetz (docker network inspect bridge, um es zu finden).
Starten Sie PostgreSQL neu und überprüfen Sie:
sudo systemctl restart postgresql
PGPASSWORD='your-secure-password' psql -h 127.0.0.1 -U kanap -d kanap -c "SELECT 1;"
3. MinIO (S3-kompatibler Speicher)¶
Laden Sie den MinIO-Server und -Client herunter:
wget -q https://dl.min.io/server/minio/release/linux-amd64/minio -O /tmp/minio
sudo mv /tmp/minio /usr/local/bin/minio
sudo chmod +x /usr/local/bin/minio
wget -q https://dl.min.io/client/mc/release/linux-amd64/mc -O /tmp/mc
sudo mv /tmp/mc /usr/local/bin/mc
sudo chmod +x /usr/local/bin/mc
Erstellen Sie einen Systembenutzer und ein Datenverzeichnis:
sudo useradd -r -s /sbin/nologin minio-user
sudo mkdir -p /opt/minio/data
sudo chown -R minio-user:minio-user /opt/minio
Konfigurieren Sie MinIO — erstellen Sie /etc/default/minio:
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=your-minio-admin-password
MINIO_VOLUMES="/opt/minio/data"
MINIO_OPTS="--address :9000 --console-address :9001"
Erstellen Sie den systemd-Dienst — /etc/systemd/system/minio.service:
[Unit]
Description=MinIO Object Storage
After=network-online.target
Wants=network-online.target
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Aktivieren und starten Sie MinIO, dann erstellen Sie den Bucket und ein Servicekonto:
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
mc alias set localminio http://127.0.0.1:9000 minioadmin your-minio-admin-password
mc mb localminio/kanap-files
mc admin user svcacct add localminio minioadmin \
--access-key your-s3-access-key \
--secret-key your-s3-secret-key
4. KANAP klonen und konfigurieren¶
cd /opt # oder Ihr bevorzugtes Verzeichnis
git clone https://github.com/kanap-it/kanap.git
cd kanap
cp infra/.env.onprem.example .env
Bearbeiten Sie .env mit Ihren Werten. Hier ist ein funktionierendes Beispiel für dieses Setup:
# DEPLOYMENT MODE
DEPLOYMENT_MODE=single-tenant
# TENANT
DEFAULT_TENANT_SLUG=default
DEFAULT_TENANT_NAME=My Organization
# ADMIN CREDENTIALS
ADMIN_EMAIL=admin@company.com
ADMIN_PASSWORD=ChangeThisAfterFirstLogin!
# SECURITY
JWT_SECRET=<output of: openssl rand -hex 32>
# APPLICATION URL
APP_BASE_URL=https://kanap.company.com
# CORS
CORS_ORIGINS=https://kanap.company.com
# DATABASE — host.docker.internal reaches the host from inside Docker
DATABASE_URL=postgres://kanap:your-secure-password@host.docker.internal:5432/kanap?sslmode=disable
# STORAGE — MinIO on the host
S3_ENDPOINT=http://host.docker.internal:9000
S3_BUCKET=kanap-files
S3_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-s3-access-key
AWS_SECRET_ACCESS_KEY=your-s3-secret-key
S3_FORCE_PATH_STYLE=true
# EMAIL (optional — choose one transport to enable invitations, password reset, notifications)
# RESEND_API_KEY=re_xxxxx
# RESEND_FROM_EMAIL=KANAP <noreply@yourdomain.com>
# SMTP (single-tenant / on-prem only)
# SMTP_HOST=smtp.company.com
# SMTP_PORT=587
# SMTP_SECURE=false
# SMTP_USER=noreply@company.com
# SMTP_PASSWORD=your-smtp-password
# SMTP_FROM=KANAP <noreply@company.com>
Wichtig: Generieren Sie ein echtes JWT-Secret (openssl rand -hex 32) — verwenden Sie keine Beispielwerte.
Wenn Sie auf KANAP über die IP-Adresse anstelle einer Domäne zugreifen, setzen Sie APP_BASE_URL und CORS_ORIGINS auf https://YOUR_IP.
Wenn Sie SMTP anstelle von Resend verwenden, stellen Sie sicher, dass der SMTP-Server E-Mails von der SMTP_FROM-Adresse akzeptiert und dass die SPF-, DKIM- und DMARC-Einstellungen Ihrer Domäne bereits eingerichtet sind, falls Nachrichten Ihr internes Netzwerk verlassen.
5. Bauen und starten¶
cd /opt/kanap
docker build -t kanap-api:latest ./backend
docker build -t kanap-web:latest ./frontend
docker compose -f infra/compose.onprem.yml up -d
Überprüfen Sie die Logs — warten Sie auf die Meldung „Application started":
Beim ersten Start führt KANAP Migrationen aus und erstellt automatisch den Mandanten, den Admin-Benutzer und das Abonnement.
6. Nginx-Reverse-Proxy mit TLS¶
TLS-Zertifikat¶
Wenn Sie eine Domäne mit einem gültigen Zertifikat haben, verwenden Sie diese. Andernfalls generieren Sie ein selbstsigniertes Zertifikat:
sudo mkdir -p /etc/ssl/kanap
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/ssl/kanap/server.key \
-out /etc/ssl/kanap/server.crt \
-subj "/CN=kanap.company.com" \
-addext "subjectAltName=DNS:kanap.company.com"
Für IP-basierten Zugriff (keine Domäne) ersetzen Sie die Werte für -subj und -addext:
Site-Konfiguration¶
Erstellen Sie /etc/nginx/sites-available/kanap:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name kanap.company.com;
ssl_certificate /etc/ssl/kanap/server.crt;
ssl_certificate_key /etc/ssl/kanap/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
client_max_body_size 20m;
# Canonicalize /api → /api/
location = /api { return 301 /api/; }
# API: strip /api prefix before proxying
location ^~ /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_redirect off;
}
# Everything else → SPA
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
}
server {
listen 80;
listen [::]:80;
server_name kanap.company.com;
return 301 https://$host$request_uri;
}
Aktivieren Sie die Site und starten Sie nginx neu:
sudo ln -sf /etc/nginx/sites-available/kanap /etc/nginx/sites-enabled/kanap
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx
7. Verifizieren¶
# API-Health-Check
curl -sk https://kanap.company.com/api/health
# Erwartet: {"status":"ok"}
# Frontend
curl -sk -o /dev/null -w "%{http_code}" https://kanap.company.com/
# Erwartet: 200
8. Erste Anmeldung¶
- Öffnen Sie Ihre KANAP-URL in einem Browser (akzeptieren Sie die Zertifikatswarnung, wenn Sie selbstsigniertes TLS verwenden)
- Melden Sie sich mit
ADMIN_EMAIL/ADMIN_PASSWORDaus.envan - Ändern Sie sofort das Admin-Passwort über das Benutzerprofil
- Konfigurieren Sie Ihren Organisationsnamen in den Admin-Einstellungen
- Laden Sie zusätzliche Benutzer ein (wenn E-Mail konfiguriert ist)
Dienste-Übersicht¶
| Dienst | Verwaltet von | Konfigurations-Standort |
|---|---|---|
| Docker | systemd | — |
| PostgreSQL | systemd | /etc/postgresql/16/main/postgresql.conf |
| MinIO | systemd | /etc/default/minio |
| KANAP API | Docker Compose | .env + infra/compose.onprem.yml |
| KANAP Web | Docker Compose | .env + infra/compose.onprem.yml |
| nginx | systemd | /etc/nginx/sites-available/kanap |
Nützliche Befehle¶
# Logs anzeigen
docker compose -f infra/compose.onprem.yml logs -f
# KANAP neu starten
docker compose -f infra/compose.onprem.yml restart
# KANAP stoppen
docker compose -f infra/compose.onprem.yml down
# Nach einem Update neu bauen
git pull origin main
docker build -t kanap-api:latest ./backend
docker build -t kanap-web:latest ./frontend
docker compose -f infra/compose.onprem.yml up -d
# Alle Dienste prüfen
sudo systemctl status postgresql nginx minio
docker compose -f infra/compose.onprem.yml ps