The-Y CRM auf deinem eigenen Server
Ein Befehl, keine Konfigurationsdateien. Der Installer erzeugt alle Passwörter selbst, erkennt deine Server-Umgebung und richtet alles ein. Den Lizenzschlüssel gibst du danach bequem in der App ein.
- Einen Linux-Server (Root/SSH-Zugang). Schon ~2 CPU / 4 GB RAM / 40 GB SSD reichen für den Start.
- Docker & Docker Compose (Schritt 1 zeigt die Installation, falls noch nicht vorhanden).
- Eine Domain (z. B.
crm.deine-firma.at), deren DNS auf den Server zeigt. Ohne Domain geht es nur im eigenen Netz (Heimnetz). - Einen Lizenzschlüssel: Paid (ohne Grenzen) aus der Founder-Willkommensmail bzw. nach dem Kauf auf the-y.at — oder kostenlos einen Gratis-Schlüssel (mit den Free-Grenzen): auf crm.the-y.at registrieren → Einstellungen → Lizenz → „Gratis-Schlüssel erzeugen“.
→ Welchen Server brauche ich? — Größen-Empfehlung (klein/mittel/groß), Ports & Architektur im Detail.
-
Docker installieren (falls noch nicht vorhanden)
Prüfe mit
docker version. Fehlt Docker, installiere es mit dem offiziellen Skript:curl -fsSL https://get.docker.com | sh
Auf Servern mit Panel (Plesk/cPanel/Virtualmin) ist Docker oft schon vorhanden oder per Ein-Klick nachrüstbar.
-
Domain auf den Server zeigen lassen
Setze bei deinem Domain-Anbieter einen A-Record für deine Domain (z. B.
crm.deine-firma.at) auf die IP-Adresse deines Servers. Das kann ein paar Minuten dauern, bis es überall aktiv ist. -
Installer ausführen
Ein einziger Befehl auf dem Server (als Root bzw. mit einem Nutzer in der
docker-Gruppe):curl -fsSL https://the-y.at/install.sh -o install.sh && bash install.sh
Der Installer fragt nur nach Domain, Admin-E-Mail, (optional) Passwort und Firmenname — und erledigt dann alles: generiert sämtliche Passwörter, richtet Datenbank + ersten Admin ein und erkennt automatisch, ob auf deinem Server schon ein Webserver läuft. Je nachdem geht es bei einem der drei Fälle unten weiter.
Seit 1.1.58 fragt er außerdem „Telefonanlage gleich mit einrichten?“ — mit „nein“ bleibt alles wie bisher, nachrüsten geht jederzeit (Telefonanlage).
Je nach Server — einer dieser drei Fälle
🟢 Frischer Server
Nichts läuft auf Port 80/443. Der Installer bringt sein eigenes HTTPS mit (holt automatisch ein Let's-Encrypt-Zertifikat).
Du musst nichts weiter tun — öffne einfach deine Domain im Browser. Falls die Seite kurz nicht lädt: DNS/Ports 80+443 prüfen.
🧩 Server mit Panel
Virtualmin, Plesk oder cPanel belegen 80/443 bereits. Der Installer schaltet automatisch in den Proxy-Modus (App lauscht lokal auf 127.0.0.1:8090).
Lege im Panel für deine Domain einen Reverse Proxy / Proxy-Pass an, Ziel:
http://127.0.0.1:8090
und aktiviere für die Domain HTTPS/Let's Encrypt im Panel. Fertig.
⚙️ Nur Apache/Nginx
Du hast einen eigenen Webserver ohne Panel. Auch hier läuft die App auf 127.0.0.1:8090 — füge einen Reverse-Proxy-Vhost hinzu (Snippets unten) und hole ein Zertifikat mit certbot.
Nginx-Vhost (Fall C)
server {
server_name crm.deine-firma.at;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
}
}
# danach: sudo certbot --nginx -d crm.deine-firma.at
Apache-Vhost (Fall C)
<VirtualHost *:443>
ServerName crm.deine-firma.at
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8090/
ProxyPassReverse / http://127.0.0.1:8090/
RequestHeader set X-Forwarded-Proto "https"
# SSLEngine + Zertifikat via certbot --apache
</VirtualHost>
Letzter Schritt — Anmelden & Lizenz eingeben
-
Im Browser öffnen & anmelden
Rufe https://deine-domain auf und melde dich mit der Admin-E-Mail und dem Passwort an, das der Installer am Ende angezeigt hat.
-
Lizenzschlüssel eingeben — in der App
Der Einrichtungs-Assistent fragt beim ersten Start danach, oder du gehst zu Einstellungen → Lizenz und trägst deinen Schlüssel ein. Keine Konfigurationsdatei nötig. Self-Hosting braucht einen Lizenzschlüssel — Paid (ohne Grenzen) oder Gratis (dieselben Grenzen wie Free in der Cloud: 3 Nutzer, 1.000 ausgehende Nachrichten und 200 ausgehende Gesprächsminuten pro Monat, 2 gleichzeitige Telefonate, 2 GB, 1 Marke; ohne Support). Ohne Schlüssel läuft die Instanz ab dem ersten Start 14 Tage voll, danach nur noch lesend, bis du einen Schlüssel einträgst. Aus Gratis wird Paid, indem du später einfach den Paid-Schlüssel einträgst — deine Daten bleiben.
Updates kommen automatisch: Ab 1.1.53 aktualisiert sich die Installation nachts mit
update.sh – vorher wird gesichert, danach geprüft, und klappt etwas nicht, läuft wieder die vorherige Version. Installationen vor 1.1.53 nutzen Watchtower, bis du umstellst (etwa 5 Minuten). Ein Banner in der App meldet neue Versionen. Du kannst auch jederzeit selbst aktualisieren:
cd ~/the-y-crm && bash update.shOhne
update.sh (Installationen vor 1.1.53): docker compose pull && docker compose up -d.
Datenbank-Änderungen spielt die App beim Start selbst ein; nach einem Update ist nichts weiter zu tun.
Für Backups sichere regelmäßig das Postgres- und das MinIO-Volume — ein einfacher Datenbank-Dump:
cd ~/the-y-crm && docker compose exec -T postgres \ pg_dump -U crm crm | gzip > crm-backup-$(date +%F).sql.gz
Telefonanlage
Die eingebaute Telefonanlage (Asterisk für Anrufe, coturn für Video-Termine) ist optional. Alles andere läuft ohne sie.
Gleich mit installieren oder nachrüsten (ab 1.1.58)
install.sh fragt „Telefonanlage gleich mit einrichten?“ — nur auf Linux-Servern mit Docker direkt (nicht Docker Desktop, nicht „rootless“), weil die Sprache im Host-Netz läuft. Mit ja laufen danach Leitungen deines Telefonie-Anbieters, Durchwahlen, Sprachmenüs, Warteschlangen, Voicemail, Aufnahmen und das Telefon im Browser; die Konfiguration erzeugt das CRM selbst. Mit nein bleibt alles wie bisher. Nachrüsten geht jederzeit, auch mehrfach – Vorhandenes bleibt:
cd ~/the-y-crm && curl -fsSL https://the-y.at/install.sh -o install.sh && bash install.sh --add-phone
- Ports prüfen: Vorher schaut der Installer, ob 5060/udp, 3478, 5038 und 8188 frei sind. Sind sie belegt, schlägt er „nein“ vor und nennt sie.
- Öffentliche IPv4-Adresse: Er fragt danach und schlägt die eigene Adresse bzw. die vor, auf die deine Domain zeigt – ein fremder Dienst wird nicht gefragt. Hinter NAT merkt er sich zusätzlich die eigene Adresse.
- Zugänge:
AMI_SECRETundTURN_SECRETentstehen zufällig und stehen nur in der.env. - Ansagen: Die englischen Standardansagen (Asterisk Core Sounds, 2,4 MB, mit Prüfsumme) lädt er von downloads.asterisk.org. Ohne Internet: die Datei woanders laden, auf den Server kopieren, dann
PBX_ANSAGEN_DATEI=<datei> bash telefonanlage.sh --ansagen. - Telefon im Browser: Mit dem eingebauten Caddy (Fall A) trägt er
/asterisk-wsselbst ein. Hinter einem eigenen Webserver (Fall B/C) leitest du/asterisk-wsals WebSocket anhttp://<PBX_DOCKER_GW>:8188/wsweiter (Wert aus der.env, meist172.17.0.1); der Installer zeigt die Zeilen mit dem richtigen Wert. Ohne diese Weiterleitung gehen Anrufe über Leitungen und Tischtelefone, nur das Telefon im Browser nicht. - Firewall: Hat der Installer die Firewall eingerichtet (Härtung, ufw), öffnet er dort die Ports der Anlage; sonst nennt er sie (
bash telefonanlage.sh --ports). Eine Firewall schaltet er nie ab. - Ohne Rückfrage:
PBX=1 PBX_PUBLIC_IP=203.0.113.10 bash install.sh(PBX=0= nein; hinter NAT zusätzlichPBX_LOCAL_IP=<eigene Adresse>).
Ports (eingehend — auch in der Firewall deines Anbieters bzw. als Weiterleitung am Router, wenn der Server hinter NAT steht): 5060/udp (SIP), 10000–20000/udp (Sprache), 3478/udp + 3478/tcp (STUN/TURN für Video-Termine), 49152–49252/udp (TURN), 443/tcp (Telefon im Browser, für die App ohnehin offen). Nie von außen öffnen: 5038/tcp (AMI) und 8188/tcp (Asterisk-HTTP).
# Nginx — im HTTPS-vhost deiner Domain, vor „location /“
location = /asterisk-ws {
proxy_pass http://172.17.0.1:8188/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
# Apache — a2enmod proxy_wstunnel; vor „ProxyPass /“ ProxyPass /asterisk-ws ws://172.17.0.1:8188/ws ProxyPassReverse /asterisk-ws ws://172.17.0.1:8188/ws
Updates: update.sh übernimmt nach jedem Update mit neuem Worker die Grund-Dateien der Anlage; die laufende Anlage lädt sie neu, Gespräche laufen weiter. Eigene Teile gehören nach pbx/asterisk/include/. Neue Stände von Asterisk und coturn kommen mit bash install.sh --add-phone. Zustand prüfen: bash telefonanlage.sh --pruefen.
Abschalten: docker compose rm -sf asterisk coturn, in der .env bei COMPOSE_FILE den Teil :docker-compose.pbx.yml entfernen und PBX=0 setzen, dann docker compose up -d. Die Dateien unter pbx/ bleiben liegen.
SELF-HOSTING.md → Telefonie. Von Hand eingerichtete Anlagen (vor 1.1.58) lässt --add-phone unangetastet; für sie gilt der Abschnitt unten weiter.Was ab 1.1.46 gilt
Nutzt du die eigene Telefonanlage, gilt ab Version 1.1.46 Folgendes. Die Version selbst kommt mit den automatischen Updates; die Teile unter „Nicht im Image“ übernimmst du einmal selbst.
- Gleichzeitige Telefonate: Ohne Paid-Schlüssel gilt deine Installation als Free: höchstens 2 gleichzeitige Telefonate (über deine Leitungen und über WhatsApp, ein- und ausgehend). Ändern kannst du das mit
PBX_CONCURRENT_FREEin der.env(Zahl,-1= keine Grenze). Mit Paid-Schlüssel gibt es keine Tarif-Grenze. - Grenze für den ganzen Server:
PBX_MAX_CONCURRENT(Standard 80,0= keine Server-Grenze). App und Worker lesen dieselbe.envund müssen dieselbe Zahl sehen. Ein neuer Wert wirkt erst, wenn du beide neu erzeugst:docker compose up -d app worker. Ohne dieulimitsunten höchstens 55 einstellen. - Nicht im Image: Automatische Updates tauschen nur die Images. Diese Teile übernimmst du einmal selbst aus dem Release:
pbx/asterisk/pjsip.conf(Block[webrtc-endpoint]),pbx/asterisk/modules.conf(neu; aktuelle Fassung: the-y.at/pbx/asterisk/modules.conf.txt),pbx/asterisk/rtp.conf(RTP 10000–20000, auch in der Firewall öffnen) und im Compose-Dienstasteriskdieulimitsund den Mount fürmodules.conf:
asterisk:
# … bestehende Einträge bleiben …
ulimits:
nofile:
soft: 65536
hard: 65536
volumes:
# … bestehende Einträge bleiben …
- ./pbx/asterisk/modules.conf:/etc/asterisk/modules.conf:ro
Danach den Container einmal neu erzeugen, am besten zur ruhigen Zeit (laufende Telefonate brechen ab):
docker compose up -d asterisk
Ansagen und Hinweis vor Aufnahmen: Seit 1.1.51 gibt es keine Computerstimme mehr. Jedes Konto nimmt seine Ansagen selbst auf (im Browser) oder lädt sie als Datei hoch. Ohne eigene Aufnahme spielt die Anlage die englische Standardansage, wo es eine gibt; vor einer Aufzeichnung hören Anrufer ohne eigenen Hinweis nur einen Signalton (die App warnt dann deutlich). Mehr: Hinweis vor Aufnahmen · Release Notes 1.1.51 · Release Notes 1.1.46 · Gleichzeitige Telefonate.
Ohne Domain im Heimnetz (ab 1.1.58)
Auf einem Heimserver (z. B. CasaOS/ZimaOS, TrueNAS) ohne Domain und ohne Zertifikat geht das CRM auch über http://<IP des Servers>. Das ist nur fürs eigene Netz gedacht: Die Verbindung ist dann nicht verschlüsselt. Für Zugriff von außen eine Domain mit https verwenden.
Mit install.sh (ab 1.1.59): Bei „Deine Domain“ einfach die IP-Adresse des Servers eingeben (z. B. 192.168.1.50). Der Installer schreibt die Werte unten dann selbst und sagt das.
Von Hand: In der .env statt der Domain die Adresse mit http:// eintragen (Beispiel-IP ersetzen), danach im Installationsordner docker compose up -d:
CADDY_DOMAIN=http://192.168.1.50 # mit „http://“ davor holt Caddy kein Zertifikat BASE_DOMAIN=192.168.1.50 # nur die Adresse, ohne http:// und ohne Pfad APP_URL=http://192.168.1.50 # beginnt mit http:// → Anmelden über http geht, Links zeigen auf diese Adresse PUBLIC_BASE_URL=http://192.168.1.50
Öffnet ein App-Store die App direkt über einen Port (ohne Caddy), gehört diese Adresse samt Port in APP_URL, z. B. APP_URL=http://192.168.1.50:3000. Auf der Anmeldeseite steht dann der Hinweis „Verbindung im Heimnetz nicht verschlüsselt“.
Links und Bilder in Mails (ab 1.1.59): Links in Mails und Benachrichtigungen (Einladungen, Termin-Datei, Abmelde- und Umfrage-Links, Report) baut die App aus APP_URL, sobald sie mit http:// beginnt. Deshalb APP_URL genau so eintragen, wie die App im Browser aufgerufen wird (mit Port, falls nötig). Solche Links funktionieren nur im eigenen Netz. Logo und Bilder aus E-Mail-Vorlagen bettet die App in die Mail ein, damit Empfänger sie sehen.
Sprache der Oberfläche (ab 1.1.59)
Wer die App zum ersten Mal öffnet (noch keine Sprache gewählt), sieht sie in der Sprache seines Browsers – Deutsch, Englisch oder Türkisch, sonst Deutsch. Fest vorgeben kannst du sie in der .env, danach im Installationsordner docker compose up -d app:
DEFAULT_LOCALE=en # de, en oder tr
Reihenfolge: DEFAULT_LOCALE > Browser > Deutsch. Die Auswahl in der App und die Sprache im eigenen Profil gehen immer vor.
„Übersetzen“ im Posteingang
Ohne Übersetzungsdienst (und ohne eigenen KI- oder DeepL-Schlüssel als Übersetzer) blendet der Posteingang die Knöpfe „Übersetzen“ aus (ab 1.1.59). Den Dienst einrichten: Self-Hosting-Betrieb → Übersetzung.
Es hakt irgendwo?
Schreib uns einfach — antworte auf deine Founder-Willkommensmail oder melde dich über the-y.at. Wir helfen beim Aufsetzen.