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 22.9k GitHub-Stars – kostenlose HubSpot-Alternative mit Lead-Management, Verkaufspipelines und KI-Inhaltsassistenz. Diese Anleitung zeigt dir, wie du es per Docker Compose in 15 Minuten auf jedem Linux-Host startest.

Hero Bild zu Krayin CRM mit Docker, Laravel basiertes Vertriebs CRM als HubSpot Alternative mit Pipeline Dashboard und moderner Büro IT Umgebung.

Krayin CRM ist ein vollständiges, Laravel-basiertes Open-Source-CRM-System, das von Webkul entwickelt wird und mit 22.9k GitHub-Stars zu den aktivsten CRM-Projekten im Self-Hosting-Bereich gehört. Es richtet sich an wachsende Vertriebsteams, die eine kostenlose Alternative zu HubSpot oder Pipedrive suchen – ohne SaaS-Zwang, ohne versteckte Kosten, MIT-lizenziert und auch für den kommerziellen Einsatz freigegeben. Der Funktionsumfang umfasst Lead- und Kontaktverwaltung, Verkaufspipelines, Aktivitätsverfolgung, E-Mail-Integration und eine KI-gestützte Inhaltsassistenz. Das offizielle All-in-One-Docker-Image webkul/krayin bringt Apache, MySQL 8.0, PHP 8.3 und Supervisor in einem einzigen Container mit – ideal für einen schnellen Start ohne komplexes Multi-Container-Setup.

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 deiner 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

Lege einen dedizierten Projektordner an. Alle Konfigurationsdateien landen dort; Docker-Volumes werden separat von Docker selbst verwaltet.

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

Erstelle die .env-Datei mit einem sicheren Datenbankpasswort. Dieses Passwort wird beim ersten Start in die MySQL-Datenbank geschrieben – es lässt sich später ohne Datenverlust nur durch direktes Ändern im Container oder per Volume-Reset ändern.

# /opt/krayin/.env
# Dieses Passwort wird beim ersten Container-Start gesetzt.
# Mindestens 16 Zeichen, Sonderzeichen erlaubt.
KRAYIN_DB_PASSWORD=MeinSicheresPasswort123!

Die .env-Datei darf nicht ins Git-Repository; lege sie im .gitignore aus und sichere sie gesondert.

Verifizieren: Datei vorhanden und Passwort gesetzt?

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 Persistenz der MySQL-Daten (krayin_mysql) und der Anwendungsdaten wie Uploads und Logs (krayin_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/html/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 du Krayin erreichst – 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

Starte Krayin CRM im Hintergrund. Beim allerersten Start lädt Docker das Image herunter (~732 MB) und führt automatisch die Laravel-Installationsroutine php artisan krayin-crm:install inklusive Datenbank-Migrationen und Seeding aus. Das dauert je nach Verbindungsgeschwindigkeit und Hardware 5–10 Minuten.

cd /opt/krayin
docker compose up -d

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
# Warte auf Zeilen wie:
# "Krayin CRM installed successfully"
# "AH00558: apache2: ... httpd started"

Sollte der Status noch starting zeigen, warte weitere 2–3 Minuten und führe docker compose ps erneut aus. Die Datenbank-Migration beim ersten Start benötigt etwas Zeit.

Schritt 4: HTTP-Erreichbarkeit prüfen

Bevor du den Browser öffnest, prüfe mit curl, ob der Container HTTP-Antworten liefert.

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. Bekommst du curl: (7) Failed to connect, ist der Container noch nicht vollständig gestartet oder der Port ist belegt (siehe Troubleshooting).

Verifizieren: HTTP-Statuscode 200 oder 302 bei /admin/login – alles in Ordnung.

Schritt 5: Erst-Einrichtung im Browser

Öffne http://localhost:8080/admin/login (oder ersetze localhost durch die IP/Domain deines Servers) im Browser.

Die Standard-Zugangsdaten nach der Installation lauten:

FeldWert
E-Mailadmin@example.com
Passwortadmin123

Diese Zugangsdaten sind öffentlich bekannt – ändere das Passwort unmittelbar nach dem ersten Login! Navigiere nach dem Einloggen zu den Profil-Einstellungen und setze ein starkes Passwort. Alternativ per Artisan-Befehl im Container:

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

Erkunde anschließend 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 Standard-Image liefert nur HTTP. Für den Produktivbetrieb oder den Zugriff aus dem Internet ist HTTPS Pflicht. Schalte einen Reverse Proxy vor den Krayin-Container und setze APP_URL in der compose.yaml auf https://crm.deine-domain.de.

Eine bewährte Kombination ist Traefik mit automatischem HTTPS – die Einrichtung beschreibt die Anleitung Traefik als Docker-Reverse-Proxy mit automatischem HTTPS. Alternativ funktioniert auch Caddy oder Nginx Proxy Manager genauso gut.

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.deine-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. Vor jedem Update unbedingt die Datenbank sichern:

# 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 anpassen, z.B. auf 2.2.3):
# image: webkul/krayin:2.2.3
docker compose pull
docker compose up -d

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

Named Volumes (krayin_storage und krayin_mysql) bleiben bei docker compose down erhalten – niemals docker compose down -v auf Produktionsdaten anwenden, da das Flag alle Volumes unwiderruflich löscht. 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: Laravel Framework 11.x.x (oder neuer)

Eckdaten auf einen Blick

EigenschaftWert
Imagewebkul/krayin:2.2.0
Aktuelle stabile Version2.2.3 (Mai 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
Setup-Zeit (All-in-One)ca. 5–10 Minuten
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/html/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] [2002] Connection refused": MySQL im Container ist noch nicht bereit. Kurz warten und dann docker compose restart krayin ausführen. Der Healthcheck und start_period: 60s in der compose.yaml mildern dieses Problem ab.
  4. HTTP 500 / „Permission denied" auf Storage: Fehlende Schreibrechte auf /var/www/html/storage. Beheben mit: docker exec krayin bash -c "chmod -R 775 /var/www/html/storage && chown -R www-data:www-data /var/www/html/storage"
  5. 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.
  6. 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.
  7. 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.
  8. 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 webkul/krayin:2.2.0 ist die einfachste Wahl für Tests, kleine Teams oder den ersten produktiven Betrieb. Alles – Apache, MySQL, PHP – läuft in einem Container; keine externe Datenbank nötig. Die Build-Variante über das krayin-docker-Repository trennt PHP/Apache, MySQL und PHPMyAdmin in separate Container und bietet mehr Flexibilität: eigenes MySQL-Backup-Scheduling, separates Volume-Management, direkter PHPMyAdmin-Zugang. Für Produktion mit strengen Backup-Anforderungen ist die Build-Variante besser geeignet; für alle anderen Fälle reicht das All-in-One-Image.

Wie ändere ich das Admin-Passwort?

Nach dem ersten Login unter /admin/login mit den Standard-Zugangsdaten (admin@example.com / admin123) über die Profil-Einstellungen das Passwort ändern. Alternativ per Artisan-Tinker direkt im Container: docker exec -it krayin php artisan tinker, dann User::find(1)->update(['password' => bcrypt('NeuesPasswort!')]);

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. Mit platform: linux/amd64 und aktivierter QEMU-Emulation kann es starten, ist aber deutlich langsamer und für Produktion nicht empfohlen. Auf echter x86_64-Hardware oder einer amd64-VM ist Krayin die deutlich bessere Wahl.

Wie aktualisiere ich Krayin auf eine neue Version?

Image-Tag in der compose.yaml auf die neue Version anpassen (z.B. von 2.2.0 auf 2.2.3), 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?

MySQL-Dump aus dem Container: docker exec krayin mysqldump -u krayin -p"${KRAYIN_DB_PASSWORD}" krayin > backup.sql. 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, wie du das mit Rotation und Cloud-Sync vollautomatisch einrichtest.

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

Neben dem sofortigen Passwort-Wechsel (Standard-Credentials sind öffentlich bekannt!): 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 überzeugt als kostenlose, MIT-lizenzierte HubSpot-Alternative für Vertriebsteams, die ihre Daten lieber selbst verwalten als in eine SaaS-Abhängigkeit zu gehen. Das All-in-One-Docker-Image macht den Einstieg erfreulich unkompliziert: Ordner anlegen, .env mit Passwort befüllen, compose.yaml ablegen, docker compose up -d – nach 10 Minuten steht ein vollständiges CRM mit Lead-Management, Pipeline-Ansicht und KI-Inhaltsassistenz bereit. Die ehrlichen Einschränkungen: Nur amd64, das All-in-One-Image eignet sich nicht für High-Availability-Setups, und für Produktionsumgebungen mit strikten Backup-Anforderungen lohnt sich der Blick auf das Build-basierte Multi-Container-Setup. Wer eine schlankere Lösung für persönliche Kontakt- und Beziehungspflege sucht, findet mit Monica CRM eine gute Ergänzung aus der gleichen Kategorie.

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