Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 12.06.2026 · 10 min Lesezeit

Krayin CRM mit Docker installieren: Laravel-basiertes Vertriebs-CRM als HubSpot-Alternative

Krayin CRM ist ein Laravel-basiertes Open-Source-CRM mit Lead-Management und Verkaufspipelines. Diese Anleitung zeigt, wie Sie es per Docker Compose auf einem Linux-Host betreiben, inklusive Datenbankpasswort, Backup und Update.

Geprüft am 30.09.2026 · für krayin 2.2.0

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Eleganter Schreibtisch mit Laptop, Visitenkartenhalter aus Marmor und Bronzeskulptur, im Hintergrund die Skyline

Krayin CRM ist ein vollständiges, Laravel-basiertes Open-Source-CRM-System, das Webkul unter MIT-Lizenz entwickelt. Es eignet sich für Vertriebsteams, die HubSpot oder Pipedrive durch eine selbst betriebene Lösung ersetzen wollen. Es bietet Lead- und Kontaktverwaltung, Verkaufspipelines, Aktivitäten und E-Mail-Integration. Das offizielle All-in-One-Docker-Image webkul/krayin bringt Nginx, PHP 8.3 (FPM), MySQL 8.0 und Supervisor in einem einzigen Container mit.

Voraussetzungen

  1. Docker Engine 24.x oder neuer sowie das Docker Compose Plugin v2 (docker compose, nicht das alte docker-compose) auf einem Linux-Host installiert – falls noch nicht geschehen, hilft die Anleitung Docker und Docker Compose auf Linux installieren.
  2. Architektur: linux/amd64 (x86_64) zwingend – es gibt kein offizielles ARM64-Image. Auf Apple Silicon (M1/M2/M3) oder ARM-Servern ist ein Workaround mit platform: linux/amd64 und QEMU-Emulation möglich, aber deutlich langsamer und für Produktion nicht empfohlen.
  3. Mindestens 3 GB RAM, empfohlen 4 GB oder mehr; mindestens 2 GB freier Speicherplatz für Image und Daten.
  4. Internetzugang für docker pull – das Image ist ca. 732 MB groß.
  5. Offene Firewall-Ports: Host-Port Ihrer Wahl (Standard in dieser Anleitung: 8080); für HTTPS-Betrieb einen Reverse Proxy (Traefik, Caddy, Nginx Proxy Manager) vorschalten.
  6. curl für die Verifikationsschritte (auf den meisten Linux-Systemen bereits installiert).

Schritt 1: Projektordner und .env-Datei anlegen

Legen Sie einen eigenen Projektordner an. Alle Konfigurationsdateien landen dort; Docker-Volumes werden separat von Docker selbst verwaltet.

mkdir -p /opt/krayin
cd /opt/krayin

Erstellen Sie die .env-Datei mit einem Datenbankpasswort. Verwenden Sie nur Buchstaben und Ziffern, etwa aus openssl rand -hex 24: Das Startskript des Images schreibt den Wert per sed in die Laravel-Konfiguration, Zeichen wie / oder & brechen das.

# /opt/krayin/.env
# Dieses Passwort wird beim ersten Container-Start gesetzt.
# Nur Buchstaben und Ziffern, mindestens 16 Zeichen.
KRAYIN_DB_PASSWORD=ErsetzenSieDiesenWert2026

Sperren Sie die Datei mit chmod 600 /opt/krayin/.env. Sie gehört nicht in ein Git-Repository; sichern Sie sie gesondert.

Verifizieren: Die Datei ist vorhanden und nur für root lesbar:

ls -la /opt/krayin/.env
# Erwartete Ausgabe: -rw------- 1 root root ... /opt/krayin/.env

Schritt 2: compose.yaml erstellen

Das All-in-One-Image webkul/krayin:2.2.0 beinhaltet MySQL intern – es braucht keinen separaten Datenbank-Container. Für Produktion mit getrenntem MySQL-Backup empfiehlt sich das Build-Setup aus dem krayin-docker-Repository; für den schnellen Einstieg ist das folgende Setup die einfachste Wahl. Named Volumes sichern die MySQL-Daten (krayin_mysql) und die Anwendungsdaten wie Uploads und Logs (krayin_storage). Die Anwendung liegt im Image unter /var/www/laravel-crm, das Storage-Volume gehört deshalb nach /var/www/laravel-crm/storage.

# /opt/krayin/compose.yaml
services:
  krayin:
    image: webkul/krayin:2.2.0
    container_name: krayin
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - krayin_storage:/var/www/laravel-crm/storage
      - krayin_mysql:/var/lib/mysql
    environment:
      APP_URL: "http://localhost:8080"
      APP_DEBUG: "false"
      DB_DATABASE: krayin
      DB_USERNAME: krayin
      DB_PASSWORD: ${KRAYIN_DB_PASSWORD:-changeme_sicher}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/admin/login"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

volumes:
  krayin_storage:
  krayin_mysql:

Wichtig: APP_URL muss exakt der Adresse entsprechen, über die Sie Krayin erreichen – inklusive Port, falls dieser nicht 80 oder 443 ist. Bei Zugriff über eine eigene Domain oder IP einfach den Wert anpassen. Falsch gesetztes APP_URL führt zu kaputten Asset-URLs und fehlschlagenden Redirects.

Verifizieren: YAML-Syntax korrekt?

docker compose -f /opt/krayin/compose.yaml config
# Erwartete Ausgabe: die aufgelöste Konfiguration ohne Fehlermeldung

Schritt 3: Container starten

Starten Sie Krayin CRM im Hintergrund. Beim ersten Start lädt Docker das Image (ca. 732 MB) und legt die interne MySQL-Datenbank an.

cd /opt/krayin
docker compose up -d

Das Image legt den MySQL-Benutzer krayin beim ersten Start fest mit dem Passwort krayin an, unabhängig von DB_PASSWORD. Solange beide Werte nicht übereinstimmen, liefert Krayin HTTP 500 („Access denied for user 'krayin'“). Setzen Sie deshalb einmalig Ihr Passwort aus der .env in MySQL:

docker exec -it krayin mysql -uroot
# In der MySQL-Shell (Wert aus KRAYIN_DB_PASSWORD einsetzen):
# ALTER USER 'krayin'@'localhost' IDENTIFIED BY 'IhrPasswort';
# ALTER USER 'krayin'@'127.0.0.1' IDENTIFIED BY 'IhrPasswort';
# exit

Die Änderung liegt im Volume krayin_mysql und bleibt bei Neustarts und Neuerstellung des Containers erhalten.

Verifizieren: Läuft der Container und zeigt er „healthy“?

docker compose ps
# Erwartete Ausgabe (nach ca. 2-3 Minuten):
# NAME      IMAGE                    COMMAND   SERVICE   STATUS              PORTS
# krayin    webkul/krayin:2.2.0      ...       krayin    Up (healthy)        0.0.0.0:8080->80/tcp

# Logs verfolgen (Strg+C zum Beenden):
docker compose logs -f krayin
# Erwartete Zeilen:
# INFO success: mysql entered RUNNING state
# INFO success: php-fpm entered RUNNING state
# INFO success: nginx entered RUNNING state

Zeigt der Status noch starting, warten Sie 2 bis 3 Minuten und führen docker compose ps erneut aus.

Schritt 4: HTTP-Erreichbarkeit prüfen

Prüfen Sie vor dem Browser mit curl, ob der Container antwortet.

curl -I http://localhost:8080/admin/login
# Erwartete Ausgabe:
# HTTP/1.1 200 OK
# Content-Type: text/html; charset=UTF-8
# ...

Ein HTTP/1.1 302 Found auf die Login-Seite ist ebenfalls korrekt – der Redirect leitet auf /admin/login weiter. Erhalten Sie curl: (7) Failed to connect, ist der Container noch nicht vollständig gestartet oder der Port ist belegt (siehe Troubleshooting).

Verifizieren: /admin/login liefert HTTP-Statuscode 200 oder 302. Ein 500 deutet auf das Datenbankpasswort aus Schritt 3.

Schritt 5: Erst-Einrichtung im Browser

Öffnen Sie http://localhost:8080/admin/login (oder ersetzen Sie localhost durch die IP/Domain Ihres Servers) im Browser.

Die Standard-Zugangsdaten nach der Installation lauten:

FeldWert
E-Mailadmin@example.com
Passwortadmin123

Diese Zugangsdaten sind öffentlich bekannt. Ändern Sie das Passwort unmittelbar nach dem ersten Login. Öffnen Sie dazu nach dem Einloggen die Profil-Einstellungen. Alternativ per Artisan-Befehl im Container:

docker exec -it krayin php artisan tinker
# Im Tinker-Prompt:
# Webkul\User\Models\User::find(1)->update(['password' => bcrypt('IhrNeuesPasswort!')]);
# exit

Die wichtigsten Bereiche: Leads (Vertriebschancen anlegen), Contacts (Kontakte und Organisationen verwalten), Activities (Anrufe, Meetings, E-Mails protokollieren) und Settings (Pipelines, Nutzer, Rollen konfigurieren).

Verifizieren: Login erfolgreich, Dashboard lädt ohne Fehler, Passwort geändert.

Schritt 6: HTTPS und Reverse Proxy (empfohlen)

Das Image liefert nur HTTP. Für Zugriffe aus dem Internet ist HTTPS Pflicht. Schalten Sie einen Reverse Proxy vor den Krayin-Container und setzen Sie APP_URL in der compose.yaml auf https://crm.ihre-domain.de.

Eine bewährte Kombination ist Traefik mit automatischem HTTPS – die Einrichtung beschreibt die Anleitung Traefik als Docker-Reverse-Proxy mit automatischem HTTPS. Caddy oder Nginx Proxy Manager eignen sich ebenso.

Nach der Proxy-Konfiguration APP_URL in der .env oder direkt in der compose.yaml anpassen und Container neu starten:

cd /opt/krayin
docker compose up -d --force-recreate

Verifizieren:

curl -I https://crm.ihre-domain.de/admin/login
# Erwartete Ausgabe: HTTP/2 200 (oder 302) mit gültigem TLS-Zertifikat

Schritt 7: Updates und Datensicherung

Neue Krayin-Versionen erscheinen als neuer Image-Tag auf Docker Hub; das Image hinkt den GitHub-Releases teils hinterher (Stand 30.09.2026: Image 2.2.0, GitHub v2.2.6). Sichern Sie vor jedem Update die Datenbank. Laden Sie dazu vorher die Variablen mit set -a; . /opt/krayin/.env; set +a:

# MySQL-Dump aus dem laufenden Container erstellen:
docker exec krayin mysqldump -u krayin -p"${KRAYIN_DB_PASSWORD}" krayin > /opt/krayin/backup-$(date +%Y%m%d).sql

# Image aktualisieren (Tag in compose.yaml auf den neuen Tag von Docker Hub setzen):
# image: webkul/krayin:NEUER_TAG
docker compose pull
docker compose up -d

# Laravel-Migrationen nach dem Update ausführen:
docker exec krayin php artisan migrate --force

Die Named Volumes bleiben bei docker compose down erhalten; down -v löscht sie (siehe „Typische Fehler“). Zur Backup-Strategie empfiehlt sich die Anleitung MySQL & PostgreSQL Backup automatisieren mit cron.

Verifizieren:

docker compose ps
# STATUS: Up (healthy)
docker exec krayin php artisan --version
# Erwartete Ausgabe bei 2.2.0: Laravel Framework 12.x

Eckdaten auf einen Blick

EigenschaftWert
Imagewebkul/krayin:2.2.0
Aktuelle VersionImage 2.2.0, GitHub v2.2.6 (Stand 30.09.2026)
Image-Größeca. 732 MB
Architekturlinux/amd64 only (kein ARM64)
Interner Port80 (HTTP)
Host-Port (Beispiel)8080
PHP-Version im Image8.3
MySQL-Version im Image8.0
LizenzMIT
Webserver im ImageNginx mit PHP-FPM
UmgebungsvariablePflichtBeschreibung
APP_URLjaErreichbare URL inkl. Port (z.B. http://localhost:8080)
APP_DEBUGneinDebug-Modus; niemals true in Produktion
DB_DATABASEjaDatenbankname (Standard: krayin)
DB_USERNAMEjaDatenbankbenutzer (Standard: krayin)
DB_PASSWORDjaDatenbankpasswort – sicher wählen!
Volume / Pfad im ContainerInhaltPersistenz
/var/www/laravel-crm/storageLogs, Uploads, CacheNamed Volume krayin_storage
/var/lib/mysqlMySQL-DatenbankdatenNamed Volume krayin_mysql

Troubleshooting / Typische Fehler

  1. „exec format error“ / Container startet nicht auf ARM: Das Image ist nur für linux/amd64 gebaut. Auf Apple Silicon oder ARM-Servern: platform: linux/amd64 in der compose.yaml unter dem Service ergänzen und QEMU aktivieren (docker run --privileged --rm tonistiigi/binfmt --install all). Für Produktion nicht empfohlen.
  2. „port is already allocated“ / Port 8080 belegt: Auf dem Host läuft bereits ein Dienst auf diesem Port. Anderen Host-Port wählen, z.B. "9090:80", und APP_URL entsprechend anpassen.
  3. „SQLSTATE[HY000] [1045] Access denied for user 'krayin'“ / HTTP 500: Das Passwort in DB_PASSWORD stimmt nicht mit dem MySQL-Benutzer überein. Führen Sie die ALTER USER-Befehle aus Schritt 3 aus.
  4. „SQLSTATE[HY000] [2002] Connection refused“: MySQL im Container ist noch nicht bereit. Kurz warten und dann docker compose restart krayin ausführen.
  5. HTTP 500 / „Permission denied“ auf Storage: Fehlende Schreibrechte auf /var/www/laravel-crm/storage. Beheben mit: docker exec krayin bash -c "chmod -R 775 /var/www/laravel-crm/storage && chown -R www-data:www-data /var/www/laravel-crm/storage"
  6. Asset-URLs kaputt / Redirect-Schleife: APP_URL stimmt nicht mit der tatsächlich verwendeten Adresse überein. Wert in der compose.yaml korrigieren, dann docker compose up -d --force-recreate.
  7. Datenverlust nach docker compose down -v: Das -v-Flag löscht Named Volumes unwiderruflich. Niemals mit Produktionsdaten verwenden – nur docker compose down ohne Flags für normales Stoppen.
  8. Composer „Allowed memory size exhausted“ (nur Build-Variante): Bei VMs mit weniger als 1 GB RAM schlägt composer install fehl. Umgebungsvariable COMPOSER_MEMORY_LIMIT=-1 im Container setzen.
  9. setup.sh checkt veraltete Version aus (nur krayin-docker Build-Variante): Das offizielle setup.sh im krayin-docker-Repository checkt noch v2.0.1 aus. Für die aktuelle Version 2.2.x muss der Checkout-Befehl in setup.sh auf den gewünschten Tag angepasst werden.

Häufige Fragen

Welches Setup soll ich wählen: All-in-One-Image oder Build-Variante?

Das All-in-One-Image eignet sich für Tests und kleine Teams. Nginx, PHP und MySQL laufen in einem Container. Die Build-Variante über das krayin-docker-Repository trennt Webserver, MySQL und phpMyAdmin in eigene Container. Sie lohnt sich bei strengen Backup-Anforderungen.

Wie ändere ich das Admin-Passwort?

Über die Profil-Einstellungen nach dem ersten Login oder per Tinker, wie in Schritt 5 gezeigt.

Kann ich eine externe MySQL-Datenbank verwenden?

Ja. Die Umgebungsvariablen DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME und DB_PASSWORD auf den externen Server setzen. Das Volume krayin_mysql dann nicht mounten. Der externe MySQL-Benutzer benötigt alle Rechte (GRANT ALL PRIVILEGES) auf die Krayin-Datenbank.

Läuft Krayin auf einem Raspberry Pi oder ARM-Server?

Nicht offiziell, es gibt kein ARM64-Image. Die QEMU-Emulation aus dem Abschnitt „Typische Fehler“ ist langsam und für Produktion ungeeignet.

Wie aktualisiere ich Krayin auf eine neue Version?

Image-Tag in der compose.yaml auf die neue Version anpassen (neuen Tag auf Docker Hub prüfen), dann docker compose pull && docker compose up -d. Anschließend Migrationen ausführen: docker exec krayin php artisan migrate --force. Vorher immer einen MySQL-Dump erstellen.

Wie sichere ich die Daten regelmäßig?

Den MySQL-Dump zeigt Schritt 7. Named Volumes lassen sich außerdem mit docker run --rm -v krayin_mysql:/data -v $(pwd):/backup alpine tar czf /backup/krayin_mysql.tar.gz /data sichern. Die Anleitung MySQL & PostgreSQL Backup automatisieren mit cron zeigt die Automatisierung mit Rotation und Cloud-Sync.

Wie sichere ich den Zugang ab, wenn Krayin öffentlich erreichbar ist?

Neben dem sofortigen Passwort-Wechsel: HTTPS über einen Reverse Proxy erzwingen, APP_DEBUG=false sicherstellen und den Admin-Port nicht direkt ohne Firewall-Schutz exponieren. Eine umfassende Härtung für selbstgehostete Dienste beschreibt die Anleitung Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only.

Fazit

Krayin CRM ist eine MIT-lizenzierte Alternative zu HubSpot für Vertriebsteams, die ihre Daten selbst verwalten. Das All-in-One-Image hält den Einstieg klein: Ordner anlegen, .env befüllen, compose.yaml ablegen, starten und das Datenbankpasswort einmalig setzen. Einschränkungen: nur amd64, keine Hochverfügbarkeit, und das Docker-Image folgt den GitHub-Releases verzögert. Wer eine schlankere Lösung für persönliche Kontakt- und Beziehungspflege sucht, findet sie mit Monica CRM.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian)
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten
  3. MySQL & PostgreSQL Backup automatisieren mit cron
  4. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only
  5. Monica CRM mit Docker installieren: Persönliches CRM für Kontakte

Offizielle Quellen: Krayin CRM Developer Docs – Docker | Krayin CRM GitHub Repository | krayin/krayin-docker auf GitHub | webkul/krayin auf Docker Hub