So installierst du Zulip Chat Server mit Docker auf Rocky Linux 9
Zulip ist ein Open-Source-Chat-Server, ähnlich wie Microsoft Teams, Rocket Chat oder Slack. Er ist in Python geschrieben und nutzt Django, PostgreSQL und JavaScript. Er lässt sich mit über 90 Plugins von Drittanbietern integrieren, darunter Github, Jira, Stripe, Zendesk, Sentry usw. Du kannst die Integrationen erweitern, indem du sie mit Zapier und IFTTT verbindest. Zulip bietet Funktionen wie private Nachrichten, Gruppenchats, Unterhaltungen mit Threads, benutzerdefinierte Kanäle, Videoanrufe, Datei-Uploads per Drag-and-Drop, benutzerdefinierte Emojis, Giphy-Integration, Bild- und Tweet-Vorschauen und vieles mehr. Zulip wird mit Desktop- und Mobil-Apps für jede Plattform geliefert und ist somit plattformunabhängig.
In diesem Lernprogramm lernst du, wie du Zulip Chat auf einem Rocky Linux 9 Server installierst und konfigurierst.
Voraussetzungen
- Ein Server, auf dem Rocky Linux 9 läuft.
- Mindestens 2 GB RAM, wenn du weniger als 100 Benutzer erwartest. Für mehr als 100 Benutzer brauchst du einen Server mit 4 GB RAM und 2 CPUs.
- Ein Nicht-Root-Benutzer mit sudo-Rechten.
- Einen Domainnamen, der auf den Server zeigt,
zulip.example.com
. - Alles ist auf dem neuesten Stand.
$ sudo dnf update
- Ein paar Pakete, die dein System braucht.
$ sudo dnf install wget curl nano unzip yum-utils policycoreutils-python-utils -y
Einige dieser Pakete sind vielleicht schon auf deinem System installiert.
Schritt 1 – Firewall konfigurieren
Bevor du die Pakete installierst, musst du zunächst die Firewall so konfigurieren, dass sie die Ports für HTTP und HTTPS öffnet. Rocky Linux verwendet die Firewalld Firewall. Überprüfe den Status der Firewall.
$ sudo firewall-cmd --state running
Die Firewall arbeitet mit verschiedenen Zonen, wobei die öffentliche Zone die Standardzone ist, die wir verwenden werden. Liste alle Dienste und Ports auf, die auf der Firewall aktiv sind.
$ sudo firewall-cmd --zone=public --list-all
Es sollte die folgende Ausgabe angezeigt werden.
public target: default icmp-block-inversion: no interfaces: enp1s0 sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Öffne die HTTP- und HTTPS-Ports in der Firewall.
$ sudo firewall-cmd --zone=public --add-service=http $ sudo firewall-cmd --zone=public --add-service=https
Überprüfe erneut den Status der Firewall.
$ sudo firewall-cmd --zone=public --list-all
Du solltest eine ähnliche Ausgabe sehen.
public target: default icmp-block-inversion: no interfaces: enp1s0 sources: services: cockpit dhcpv6-client http https ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Setze alle Änderungen dauerhaft um und lade die Firewall neu, um die Änderungen zu aktivieren.
$ sudo firewall-cmd --runtime-to-permanent $ sudo firewall-cmd --reload
Schritt 2 – Installiere Docker und Docker Compose
Installiere das offizielle Docker-Repository.
$ sudo dnf install yum-utils $ sudo dnf config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Installiere Docker.
$ sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Aktiviere den Docker-Daemon und starte ihn.
$ sudo systemctl enable docker --now
Überprüfe den Status des Docker-Dienstes.
$ sudo systemctl status docker ? docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled) Active: active (running) since Tue 2024-02-06 07:17:33 UTC; 5s ago TriggeredBy: ? docker.socket Docs: https://docs.docker.com Main PID: 22302 (dockerd) Tasks: 10 Memory: 31.3M CPU: 198ms CGroup: /system.slice/docker.service ??22302 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Füge deinen Systembenutzer zur Docker-Gruppe hinzu, um zu vermeiden, dass du sudo
zur Ausführung von Docker-Befehlen verwendest.
$ sudo usermod -aG docker $(whoami)
Melde dich nach dem Abmelden erneut an deinem Server an, um die Änderung zu aktivieren.
Schritt 3 – Nginx installieren
Für die Produktionsumgebung empfiehlt es sich, den Synapse-Server mit einem Nginx-Proxy zu betreiben.
Rocky Linux 9 wird mit einer älteren Version von Nginx ausgeliefert. Du musst das offizielle Nginx-Repository verwenden, um die neueste Version zu installieren.
Erstelle und öffne die Datei /etc/yum.repos.d/nginx.repo
zum Bearbeiten.
$ sudo nano /etc/yum.repos.d/nginx.repo
Füge den folgenden Code in die Datei ein.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Wenn du fertig bist, speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Wir werden Nginx Mainline installieren, also aktiviere das Paket für Nginx.
$ sudo dnf config-manager --enable nginx-mainline
Installiere Nginx.
$ sudo dnf install nginx -y
Überprüfe die Installation.
$ nginx -v nginx version: nginx/1.25.3
Aktiviere und starte den Nginx-Serverdienst.
$ sudo systemctl enable nginx --now
Überprüfe den Status des Dienstes.
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled) Active: active (running) since Tue 2024-02-06 07:18:56 UTC; 5s ago Docs: http://nginx.org/en/docs/ Process: 22762 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 22763 (nginx) Tasks: 5 (limit: 50339) Memory: 4.9M CPU: 16ms CGroup: /system.slice/nginx.service ??22763 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??22764 "nginx: worker process" ??22765 "nginx: worker process" ??22766 "nginx: worker process" ??22767 "nginx: worker process"
Schritt 4 – SSL installieren
Wir müssen Certbot installieren, um das SSL-Zertifikat zu erstellen. Dazu verwenden wir den Snapd-Paketinstaller. Da Rocky Linux nicht mit diesem Paket ausgeliefert wird, installierst du den Snapd-Installer. Er benötigt das EPEL (Extra Packages for Enterprise Linux) Repository, um zu funktionieren.
Installiere das EPEL-Repository.
$ sudo dnf install epel-release -y
Installiere das Snapd-Paket.
$ sudo dnf install snapd -y
Aktiviere und starte den Snap-Dienst.
$ sudo systemctl enable snapd --now
Installiere das Snap-Kernpaket und stelle sicher, dass deine Snapd-Version auf dem neuesten Stand ist.
$ sudo snap install core && sudo snap refresh core
Erstelle die notwendigen Links, damit Snapd funktioniert.
$ sudo ln -s /var/lib/snapd/snap /snap $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
Installiere Certbot.
$ sudo snap install --classic certbot
Stelle mit dem folgenden Befehl sicher, dass der Certbot-Befehl ausgeführt werden kann, indem du einen symbolischen Link auf das Verzeichnis /usr/bin
erstellst.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Überprüfe die Certbot-Version.
$ certbot --version certbot 2.8.0
Führe den folgenden Befehl aus, um ein SSL-Zertifikat zu erzeugen.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d zulip.example.com
Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/zulip.example.com
auf deinem Server heruntergeladen.
Erstelle ein Diffie-Hellman-Gruppenzertifikat.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Überprüfe den Certbot-Erneuerungszeitplanungsdienst.
$ systemctl list-timers
Du findest snap.certbot.renew.service
als einen der Dienste, die für die Ausführung vorgesehen sind.
NEXT LEFT LAST PASSED UNIT ACTIVATES ---------------------------------------------------------------------------------------------------------------------------------- Tue 2024-02-06 07:30:00 UTC 6min left Tue 2024-02-06 07:20:11 UTC 3min 41s ago sysstat-collect.timer sysstat-collect.service Tue 2024-02-06 08:22:43 UTC 58min left Tue 2024-02-06 07:22:39 UTC 1min 13s ago dnf-makecache.timer dnf-makecache.service Tue 2024-02-06 09:36:00 UTC 2h 12min left - - snap.certbot.renew.timer snap.certbot.renew.service
Führe einen Probelauf des Prozesses durch, um zu prüfen, ob die SSL-Erneuerung einwandfrei funktioniert.
$ sudo certbot renew --dry-run
Wenn du keine Fehler siehst, bist du bereit. Dein Zertifikat wird automatisch erneuert.
Schritt 5 – SELinux konfigurieren
Wende die Richtlinie an, um Verbindungen zu externen Hosts zuzulassen.
$ sudo setsebool -P httpd_can_network_connect 1
Wende die Richtlinie an, um Nginx den Zugriff auf PostgreSQL zu erlauben.
$ sudo setsebool -P httpd_can_network_connect_db 1
Schritt 6 – Zulip für die Installation vorbereiten und konfigurieren
Erstelle zunächst einen geheimen Schlüssel für Zulip. Speichere den erzeugten Schlüssel, denn wir werden ihn später brauchen.
$ openssl rand -base64 32 sLIeucGPMCNbR0LwcRhyXafXmputmtse6+EYU04+9JY=
Erstelle ein Verzeichnis für die Zulip Docker Compose Datei und wechsle dorthin.
$ mkdir ~/docker-zulip $ cd ~/docker-zulip
Erstelle und öffne die Umgebungsdatei zum Bearbeiten.
$ nano .env
Füge den folgenden Code in die Datei ein.
ZULIP_ADMINISTRATOR=admin@exapmle.com EXTERNAL_HOST=zulip.example.com ZULIP_AUTH_BACKENDS=EmailAuthBackend ZULIP_PUSH_NOTIFICATION_BOUNCER_URL=https://push.zulipchat.com DISABLE_HTTPS=true SSL_CERTIFICATE_GENERATION=self-signed EMAIL_HOST=email-smtp.us-west-2.amazonaws.com EMAIL_HOST_USER=AMAZONSESUSERNAME EMAIL_PASSWORD=AMAZONSESPASSWORD EMAIL_PORT=465 EMAIL_USE_SSL=True EMAIL_USE_TLS=False EMAIL_NOREPLY_ADD=noreply@example.com ZULIP_GIT_URL=https://github.com/zulip/zulip.git ZULIP_GIT_REF=8.2 SECRET_KEY=sLIeucGPMCNbR0LwcRhyXafXmputmtse6+EYU04+9JY= POSTGRES_USER=zulip POSTGRES_DB=zulip POSTGRES_PASSWORD=REPLACE_WITH_SECURE_POSTGRES_PASSWORD REDIS_PASSWORD=REPLACE_WITH_SECURE_REDIS_PASSWORD MEMCACHED_PASSWORD=REPLACE_WITH_SECURE_MEMCACHED_PASSWORD RABBITMQ_DEFAULT_USER=zulip RABBITMQ_DEFAULT_PASS=REPLACE_WITH_SECURE_RABBITMQ_PASSWORD
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Gehen wir nun alle Variablen durch, die wir definiert haben.
- ZULIP_ADMINISTRATOR – ist die primäre E-Mail-Adresse des Administratorkontos, das während der Installation angelegt wurde.
- EXTERNAL_HOST – ist der Domänenname, den wir für unsere Zulip-Installation verwenden werden.
- ZULIP_AUTH_BACKENDS – legt die Methode zum Einloggen fest. Wir verwenden
EmailAuthBackend
, was bedeutet, dass Zulip nach einer E-Mail-Adresse und einem Passwort fragt. Es gibt auch andere Authentifizierungsmethoden, die Google-, GitHub- und Apple-Anmeldedaten zum Einloggen verwenden. Weitere Informationen findest du in der Zulip-Dokumentation und in der Standardsettings.py
Datei. - ZULIP_PUSH_NOTIFICATION_BOUNCER_URL – ist die URL, die Zulip für den Versand von mobilen Push-Benachrichtigungen verwendet. Bei der Community-Version von Zulip für eine Organisation mit 10 oder weniger Nutzern sind Push-Benachrichtigungen kostenlos. Je nach Anforderungen kann deine Organisation auch unbegrenzte kostenlose Push-Benachrichtigungen erhalten. Details findest du in der Zulip-Abrechnungsdokumentation.
- DISABLE_HTTPS – Wir haben dies auf true gesetzt, um SSL für Zulip zu deaktivieren, da wir es außerhalb des Containers handhaben werden.
- SSL_CERTIFICATE_GENERATION – Da wir SSL für Zulip deaktiviert haben, müssen wir es so einstellen, dass es selbstsignierte Zertifikate erzeugt.
- EMAIL_HOST – Der SMTP-E-Mail-Host, den wir für die Aktivierung von E-Mail-Benachrichtigungen benötigen. In diesem Fall verwenden wir den Amazon SES E-Mail-Dienst für unser Lernprogramm.
- EMAIL_HOST_USER – Der SMTP-E-Mail-Benutzername.
- EMAIL_PASSWORD – Das SMTP-E-Mail-Passwort.
- EMAIL_PORT – Der SMTP-E-Mail-Port.
- EMAIL_USE_SSL – Ob der SMTP-Host SSL-Authentifizierung unterstützt.
- EMAIL_USE_TLS – Ob der SMTP-Host die TLS-Authentifizierung unterstützt.
- EMAIL_NOREPLY_ADD – Die No-Reply-E-Mail-Adresse, die für den Versand von Benachrichtigungs-E-Mails verwendet wird.
- ZULIP_GIT_URL – Wir verwenden das Zulip-Docker-Image, aber wenn du ein benutzerdefiniertes Image erstellen möchtest, musst du die URL des Zulip-Git-Repositorys eingeben.
- ZULIP_GIT_REF – Die Version von Zulip, die aus dem Git-Repository für die Erstellung des Docker-Images verwendet werden soll.
- SECRET_KEY – Ein starker geheimer Schlüssel, den Zulip für die Authentifizierung benötigt. Gib den Schlüssel ein, den wir zuvor erstellt haben.
- POSTGRES_USER – Wähle einen Benutzernamen für deinen PostgreSQL-Benutzer.
- POSTGRES_DB – Wähle den Datenbanknamen für deine PostgreSQL-Datenbank.
- POSTGRES_PASSWORD – Wähle ein sicheres Passwort für die PostgreSQL-Datenbank.
- REDIS_PASSWORD – Wähle ein sicheres Passwort für die Redis-Datenbank.
- MEMCACHED_PASSWORD – Wähle ein sicheres Passwort für den Memcached-Dienst.
- RABBITMQ_DEFAULT_USER – Wähle einen Benutzernamen für den RabbitMQ-Dienst.
- RABBITMQ_DEFAULT_PASS – Wähle ein sicheres Passwort für den RabbitMQ-Dienst.
Erstelle und öffne die Docker Compose-Datei zur Bearbeitung.
$ nano docker-compose.yml
Füge den folgenden Code hinzu, um den Dienst database
zu definieren.
services: database: image: "zulip/zulip-postgresql:14" container_name: zulip-db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - "postgresql-14:/var/lib/postgresql/data:rw" networks: network: ipv4_address: 10.5.0.2
Der database
Dienst enthält die folgenden Optionen:
- image – Damit wird Docker angewiesen, das
zulip-postgresql:14
Image zu ziehen. Auch wenn die neueste Version von Zulip PostgreSQL 16 unterstützt, unterstützt das entsprechende Docker-Image nur PostgreSQL 14. - container_name – legt einen Namen für den Container fest.
- restart – hier wird die Richtlinie für den Neustart des Containers festgelegt. Wir haben den Container so eingestellt, dass er automatisch neu startet, wenn er nicht manuell gestoppt wird.
- environment – Du musst Umgebungsvariablen für den Container setzen. Wir haben drei Variablen gesetzt, die die PostgreSQL-Datenbank, den Benutzernamen und das Passwort definieren.
- volumes – Hier erstellen wir ein benanntes Volume namens
postgresql-14
, das auf das PostgreSQL-Datenverzeichnis im Container verweist. - networks – Hier geben wir dem Container eine statische IP-Adresse, mit der er von anderen Containern aus erreichbar ist.
Als Nächstes fügst du unter dem Abschnitt database
die Definition für den Dienst memcached
hinzu.
memcached: image: "memcached:alpine" restart: unless-stopped container_name: zulip-memcached command: - "sh" - "-euc" - | echo 'mech_list: plain' > "$$SASL_CONF_PATH" echo "zulip@$$HOSTNAME:$$MEMCACHED_PASSWORD" > "$$MEMCACHED_SASL_PWDB" echo "zulip@localhost:$$MEMCACHED_PASSWORD" >> "$$MEMCACHED_SASL_PWDB" exec memcached -S environment: SASL_CONF_PATH: "/home/memcache/memcached.conf" MEMCACHED_SASL_PWDB: "/home/memcache/memcached-sasl-db" MEMCACHED_PASSWORD: ${MEMCACHED_PASSWORD} networks: network: ipv4_address: 10.5.0.3
Der Dienst memcached
enthält die folgenden Definitionen, die ihm eigen sind:
- image – Hier verwenden wir das
memcached:alpine
image für den Container. Ein Alpine-Image hält die Größe des Images gering, da es nur das Nötigste enthält. - command – Hier führen wir einige Befehle aus, die nach der Erstellung des Containers ausgeführt werden, um Memcached zu konfigurieren und die Zulip-Anmeldedaten festzulegen. Diese Befehle setzen auch die Standardbefehle des Images außer Kraft.
- environment – Hier legen wir den Speicherort der Memcached-Konfigurationsdatei, der Passwort-Datenbankdatei und des Passworts fest.
- network – Hier legen wir eine eindeutige private IP-Adresse für den Docker-Container fest.
Als Nächstes fügen wir die Definition für den Dienst rabbitmq
unterhalb des Abschnitts memcached
hinzu.
rabbitmq: image: "rabbitmq:alpine" restart: unless-stopped container_name: zulip-rabbitmq environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} volumes: - "rabbitmq:/var/lib/rabbitmq:rw" networks: network: ipv4_address: 10.5.0.4
Der Dienst rabbitmq
enthält die folgenden Definitionen, die für ihn spezifisch sind:
- image – Ähnlich wie zuvor verwenden wir das alpine Image für den RabbitMQ-Container.
- environment – Im Abschnitt environment legen wir den Standardbenutzernamen und das Standardpasswort von RabbitMQ fest.
- volumes – Hier erstellen wir ein benanntes Volume namens
rabbitmq
, das auf das RabbitMQ-Verzeichnis im Container verweist. - network – Wie schon zuvor legen wir eine eindeutige IP-Adresse für den Container fest.
Als nächstes fügen wir die Definition für den Dienst redis
unter dem Abschnitt rabbitmq
ein.
redis: image: "redis:alpine" restart: unless-stopped container_name: zulip-redis command: - "sh" - "-euc" - | echo "requirepass '$$REDIS_PASSWORD'" > /etc/redis.conf exec redis-server /etc/redis.conf environment: REDIS_PASSWORD: ${REDIS_PASSWORD} volumes: - "redis:/data:rw" networks: network: ipv4_address: 10.5.0.5
Der Dienst redis
enthält die folgenden Definitionen, die für ihn spezifisch sind:
- image – Hier verwenden wir das Alpine-Image für den Redis-Container.
- command – Wir verwenden die Befehle, um das Redis-Passwort zu konfigurieren und den Server damit zu starten.
- volumes – Hier erstellen wir ein benanntes Volume namens
redis
, das auf das Datenverzeichnis im Container verweist. - network – Wie schon zuvor legen wir eine eindeutige IP-Adresse für den Redis-Container fest.
Schließlich fügen wir die Definition für den Dienst zulip
unter dem Abschnitt redis
ein.
zulip: image: "zulip/docker-zulip:8.2-0" restart: unless-stopped container_name: zulip ports: - "8080:80" environment: DB_HOST: "database" DB_HOST_PORT: "5432" DB_USER: ${POSTGRES_USER} DISABLE_HTTPS: ${DISABLE_HTTPS} SSL_CERTIFICATE_GENERATION: ${SSL_CERTIFICATE_GENERATION} LOADBALANCER_IPS: 10.5.0.0/16 SETTING_MEMCACHED_LOCATION: "memcached:11211" SETTING_RABBITMQ_HOST: "rabbitmq" SETTING_REDIS_HOST: "redis" SECRETS_email_password: ${EMAIL_PASSWORD} SECRETS_rabbitmq_password: ${RABBITMQ_DEFAULT_PASS} SECRETS_postgres_password: ${POSTGRES_PASSWORD} SECRETS_memcached_password: ${MEMCACHED_PASSWORD} SECRETS_redis_password: ${REDIS_PASSWORD} SECRETS_secret_key: ${SECRET_KEY} SETTING_EXTERNAL_HOST: ${EXTERNAL_HOST} SETTING_ZULIP_ADMINISTRATOR: ${ZULIP_ADMINISTRATOR} SETTING_EMAIL_HOST: ${EMAIL_HOST} SETTING_EMAIL_HOST_USER: ${EMAIL_HOST_USER} SETTING_EMAIL_PORT: ${EMAIL_PORT} SETTING_EMAIL_USE_SSL: ${EMAIL_USE_SSL} SETTING_EMAIL_USE_TLS: ${EMAIL_USE_TLS} ZULIP_AUTH_BACKENDS: ${ZULIP_AUTH_BACKENDS} SETTING_NOREPLY_EMAIL_ADDRESS: ${EMAIL_NOREPLY_ADD} # Uncomment this when configuring the mobile push notifications service # SETTING_PUSH_NOTIFICATION_BOUNCER_URL: ${ZULIP_PUSH_NOTIFICATION_BOUNCER_URL} volumes: - "zulip:/data:rw" ulimits: nofile: soft: 1000000 hard: 1048576 networks: network: ipv4_address: 10.5.0.6
Der Dienst zulip
enthält die folgenden Definitionen, die für ihn spezifisch sind:
- Ports – Der Zulip-Container führt nginx als Teil des Prozesses aus. Hier haben wir Port 80 des Containers auf Port 8080 auf dem Hostserver abgebildet. Wir werden ihn später verwenden, um Nginx als Proxy-Manager außerhalb des Containers zu konfigurieren.
- environment – Hier konfigurieren wir Umgebungsvariablen, um Zulip zu konfigurieren. Die meisten Umgebungsvariablen werden aus der Datei
.env
entnommen, die wir bereits erklärt haben. Der Datenbankhost wird auf dendatabase
Containerdienst und der Port auf den Standard-PostgreSQL-Port 5432 gesetzt. Die VariableLOADBALANCER_IPS
wird auf das Subnetz des Docker-Netzwerks gesetzt. Dies ist erforderlich, damit Zulip hinter einem Reverse-Proxy-Server funktioniert. Die VariableMEMCACHED_LOCATION
wird auf den Dienstmemcached
mit dem Standardport 11211 gesetzt. In ähnlicher Weise haben wir die RabbitMQ- und Redis-Hosts auf ihre jeweiligen Containerdienste gesetzt. - volumes – Hier legen wir ein benanntes Volume fest und setzen es auf das Verzeichnis
/data
im Lese- und Schreibmodus. - ulimits – Hier legen wir die weichen und harten Grenzen für die Ressourcennutzung des Benutzers für den Container fest.
- networks – Wie zuvor legen wir auch hier eine eindeutige IP-Adresse für den Zulip-Container fest.
Als letztes fügen wir den folgenden Code ein.
volumes: zulip: postgresql-14: rabbitmq: redis: networks: network: driver: bridge ipam: config: - subnet: 10.5.0.0/16 gateway: 10.5.0.1
Hier definieren wir die benannten Volumes, die wir zuvor für unsere Container erstellt haben. Als Nächstes definieren wir das Brückennetzwerk, das alle Container miteinander verbinden soll, und geben Subnetz- und Gateway-IP-Adressen an.
Wenn du fertig bist, speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Die fertige Docker-Compose-Datei sieht dann wie folgt aus.
services: database: image: "zulip/zulip-postgresql:14" restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - "postgresql-14:/var/lib/postgresql/data:rw" networks: network: ipv4_address: 10.5.0.2 memcached: image: "memcached:alpine" restart: unless-stopped command: - "sh" - "-euc" - | echo 'mech_list: plain' > "$$SASL_CONF_PATH" echo "zulip@$$HOSTNAME:$$MEMCACHED_PASSWORD" > "$$MEMCACHED_SASL_PWDB" echo "zulip@localhost:$$MEMCACHED_PASSWORD" >> "$$MEMCACHED_SASL_PWDB" exec memcached -S environment: SASL_CONF_PATH: "/home/memcache/memcached.conf" MEMCACHED_SASL_PWDB: "/home/memcache/memcached-sasl-db" MEMCACHED_PASSWORD: ${MEMCACHED_PASSWORD} networks: network: ipv4_address: 10.5.0.3 rabbitmq: image: "rabbitmq:alpine" restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} volumes: - "rabbitmq:/var/lib/rabbitmq:rw" networks: network: ipv4_address: 10.5.0.4 redis: image: "redis:alpine" restart: unless-stopped command: - "sh" - "-euc" - | echo "requirepass '$$REDIS_PASSWORD'" > /etc/redis.conf exec redis-server /etc/redis.conf environment: REDIS_PASSWORD: ${REDIS_PASSWORD} volumes: - "redis:/data:rw" networks: network: ipv4_address: 10.5.0.5 zulip: image: "zulip/docker-zulip:8.1-0" restart: unless-stopped #build: # context: . # args: # ZULIP_GIT_URL: ${ZULIP_GIT_URL} # ZULIP_GIT_REF: ${ZULIP_GIT_REF} # Set this up if you plan to use your own CA certificate bundle for building # CUSTOM_CA_CERTIFICATES: ${ZULIP_CUSTOM_CA_CERTIFICATES} ports: - "8080:80" environment: DB_HOST: 10.5.0.2 DB_HOST_PORT: "5432" DB_USER: ${POSTGRES_USER} DISABLE_HTTPS: ${DISABLE_HTTPS} LOADBALANCER_IPS: 10.5.0.6 SSL_CERTIFICATE_GENERATION: ${SSL_CERTIFICATE_GENERATION} SETTING_MEMCACHED_LOCATION: "memcached:11211" SETTING_RABBITMQ_HOST: "rabbitmq" SETTING_REDIS_HOST: "redis" SECRETS_email_password: ${EMAIL_PASSWORD} SECRETS_rabbitmq_password: ${RABBITMQ_DEFAULT_PASS} SECRETS_postgres_password: ${POSTGRES_PASSWORD} SECRETS_memcached_password: ${MEMCACHED_PASSWORD} SECRETS_redis_password: ${REDIS_PASSWORD} SECRETS_secret_key: ${SECRET_KEY} SETTING_EXTERNAL_HOST: ${EXTERNAL_HOST} SETTING_ZULIP_ADMINISTRATOR: ${ZULIP_ADMINISTRATOR} SETTING_EMAIL_HOST: ${EMAIL_HOST} SETTING_EMAIL_HOST_USER: ${EMAIL_HOST_USER} SETTING_EMAIL_PORT: ${EMAIL_PORT} SETTING_EMAIL_USE_SSL: ${EMAIL_USE_SSL} SETTING_EMAIL_USE_TLS: ${EMAIL_USE_TLS} ZULIP_AUTH_BACKENDS: ${ZULIP_AUTH_BACKENDS} SETTING_NOREPLY_EMAIL_ADDRESS: ${EMAIL_NOREPLY_ADD} # Uncomment this when configuring the mobile push notifications service # SETTING_PUSH_NOTIFICATION_BOUNCER_URL: ${ZULIP_PUSH_NOTIFICATION_BOUNCER_URL} volumes: - "zulip:/data:rw" ulimits: nofile: soft: 1000000 hard: 1048576 networks: network: ipv4_address: 10.5.0.6 volumes: zulip: postgresql-14: rabbitmq: redis: networks: network: driver: bridge ipam: config: - subnet: 10.5.0.0/16 gateway: 10.5.0.1
Schritt 7 – Zulip installieren
Starte den Zulip-Container mit dem folgenden Befehl.
$ docker compose up -d
Überprüfe den Status der Container mit den folgenden Befehlen.
$ docker ps
Du solltest eine ähnliche Ausgabe sehen.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fea5d02f53d7 rabbitmq:alpine "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 4369/tcp, 5671-5672/tcp, 15691-15692/tcp, 25672/tcp zulip-rabbitmq 01cb77f16c1a zulip/zulip-postgresql:14 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 5432/tcp zulip-db f5b6523a3a8c zulip/docker-zulip:8.2-0 "/sbin/entrypoint.sh…" 2 minutes ago Up 2 minutes 443/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp zulip c0a358209b09 redis:alpine "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp zulip-redis 27be352a0a35 memcached:alpine "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 11211/tcp zulip-memcached
Du kannst auch den folgenden Befehl verwenden.
$ docker compose ps
In diesem Fall würde deine Ausgabe wie die folgende aussehen.
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS zulip zulip/docker-zulip:8.2-0 "/sbin/entrypoint.sh…" zulip About a minute ago Up About a minute 443/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp zulip-db zulip/zulip-postgresql:14 "docker-entrypoint.s…" database About a minute ago Up About a minute 5432/tcp zulip-memcached memcached:alpine "docker-entrypoint.s…" memcached About a minute ago Up About a minute 11211/tcp zulip-rabbitmq rabbitmq:alpine "docker-entrypoint.s…" rabbitmq About a minute ago Up About a minute 4369/tcp, 5671-5672/tcp, 15691-15692/tcp, 25672/tcp zulip-redis redis:alpine "docker-entrypoint.s…" redis About a minute ago Up About a minute 6379/tcp
Der Zulip-Container wird einige Zeit brauchen, um zu funktionieren. Du kannst den Fortschritt mit folgendem Befehl verfolgen.
$ docker logs zulip --follow
Du wirst eine lange Liste von Befehlen sehen, die ausgeführt werden, um den Container einzurichten. Sobald du die folgende Ausgabe siehst, bedeutet das, dass Zulip installiert ist.
2024-02-21 09:02:55,310 INFO success: go-camo entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: smokescreen entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip-django entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip-tornado entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip_deliver_scheduled_emails entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip_deliver_scheduled_messages entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: process-fts-updates entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: cron entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip_events_deferred_work entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip_events_digest_emails entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,311 INFO success: zulip_events_email_mirror entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_embed_links entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_embedded_bots entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_invites entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_email_senders entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_missedmessage_emails entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_missedmessage_mobile_notifications entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_outgoing_webhooks entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_user_activity entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_user_activity_interval entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) 2024-02-21 09:02:55,312 INFO success: zulip_events_user_presence entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
Drücke Strg + C, um den Bildschirm zu verlassen. Zulip ist installiert. Wir müssen jedoch noch Nginx konfigurieren, um Zulip zu bedienen.
Schritt 8 – Nginx konfigurieren
Öffne die Datei /etc/nginx/nginx.conf
zum Bearbeiten.
$ sudo nano /etc/nginx/nginx.conf
Füge die folgende Zeile vor der Zeile include /etc/nginx/conf.d/*.conf;
ein.
server_names_hash_bucket_size 64;
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Erstelle und öffne die Datei /etc/nginx/conf.d/zulip.conf
zum Bearbeiten.
$ sudo nano /etc/nginx/conf.d/zulip.conf
Füge den folgenden Code in die Datei ein.
server { listen 80; listen [::]:80; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name zulip.example.com; ssl_certificate /etc/letsencrypt/live/zulip.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/zulip.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/zulip.example.com/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_prefer_server_ciphers on; ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s; resolver_timeout 2s; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; tcp_nopush on; gzip on; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_http_version 1.1; proxy_buffering off; proxy_read_timeout 20m; proxy_pass http://127.0.0.1:8080; } }
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Überprüfe die Syntax der Nginx-Konfigurationsdatei.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Starte den Nginx-Dienst neu.
$ sudo systemctl restart nginx
Schritt 9 – Zugriff auf die Zulip-Schnittstelle
Rufe in deinem Browser https://zulip.example.com/
auf und der folgende Bildschirm wird angezeigt.
Wenn du oben auf den Link Neue Organisation klickst, wirst du auf die folgende Seite weitergeleitet.
Wie du siehst, kannst du mit Zulip keine Organisation über das Frontend erstellen. Gehe zurück zum Terminal und führe den folgenden Befehl aus, um die URL der neuen Organisationsseite zu erstellen. Im nächsten Abschnitt werden wir mehr über die Verwendung von Zulip-Befehlen erfahren.
$ docker compose exec -u zulip zulip /home/zulip/deployments/current/manage.py generate_realm_creation_link Please visit the following secure single-use link to register your new Zulip organization: https://zulip.example.com/new/svvss33z4qmwewmanbbcalen
Öffne die URL https://zulip.example.com/new/cjjivovgcillw44z7gsnobkv
in deinem Browser und du wirst auf die folgende Seite weitergeleitet.
Gib den Namen deiner Organisation, den Organisationstyp, die Sprache und die E-Mail-ID ein, um mit der Erstellung deiner Organisation zu beginnen. Klicke auf die Schaltfläche Organisation erstellen, um fortzufahren.
Auf dem nächsten Bildschirm wirst du aufgefordert, ein Konto einzurichten.
Gib deinen Namen ein, wähle ein Passwort zum Einloggen und klicke auf die Schaltfläche Anmelden, um fortzufahren.
Sobald du fertig bist, öffnet sich das Zulip Dashboard und du kannst es benutzen.
Schritt 10 – Zulip Server-Befehle
Um Zulip Server-Befehle auszuführen, brauchst du von Zeit zu Zeit Zugriff auf die Container-Shell. Um als Benutzer zulip
auf die Shell zuzugreifen, verwende den folgenden Befehl.
$ docker compose exec -u zulip zulip bash
Oder du kannst den folgenden Befehl verwenden.
$ docker exec -itu zulip zulip bash
Um einen Befehl innerhalb eines Containers auszuführen, kannst du ihn mit einem einzigen Befehl wie folgt ausführen.
$ docker compose exec -u zulip zulip \ /home/zulip/deployments/current/manage.py help <subcommand>
Es gibt aber auch eine einfachere Methode, dies zu tun. Wir können ein Shell-Skript zum Ausführen von Befehlen erstellen. Erstelle und öffne zulip_manage.sh
zum Bearbeiten.
$ nano zulip_manage.sh
Füge den folgenden Code in die Datei ein.
#!/bin/sh docker compose exec -u zulip zulip /home/zulip/deployments/current/manage.py "$@"
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Mache das Skript ausführbar.
$ chmod +x zulip_manage.sh
Um den Zulip-Server anzuhalten, verwende den folgenden Befehl.
$ docker exec -u zulip zulip /home/zulip/deployments/current/scripts/stop-server process-fts-updates: stopped zulip-django: stopped zulip-tornado: stopped zulip-workers:zulip_events_deferred_work: stopped zulip-workers:zulip_events_digest_emails: stopped zulip-workers:zulip_events_email_mirror: stopped zulip-workers:zulip_events_email_senders: stopped zulip-workers:zulip_events_embed_links: stopped zulip-workers:zulip_events_embedded_bots: stopped zulip-workers:zulip_events_invites: stopped zulip-workers:zulip_events_missedmessage_emails: stopped zulip-workers:zulip_events_missedmessage_mobile_notifications: stopped zulip-workers:zulip_events_outgoing_webhooks: stopped zulip-workers:zulip_events_user_activity: stopped zulip-workers:zulip_events_user_activity_interval: stopped zulip-workers:zulip_events_user_presence: stopped zulip_deliver_scheduled_emails: stopped zulip_deliver_scheduled_messages: stopped Zulip stopped successfully!
Um den Server wieder zu starten, verwende den folgenden Befehl.
$ docker exec -u zulip zulip /home/zulip/deployments/current/scripts/start-server 2024-02-21 09:18:52,932 start-server: Running syntax and database checks System check identified no issues (28 silenced). 2024-02-21 09:18:54,944 start-server: Starting Tornado process zulip-tornado: started 2024-02-21 09:18:56,089 start-server: Starting django server zulip-django: started 2024-02-21 09:18:58,133 start-server: Starting workers process-fts-updates: started zulip-workers:zulip_events_deferred_work: started zulip-workers:zulip_events_digest_emails: started zulip-workers:zulip_events_email_mirror: started zulip-workers:zulip_events_email_senders: started zulip-workers:zulip_events_embed_links: started zulip-workers:zulip_events_embedded_bots: started zulip-workers:zulip_events_invites: started zulip-workers:zulip_events_missedmessage_emails: started zulip-workers:zulip_events_missedmessage_mobile_notifications: started zulip-workers:zulip_events_outgoing_webhooks: started zulip-workers:zulip_events_user_activity: started zulip-workers:zulip_events_user_activity_interval: started zulip-workers:zulip_events_user_presence: started zulip_deliver_scheduled_emails: started zulip_deliver_scheduled_messages: started 2024-02-21 09:19:19,571 start-server: Done! Zulip started successfully!
Starte den Server auf ähnliche Weise neu.
$ docker exec -u zulip zulip /home/zulip/deployments/current/scripts/restart-server
Es gibt viele Verwaltungsaufgaben, die du mit dem manage.py
Skript, das mit Zulip geliefert wird, erledigen kannst.
Du kannst das Skript mit dem folgenden Befehl ausführen. Wir werden den Unterbefehl help
verwenden, um alle möglichen Operationen aufzulisten, die man durchführen kann.
$ ./zulip_manage.sh help Type 'manage.py help <subcommand>' for help on a specific subcommand. Available subcommands: [analytics] check_analytics_state clear_analytics_tables clear_single_stat populate_analytics_db update_analytics_counts [django] dbshell makemigrations migrate shell showmigrations [zerver] add_users_to_streams archive_messages audit_fts_indexes backup bulk_change_user_name change_password change_realm_subdomain change_user_email change_user_role check_redis checkconfig compilemessages convert_gitter_data convert_mattermost_data convert_rocketchat_data convert_slack_data create_default_stream_groups create_realm create_realm_internal_bots create_stream create_user deactivate_realm deactivate_user delete_old_unclaimed_attachments delete_realm delete_user deliver_scheduled_emails deliver_scheduled_messages edit_linkifiers email_mirror enqueue_digest_emails enqueue_file export export_search export_single_user export_usermessage_batch fetch_tor_exit_nodes fill_memcached_caches generate_realm_creation_link get_migration_status import list_realms logout_all_users makemessages merge_streams process_queue promote_new_full_members purge_queue query_ldap rate_limit reactivate_realm realm_domain register_server remove_users_from_stream reset_authentication_attempt_count restore_messages runtornado scrub_realm send_custom_email send_password_reset_email send_realm_reactivation_email send_test_email send_to_email_mirror send_webhook_fixture_message send_welcome_bot_message show_admins soft_deactivate_users sync_ldap_user_data transfer_uploads_to_s3 unarchive_stream
Die Datei entrypoint.sh von Docker bietet noch ein paar andere Optionen. Führe den folgenden Befehl aus, um sie zu sehen.
$ docker exec -it zulip bash /sbin/entrypoint.sh app:help
Du solltest die folgende Ausgabe sehen.
Available commands: > app:help - Show this help menu and exit > app:version - Container Zulip server version > app:managepy - Run Zulip's manage.py script (defaults to "shell") > app:backup - Create backups of Zulip instances > app:restore - Restore backups of Zulip instances > app:certs - Create self-signed certificates > app:run - Run the Zulip server > [COMMAND] - Run given command with arguments in shell
Schritt 11 – Ausgehende E-Mails testen
Um deine Konfiguration für ausgehende E-Mails zu testen, kannst du mit dem folgenden Befehl eine Test-E-Mail versenden.
$ ~/docker-zulip/zulip_manage.sh send_test_email user@example.com If you run into any trouble, read: https://zulip.readthedocs.io/en/latest/production/email.html#troubleshooting The most common error is not setting `ADD_TOKENS_TO_NOREPLY_ADDRESS=False` when using an email provider that doesn't support that feature. Sending 2 test emails from: * user@zulip.example.com * noreply@zulip.example.com Successfully sent 2 emails to user@example.com
Schritt 12 – Upgrades von Zulip
Der erste Schritt beim Upgrade von Zulip besteht darin, die vorhandenen Container zu stoppen.
$ cd ~/docker-zulip $ docker compose stop
Öffne die Datei docker-compose.yml
zur Bearbeitung.
$ nano docker-compose.yml
Überprüfe die neueste verfügbare Version auf der DockerHub Tags-Seite von Zulip. Ändere die Version im folgenden Abschnitt.
..... zulip: image: "zulip/docker-zulip:8.2-0" restart: unless-stopped container_name: zulip ....
Nimm alle anderen Änderungen vor, die du brauchst. Du musst dafür im Changelog von Zulip und im Docker GitHub Repository von Zulip nachsehen.
Wenn du fertig bist, speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Starten Sie die Container erneut. Der Zulip-Container wird mit den Änderungen neu erstellt.
$ docker compose up -d
Entferne alle alten Container.
$ docker compose rm
Fazit
Damit ist unsere Anleitung zur Installation und Konfiguration des Zulip Chat-Servers auf einem Rocky Linux 9 Server abgeschlossen. Du kannst die offizielle Dokumentation von Zulip lesen, um mehr zu erfahren. Wenn du Fragen hast, schreibe sie unten in die Kommentare.