Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 26.06.2026 · 12 min Lesezeit

Frappe HRMS mit Docker installieren: Vollständiges Open-Source-HR-System mit Gehaltsabrechnung

Frappe HRMS: 13+ HR-Module, Gehaltsabrechnung und Onboarding – kostenlos, selbst gehostet, DSGVO-konform. Diese Anleitung zeigt den produktionsreifen Docker-Weg mit Custom-Image-Build und vollständiger Schritt-für-Schritt-Einrichtung.

Frappe HRMS mit Docker installieren als modernes Open Source HR System mit Mitarbeiterverwaltung, Zeiterfassung, Abwesenheiten, Gehaltsabrechnung, Datenbank und Admin Dashboard für Self Hosting Unternehmen.

Wer im DACH-Raum ein vollständiges HR-System sucht, zahlt bei Personio oder Sage HR schnell vierstellige Jahresbeträge – und bekommt trotzdem nicht alles. Frappe HRMS (8.100+ GitHub-Sterne, 311 Releases, aktiv gepflegt) bietet auf Basis des Frappe-Frameworks und ERPNext über 13 Module: Mitarbeiterverwaltung, Urlaubsplanung, Gehaltsabrechnung, Performance-Management, Expense Claims, Onboarding und Offboarding, Shift-Management, Recruitment, Loan Management und mehr. Das System ist mandantenfähig, API-first und vollständig browserbasiert. Diese Anleitung richtet sich an IT-Verantwortliche und DevOps-Engineers in wachsenden Unternehmen (10–500 MA), die eine selbst gehostete, wartbare HR-Lösung auf einem beliebigen Linux-Host via Docker Compose betreiben wollen.

Voraussetzungen

  1. Docker Engine v23.0+ (BuildKit ist ab dieser Version Standard) und Docker Compose v2 (docker compose, nicht docker-compose) auf dem Host installiert – siehe Docker und Docker Compose auf Linux installieren
  2. Linux-Host, VM oder NAS mit Docker-Unterstützung (Ubuntu 22.04/24.04 LTS empfohlen; macOS mit Docker Desktop oder Windows mit WSL2 funktionieren ebenfalls)
  3. Mindestens 4 GB RAM (8 GB empfohlen), 4 CPU-Kerne, 30 GB freier SSD-Speicher – der vollständige Stack benötigt diese Ressourcen für stabile Payroll-Läufe; mit weniger RAM können Worker-Prozesse unter Last abstürzen (OOMKilled)
  4. Internetzugang beim Build: Der Image-Build lädt Python-Pakete und JavaScript-Abhängigkeiten von GitHub und PyPI herunter
  5. Git zum Klonen des frappe_docker-Repositorys
  6. Optional: einen Reverse Proxy (Traefik, Nginx Proxy Manager) für HTTPS mit eigenem Domainnamen – etwa über Traefik als Docker-Reverse-Proxy einrichten

Schritt 1: frappe_docker klonen und apps.json erstellen

Frappe HRMS wird nicht als fertiges Image bereitgestellt. Du musst ein eigenes Custom-Image bauen, das ERPNext und HRMS als Frappe-Apps enthält. Basis dafür ist das offizielle frappe_docker-Repository. Klone es zunächst und lege den Projektordner an:

mkdir -p /opt/frappe-hrms
cd /opt/frappe-hrms
git clone https://github.com/frappe/frappe_docker.git
cd frappe_docker

Erstelle jetzt die apps.json direkt im frappe_docker-Verzeichnis. Diese Datei legt fest, welche Frappe-Apps ins Custom-Image eingebaut werden. Für HRMS sind ERPNext und HRMS zwingend erforderlich – HRMS hat ERPNext als Abhängigkeit für die Buchhaltungsintegration:

cat > apps.json <<'EOF'
[
  {
    "url": "https://github.com/frappe/erpnext",
    "branch": "version-16"
  },
  {
    "url": "https://github.com/frappe/hrms",
    "branch": "version-16"
  }
]
EOF

Verifizieren: Prüfe, ob die Datei korrekt angelegt wurde:

cat apps.json

Erwartetes Ergebnis: Das JSON-Array mit beiden App-Einträgen (erpnext, hrms) erscheint vollständig und ist syntaktisch korrekt.

Schritt 2: Custom-Image mit BuildKit-Secret bauen

Seit Docker Engine v23.0 ist BuildKit Standard. Der offizielle Build-Befehl nutzt --secret=id=apps_json,src=apps.json – so werden keine Zugangstokens in der Image-History sichtbar (im Gegensatz zur alten APPS_JSON_BASE64-Methode aus älteren Community-Guides). Der Build lädt alle Apps von GitHub herunter und kompiliert JavaScript-Assets; das dauert je nach Internetgeschwindigkeit und Hardware 15–30 Minuten:

docker build \
  --no-cache \
  --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \
  --build-arg=FRAPPE_BRANCH=version-16 \
  --secret=id=apps_json,src=apps.json \
  --tag=custom-hrms:1.0 \
  --file=images/layered/Containerfile .

Hinweis für ARM64-Hosts (Apple M-Chips, Raspberry Pi 5): Die Standard-compose.yaml erzwingt linux/amd64. Für ARM64 muss --platform=linux/arm64 ergänzt werden. ARM64 mit mindestens 8 GB RAM ist Voraussetzung; ARMv7 ist unzureichend.

Hinweis zu RAM beim Build: Unter 4 GB RAM kann es zu Segmentation Faults kommen (bekanntes Issue frappe_docker #1373). Lösung: mehr RAM zuweisen oder explizit --build-arg=NODE_VERSION=18.12.0 ergänzen.

Verifizieren:

docker images custom-hrms

Erwartetes Ergebnis: Eine Zeile mit custom-hrms, Tag 1.0 und einer Imagegröße von ca. 4–6 GB. Ist das Image nicht vorhanden, ist der Build fehlgeschlagen – prüfe die Build-Logs auf Netzwerkfehler oder OOMKilled-Meldungen.

Schritt 3: Projektordner und .env-Datei anlegen

Wechsle in deinen Arbeitsordner und lege die .env-Datei an. Ändere zwingend die Passwörter vor dem ersten Start – der MariaDB-Default aus der Beispiel-Konfiguration ist ein erhebliches Sicherheitsrisiko:

cd /opt/frappe-hrms
# /opt/frappe-hrms/.env
# ── Custom-Image (nach eigenem Build) ────────────────────────
CUSTOM_IMAGE=custom-hrms
CUSTOM_TAG=1.0
PULL_POLICY=missing

# ── Datenbank ────────────────────────────────────────────────
# PFLICHT: sicheres Passwort setzen (mind. 16 Zeichen, Sonderzeichen)
DB_PASSWORD=Dein_Sicheres_DB_Passwort_2026!

# ── Gunicorn (Worker-Formel: 2 x CPU-Kerne + 1) ─────────────
# Beispiel 4-Kern-Server: 9 Worker
GUNICORN_WORKERS=9
GUNICORN_THREADS=4
GUNICORN_TIMEOUT=120

# ── Web-Port ─────────────────────────────────────────────────
HTTP_PUBLISH_PORT=8080

# ── Optionale Einstellungen ───────────────────────────────────
# CLIENT_MAX_BODY_SIZE=50m
# PROXY_READ_TIMEOUT=120s
# FRAPPE_SITE_NAME_HEADER=meinefirma.localhost
# LETSENCRYPT_EMAIL=admin@meinefirma.de

Verifizieren:

grep -E "CUSTOM_IMAGE|DB_PASSWORD|PULL_POLICY" /opt/frappe-hrms/.env

Erwartetes Ergebnis: Alle drei Variablen erscheinen mit deinen gesetzten Werten. PULL_POLICY=missing ist zwingend – ohne diesen Wert versucht Docker, das lokal gebaute Image aus einer Registry zu pullen, und scheitert mit „manifest unknown".

Schritt 4: compose.yaml anlegen

Lege die compose.yaml in /opt/frappe-hrms/ an. Die Datei definiert alle 8 Dienste des Stacks. Achte auf die kompakte Tabelle der Eckdaten:

DienstImageBeschreibung
frontendcustom-hrms:1.0Nginx, exponiert Port 8080
backendcustom-hrms:1.0Gunicorn/WSGI, intern Port 8000
websocketcustom-hrms:1.0Node.js/Socket.IO, intern Port 9000
queue-shortcustom-hrms:1.0Worker für kurze Jobs
queue-longcustom-hrms:1.0Worker für lange Jobs (Payroll)
schedulercustom-hrms:1.0Zeitgesteuerte Frappe-Jobs
dbmariadb:11.8MariaDB, nur intern
redis-cacheredis:8.6-alpineSession-Cache
redis-queueredis:8.8-alpineJob-Queue mit Persistenz
EinstellungWert
HTTP-Port (extern)8080 (konfigurierbar via HTTP_PUBLISH_PORT)
HTTPS-Port (optional)443 (mit Traefik-Overlay)
Volume: Site-Datensites:/home/frappe/frappe-bench/sites
Volume: MariaDBdb-data:/var/lib/mysql
Volume: Redis-Queueredis-queue-data:/data
# /opt/frappe-hrms/compose.yaml
# Frappe HRMS – Docker Compose (plattformneutral)
# Voraussetzung: Custom-Image custom-hrms:1.0 muss gebaut sein (Schritt 2)

x-customizable-image: &customizable_image
  image: ${CUSTOM_IMAGE:-custom-hrms}:${CUSTOM_TAG:-1.0}
  pull_policy: ${PULL_POLICY:-missing}

x-depends-on-configurator: &depends_on_configurator
  depends_on:
    configurator:
      condition: service_completed_successfully

x-backend-defaults: &backend_defaults
  <<: [*customizable_image, *depends_on_configurator]
  restart: unless-stopped
  volumes:
    - sites:/home/frappe/frappe-bench/sites

services:
  configurator:
    <<: *customizable_image
    restart: on-failure
    entrypoint:
      - bash
      - -c
    command:
      - >
        ls -1 apps/ | echo "installed apps" &&
        bench set-config -g db_host $$DB_HOST &&
        bench set-config -gp db_port $$DB_PORT &&
        bench set-config -g redis_cache "redis://$$REDIS_CACHE" &&
        bench set-config -g redis_queue "redis://$$REDIS_QUEUE" &&
        bench set-config -gp socketio_port $$SOCKETIO_PORT;
    environment:
      DB_HOST: ${DB_HOST:-db}
      DB_PORT: ${DB_PORT:-3306}
      REDIS_CACHE: ${REDIS_CACHE:-redis-cache:6379}
      REDIS_QUEUE: ${REDIS_QUEUE:-redis-queue:6379}
      SOCKETIO_PORT: 9000
    volumes:
      - sites:/home/frappe/frappe-bench/sites
    depends_on:
      db:
        condition: service_healthy
      redis-cache:
        condition: service_started
      redis-queue:
        condition: service_started

  backend:
    <<: *backend_defaults
    environment:
      GUNICORN_WORKERS: ${GUNICORN_WORKERS:-2}
      GUNICORN_THREADS: ${GUNICORN_THREADS:-4}
      GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-120}

  frontend:
    <<: *customizable_image
    restart: unless-stopped
    command: nginx-entrypoint.sh
    environment:
      BACKEND: backend:8000
      SOCKETIO: websocket:9000
      FRAPPE_SITE_NAME_HEADER: ${FRAPPE_SITE_NAME_HEADER:-$$host}
      UPSTREAM_REAL_IP_ADDRESS: ${UPSTREAM_REAL_IP_ADDRESS:-127.0.0.1}
      UPSTREAM_REAL_IP_HEADER: ${UPSTREAM_REAL_IP_HEADER:-X-Forwarded-For}
      UPSTREAM_REAL_IP_RECURSIVE: ${UPSTREAM_REAL_IP_RECURSIVE:-off}
      PROXY_READ_TIMEOUT: ${PROXY_READ_TIMEOUT:-120}
      CLIENT_MAX_BODY_SIZE: ${CLIENT_MAX_BODY_SIZE:-50m}
    volumes:
      - sites:/home/frappe/frappe-bench/sites
    ports:
      - "${HTTP_PUBLISH_PORT:-8080}:8080"
    depends_on:
      - backend
      - websocket

  websocket:
    <<: [*customizable_image, *depends_on_configurator]
    restart: unless-stopped
    command: node /home/frappe/frappe-bench/apps/frappe/socketio.js
    volumes:
      - sites:/home/frappe/frappe-bench/sites

  queue-short:
    <<: *backend_defaults
    command: bench worker --queue short,default

  queue-long:
    <<: *backend_defaults
    command: bench worker --queue long,default,short

  scheduler:
    <<: *backend_defaults
    command: bench schedule

  db:
    image: mariadb:11.8
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-ChangeMeNow123!}
      MARIADB_AUTO_UPGRADE: 1
    volumes:
      - db-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 5s
      interval: 5s
      timeout: 5s
      retries: 5
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --skip-character-set-client-handshake

  redis-cache:
    image: redis:8.6-alpine
    restart: unless-stopped

  redis-queue:
    image: redis:8.8-alpine
    restart: unless-stopped
    volumes:
      - redis-queue-data:/data

volumes:
  sites:
  db-data:
  redis-queue-data:

Verifizieren:

docker compose -f /opt/frappe-hrms/compose.yaml config --quiet && echo "YAML valide"

Erwartetes Ergebnis: YAML valide ohne Fehlermeldung. Tauchen Syntaxfehler auf, prüfe Einrückungen und YAML-Anchors (& / <<:).

Schritt 5: Stack starten

Starte alle Dienste im Hintergrund. Der erste Start dauert etwas länger, weil MariaDB seine Datenbankdateien initialisiert und der Configurator-Container die globale Bench-Konfiguration schreibt:

cd /opt/frappe-hrms
docker compose up -d

Warte ca. 60 Sekunden, bis MariaDB den Healthcheck besteht und der Configurator durchgelaufen ist. Dann prüfe den Status:

docker compose ps

Verifizieren: Erwartetes Ergebnis – alle dauerhaften Dienste müssen „running" zeigen, configurator darf „Exited (0)" zeigen (das ist korrekt, er ist ein One-Shot-Container):

NAME                        STATUS
frappe-hrms-backend-1       running
frappe-hrms-db-1            running (healthy)
frappe-hrms-frontend-1      running
frappe-hrms-queue-long-1    running
frappe-hrms-queue-short-1   running
frappe-hrms-redis-cache-1   running
frappe-hrms-redis-queue-1   running
frappe-hrms-scheduler-1     running
frappe-hrms-websocket-1     running
frappe-hrms-configurator-1  Exited (0)

Prüfe außerdem die Logs des Backends auf Fehler:

docker compose logs backend --tail=20

Kein Fehler zu Port, Volume oder Image sollte erscheinen. Taucht No module named hrms auf, wurde HRMS nicht in apps.json aufgeführt oder der Image-Build nicht erneut ausgeführt.

Schritt 6: Frappe-Site erstellen und HRMS installieren

Nach docker compose up ist der Stack gestartet, aber noch leer – es gibt noch keine Datenbank und keine installierte Anwendung. Dieser Schritt ist der häufigste Fallstrick: Ohne bench new-site zeigt der Browser nur eine leere Seite oder „Site does not exist".

Öffne eine Shell im Backend-Container:

docker compose exec backend bash

Führe innerhalb des Containers folgende Befehle aus. Ersetze meinefirma.localhost durch deinen gewünschten Site-Namen. Das MariaDB-Root-Passwort muss exakt dem in .env gesetzten DB_PASSWORD entsprechen:

# Site anlegen (Datenbank + Admin-Account erstellen)
bench new-site meinefirma.localhost \
  --mariadb-root-password Dein_Sicheres_DB_Passwort_2026! \
  --admin-password MeinHRMS_AdminPW!

# ERPNext installieren (Pflicht als HRMS-Abhängigkeit)
bench --site meinefirma.localhost install-app erpnext

# HRMS installieren
bench --site meinefirma.localhost install-app hrms

# Host-Namen für korrekte URL-Auflösung setzen
bench --site meinefirma.localhost set-config host_name "http://localhost:8080"

# Zeitzone für korrekte Lohnperioden setzen (DACH-empfohlen)
bench --site meinefirma.localhost set-config time_zone "Europe/Berlin"

exit

Die Installation von ERPNext und HRMS dauert je nach Server 5–15 Minuten. Alle Datenbankmigrationen werden automatisch ausgeführt.

Verifizieren:

curl -I http://localhost:8080

Erwartetes Ergebnis: HTTP/1.1 200 OK oder HTTP/1.1 302 Found (Redirect zur Login-Seite). Öffne dann im Browser http://localhost:8080 – du siehst die Frappe-Login-Maske. Login: Administrator / das bei --admin-password gesetzte Passwort (nicht das MariaDB-Root-Passwort!).

docker compose logs frontend --tail=10

Keine Nginx-Fehler sollten erscheinen. Taucht upstream connect error auf, ist der Backend-Container noch nicht bereit – warte 30 Sekunden und wiederhole den Aufruf.

Schritt 7: HRMS einrichten und erste Mitarbeiterdaten anlegen

Nach dem Login führt dich der Frappe-Setup-Wizard durch die Grundkonfiguration: Firmenname, Währung (EUR für DACH), Land und Zeitzone. Aktiviere danach das HRMS-Modul über Apps > HRMS.

Die wichtigsten ersten Schritte in HRMS:

  1. Unternehmen konfigurieren: Unter „HR Settings" Währung (EUR), Land und steuerrelevante Einstellungen prüfen
  2. Abteilungen anlegen: HR > Abteilung > Neu
  3. Mitarbeiter erfassen: HR > Mitarbeiter > Neu (mit Gehaltsstufe, Abteilung, Eintrittsdatum)
  4. Urlaubstypen definieren: HR > Urlaubstyp (z. B. Jahresurlaub, Krankheit, Überstundenausgleich)
  5. Gehaltskomponenten einrichten: Payroll > Gehaltskomponente (Grundgehalt, Sozialabgaben, Boni)

Die vollständige REST-API ist automatisch für alle Frappe-DocTypes verfügbar – keine separate Konfiguration nötig. Damit lässt sich HRMS mit Zeiterfassungssystemen oder Buchhaltungs-Tools integrieren. Mehr zur Absicherung von Docker-Stacks im Produktivbetrieb erklärt Docker Compose absichern: Secrets, Healthchecks und Non-Root.

Verifizieren: Navigiere in der Frappe-Oberfläche zu HR > Mitarbeiter. Die Liste lädt ohne Fehler. Unter Installierte Apps (Einstellungen > Über) müssen beide Apps erscheinen: erpnext und hrms.

Schritt 8: Backup und Updates

Sichere die Site regelmäßig – das Backup landet im Volume und sollte anschließend auf externen Speicher kopiert werden:

# Manuelles Backup
docker compose exec backend bench --site meinefirma.localhost backup

# Backup-Dateien liegen in:
# sites/meinefirma.localhost/private/backups/

Für eine umfassende Backup-Strategie empfiehlt sich zusätzlich ein externer Sync – die Grundlagen dazu beschreibt 3-2-1-Backup-Strategie umsetzen.

Für Updates auf eine neue HRMS-Version:

# 1. apps.json bei Bedarf aktualisieren
# 2. Neues Custom-Image bauen (CUSTOM_TAG in .env auf 1.1 erhöhen)
docker build \
  --no-cache \
  --build-arg=FRAPPE_PATH=https://github.com/frappe/frappe \
  --build-arg=FRAPPE_BRANCH=version-16 \
  --secret=id=apps_json,src=/opt/frappe-hrms/frappe_docker/apps.json \
  --tag=custom-hrms:1.1 \
  --file=/opt/frappe-hrms/frappe_docker/images/layered/Containerfile \
  /opt/frappe-hrms/frappe_docker/

# 3. Stack neu starten
docker compose up -d

# 4. Datenbank-Migrationen ausführen
docker compose exec backend bench --site meinefirma.localhost migrate

Verifizieren:

docker compose ps
docker compose logs backend --tail=20

Alle Dienste müssen nach dem Update wieder „running" zeigen. Der migrate-Befehl gibt am Ende eine Zusammenfassung der ausgeführten Migrationen aus.

Troubleshooting / Typische Fehler

  1. „No module named hrms" im Backend-Log: HRMS wurde in apps.json vergessen oder das Custom-Image wurde nach der Änderung nicht neu gebaut. Lösung: apps.json prüfen, Image neu bauen (--no-cache), Stack neu starten.
  2. Leere Seite / „Site does not exist": bench new-site und bench install-app hrms wurden noch nicht ausgeführt. Diese Schritte sind nach jedem docker compose up auf einer frischen Installation zwingend nötig.
  3. „manifest unknown" beim Start: PULL_POLICY=missing fehlt in der .env. Docker versucht, das lokale Image aus Docker Hub zu pullen. Lösung: Variable in .env setzen, docker compose up -d wiederholen.
  4. Site-Erstellung schlägt fehl mit „Access denied": DB_PASSWORD in .env und --mariadb-root-password im bench new-site-Befehl stimmen nicht überein. Beide müssen identisch sein.
  5. Segmentation Fault beim Image-Build: Häufig bei weniger als 4 GB RAM. Lösung: mehr RAM zuweisen oder explizit --build-arg=NODE_VERSION=18.12.0 ergänzen.
  6. Volume-Rechte-Fehler nach Update (PermissionError): Nach Image-Updates können Berechtigungen auf dem sites-Volume nicht passen. Lösung: docker compose exec backend chown -R frappe:frappe /home/frappe/frappe-bench/sites
  7. Falsche Lohnperioden / Zeitzonenfehler: bench --site <name> set-config time_zone "Europe/Berlin" ausführen und Worker neu starten: docker compose restart queue-long queue-short scheduler
  8. OOMKilled Worker unter Last: Zu wenig RAM. Entweder mehr RAM zuweisen oder GUNICORN_WORKERS in .env reduzieren. Die Formel (2 × CPU-Kerne) + 1 gilt für Systeme mit 8 GB+ RAM.

Häufige Fragen

Kann ich Frappe HRMS ohne ERPNext betreiben?

Nein. HRMS ist eine Frappe-App und hat ERPNext als direkte Abhängigkeit – insbesondere für die Buchhaltungsintegration (Lohnbuchungen, Kostenstellen, Chart of Accounts). Die apps.json muss immer zuerst ERPNext und dann HRMS enthalten. Eine reine HRMS-Installation ohne ERPNext ist offiziell nicht unterstützt.

Wie richte ich HTTPS mit meinem Domainnamen ein?

Das frappe_docker-Repository enthält ein Traefik-Overlay unter overrides/compose.traefik.yaml. Setze LETSENCRYPT_EMAIL in der .env und starte den Stack mit beiden Compose-Dateien: docker compose -f compose.yaml -f overrides/compose.traefik.yaml up -d. Eine vollständige Anleitung zum Traefik-Setup findest du unter Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten.

Wie betreibe ich mehrere Unternehmen (Mandantenfähigkeit)?

Frappe unterstützt mehrere Sites auf derselben Instanz. Für jede weitere Firma führst du bench new-site firma2.localhost --mariadb-root-password ... --admin-password ... und anschließend die App-Installationen aus. Jede Site hat eine eigene Datenbank und Konfiguration. Für die korrekte Site-Auflösung über Domainnamen setze FRAPPE_SITE_NAME_HEADER in der .env.

Funktioniert der Stack auf einem ARM64-Server (Raspberry Pi 5, Apple M)?

Grundsätzlich ja, aber die Standard-compose.yaml setzt platform: linux/amd64. Für ARM64 muss beim Build --platform=linux/arm64 ergänzt werden. Mindestvoraussetzung: ARM64 (v8+) mit 8 GB RAM. ARMv7 (Raspberry Pi 3/4 32-Bit) ist für diesen Stack ungeeignet.

Wie exportiere ich Gehaltsabrechnungen als PDF?

HRMS nutzt Frappees eingebautes PDF-Rendering via Chromium, das im Standard-Image enthalten ist. Unter „Gehaltszettel" gibt es einen „Drucken"-Button, der ein PDF erzeugt. Auf ARM64 muss die CHROMIUM_BIN-Umgebungsvariable ggf. manuell konfiguriert werden.

Wie führe ich ein vollständiges Backup durch?

docker compose exec backend bench --site meinefirma.localhost backup erzeugt einen Datenbank-Dump und ein Datei-Backup unter sites/meinefirma.localhost/private/backups/ im sites-Volume. Kopiere dieses Verzeichnis regelmäßig auf externen Speicher oder einen S3-kompatiblen Dienst.

Fazit

Frappe HRMS ist das vollständigste frei verfügbare HR-System für KMU – mit echter Gehaltsabrechnung, Urlaubsverwaltung und Onboarding in einem einzigen, aktiv gepflegten Open-Source-Projekt. Der Docker-Weg über frappe_docker erfordert einen einmaligen Custom-Image-Build und einen sorgfältig ausgeführten bench new-site-Schritt, ist danach aber wartungsarm und flexibel skalierbar. Wer die Ressourcen hat (mindestens 4 GB RAM, SSD), erhält eine HR-Plattform, die mit Personio oder Sage HR auf Augenhöhe ist – zum Preis von null Euro Lizenzkosten. Die Kombination aus mandantenfähiger Architektur, vollständiger REST-API und aktiver Community macht Frappe HRMS zur ernsthaften Alternative für wachsende Unternehmen im DACH-Raum.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian) – die Grundlage für alle Docker-Setups
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten – für den produktiven Betrieb mit eigenem Domainnamen
  3. Docker Compose absichern: Secrets, Healthchecks und Non-Root – Härtung für Produktivumgebungen
  4. 3-2-1-Backup-Strategie umsetzen – externe Datensicherung für alle selbst gehosteten Dienste
  5. Mautic mit Docker installieren – Open-Source-Marketing-Automation als Ergänzung zum HR-Stack

Offizielle Quellen: Frappe HRMS auf GitHub · frappe_docker (offizielles Deployment-Repository) · Frappe HRMS Dokumentation

Passende Anleitungen auf S-EDV

  1. OpenSSL: Neun Schwachstellen im Sicherheitsrelease vom 9. Juni 2026, darunter Hi
  2. Automatische Sicherheitsupdates unter Debian/Ubuntu mit unattended-upgrades rich
  3. netcup Local Block Storage bestellen, einrichten und unter Linux einbinden