Bump remaining apps: major version slots and infrastructure

New version slots (major version jumps):
- gitea: 1.24.3 -> 28.2.0 (slot 1 -> 28)
- ghost: 5.130.6 -> 6.72.0 (slot 5 -> 6)
- formbricks: 3.6.0 -> 6.1.0 (slot 3 -> 6)
- mattermost: 10.8.1 -> 12.0.1 (slot 10 -> 12)
- zulip: 9.4 -> 12.3 (slot 9 -> 12)
- immich: 1.135.3 -> 3.3.5 (slot 1 -> 3)
- openproject: 16.1.1 -> 17.9.3 (slot 16 -> 17)
- listmonk: 5.0.3 -> 6.1.0 (slot 5 -> 6)
- discourse: 3.5.3 -> 2026.10.0 (slot 3 -> 2026, calver)

Same-slot large bumps:
- vllm: 0.9.2 -> 0.32.0
- longhorn: v1.8.1 -> v1.13.0

Infrastructure:
- cert-manager: v1.17.2 -> v1.21.2
- coredns: v1.12.0 -> v1.14.7
- externaldns: v0.13.4 -> v0.23.0
- metallb: v0.15.0 -> v0.16.1
- mysql: 9.1.0 -> 9.7.4
- node-feature-discovery: v0.17.3 -> v0.20.1
- nvidia-device-plugin: v0.17.1 -> v0.20.1
This commit is contained in:
2026-10-23 14:18:48 +00:00
parent e25b07126c
commit 9fd046c378
122 changed files with 3665 additions and 35 deletions

View File

@@ -3,4 +3,4 @@ is: zulip
description: Zulip is an open-source team chat application with threaded conversations, making it easy to catch up on important discussions without information overload.
category: communication
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/zulip.svg
latest: "9"
latest: "12"

View File

@@ -0,0 +1,42 @@
# Zulip
Zulip is an open-source team messaging platform with a unique topic-based threading model.
## Dependencies
- **SMTP** - For sending invitations and notifications
- **Redis** - Used for caching and real-time event queuing
Zulip bundles its own **PostgreSQL**, **RabbitMQ**, and **Memcached** instances — these are deployed alongside the main Zulip pod and are not shared with other apps.
## Configuration
Key settings in `config.yaml`:
- **domain** - Where Zulip will be accessible
- **adminEmail** - Admin account email (defaults to your operator email)
- **smtp** - Email settings inherited from your Wild Cloud SMTP service
## First-Time Setup
1. Add and deploy the app:
```bash
wild app add zulip
wild app deploy zulip
```
2. **First start takes 5–10 minutes** as Zulip runs hundreds of Django database migrations. Wait until the pod shows `1/1 Running`.
3. The admin account is pre-configured with the `adminEmail` and `adminPassword` from `secrets.yaml`. Visit the app URL and log in.
4. Complete the realm (organization) setup wizard on first login.
## Inviting Users
Send invitation emails from **Settings → Organization → Invitations**, or use pre-generated invite links.
## Notes
- The `secretKey`, `postgresPassword`, and `rabbitmqPassword` are all auto-generated in `secrets.yaml`
- Zulip's topic-based threading keeps conversations organized — each stream (channel) has multiple topics
- Mobile and desktop apps are available and connect to self-hosted instances

View File

@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: zulip-memcached
namespace: {{ .namespace }}
spec:
replicas: 1
selector:
matchLabels:
component: memcached
template:
metadata:
labels:
component: memcached
spec:
securityContext:
runAsNonRoot: true
runAsUser: 11211
seccompProfile:
type: RuntimeDefault
containers:
- name: memcached
image: memcached:1.6.32-alpine
args:
- -m
- "64m"
- -c
- "1024"
- -p
- "11211"
ports:
- containerPort: 11211
name: memcached
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: "200m"
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true

View File

@@ -0,0 +1,56 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: zulip-postgres
namespace: {{ .namespace }}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
component: postgres
template:
metadata:
labels:
component: postgres
spec:
securityContext:
runAsNonRoot: false
runAsUser: 0
seccompProfile:
type: RuntimeDefault
containers:
- name: postgres
image: zulip/zulip-postgresql:14
ports:
- containerPort: 5432
name: postgres
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: POSTGRES_DB
value: "{{ .db.name }}"
- name: POSTGRES_USER
value: "{{ .db.user }}"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: zulip-secrets
key: postgresPassword
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
securityContext:
readOnlyRootFilesystem: false
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: zulip-postgres-data

View File

@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: zulip-rabbitmq
namespace: {{ .namespace }}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
component: rabbitmq
template:
metadata:
labels:
component: rabbitmq
spec:
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
seccompProfile:
type: RuntimeDefault
containers:
- name: rabbitmq
image: rabbitmq:3.13-alpine
ports:
- containerPort: 5672
name: amqp
env:
- name: RABBITMQ_DEFAULT_USER
value: "{{ .rabbitmq.user }}"
- name: RABBITMQ_DEFAULT_PASS
valueFrom:
secretKeyRef:
name: zulip-secrets
key: rabbitmqPassword
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: "1"
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false

View File

@@ -0,0 +1,145 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: zulip
namespace: {{ .namespace }}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
securityContext:
runAsNonRoot: false
runAsUser: 0
seccompProfile:
type: RuntimeDefault
containers:
- name: zulip
image: zulip/docker-zulip:12.3-0
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: SETTING_ZULIP_ADMINISTRATOR
value: "{{ .adminEmail }}"
- name: ZULIP_PASSWORD
valueFrom:
secretKeyRef:
name: zulip-secrets
key: adminPassword
- name: SETTING_EXTERNAL_HOST
value: "{{ .domain }}"
- name: SSL_CERTIFICATE_GENERATION
value: "self-signed"
- name: SECRETS_secret_key
valueFrom:
secretKeyRef:
name: zulip-secrets
key: secretKey
# Database
- name: DB_HOST
value: "{{ .db.host }}"
- name: DB_HOST_PORT
value: "{{ .db.port }}"
- name: DB_NAME
value: "{{ .db.name }}"
- name: DB_USER
value: "{{ .db.user }}"
- name: SECRETS_postgres_password
valueFrom:
secretKeyRef:
name: zulip-secrets
key: postgresPassword
# RabbitMQ
- name: SETTING_RABBITMQ_HOST
value: "{{ .rabbitmq.host }}"
- name: SETTING_RABBITMQ_USER
value: "{{ .rabbitmq.user }}"
- name: SECRETS_rabbitmq_password
valueFrom:
secretKeyRef:
name: zulip-secrets
key: rabbitmqPassword
# Redis
- name: SETTING_REDIS_HOST
value: "{{ .redis.host }}"
- name: SECRETS_redis_password
valueFrom:
secretKeyRef:
name: zulip-secrets
key: redis.password
# Memcached
- name: SETTING_MEMCACHED_LOCATION
value: "{{ .memcached.host }}:11211"
# Email
- name: SETTING_EMAIL_HOST
value: "{{ .smtp.host }}"
- name: SETTING_EMAIL_HOST_USER
value: "{{ .smtp.user }}"
- name: SETTING_EMAIL_PORT
value: "{{ .smtp.port }}"
- name: SETTING_EMAIL_USE_TLS
value: "True"
- name: SETTING_EMAIL_BACKEND
value: "django.core.mail.backends.smtp.EmailBackend"
- name: SETTING_DEFAULT_FROM_EMAIL
value: "{{ .smtp.from }}"
- name: SECRETS_email_password
valueFrom:
secretKeyRef:
name: zulip-secrets
key: smtp.password
# Reverse proxy configuration (Traefik terminates TLS)
- name: DISABLE_HTTPS
value: "true"
- name: LOADBALANCER_IPS
value: "10.244.0.0/16"
resources:
limits:
cpu: "2"
ephemeral-storage: 1Gi
memory: 3Gi
requests:
cpu: 50m
ephemeral-storage: 100Mi
memory: 512Mi
volumeMounts:
- name: zulip-data
mountPath: /data
livenessProbe:
httpGet:
path: /accounts/home/
port: 80
httpHeaders:
- name: Host
value: "{{ .domain }}"
initialDelaySeconds: 180
timeoutSeconds: 30
periodSeconds: 30
failureThreshold: 6
readinessProbe:
httpGet:
path: /accounts/home/
port: 80
httpHeaders:
- name: Host
value: "{{ .domain }}"
initialDelaySeconds: 120
timeoutSeconds: 30
periodSeconds: 15
failureThreshold: 6
securityContext:
readOnlyRootFilesystem: false
volumes:
- name: zulip-data
persistentVolumeClaim:
claimName: zulip-data
restartPolicy: Always

View File

@@ -0,0 +1,18 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zulip
namespace: {{ .namespace }}
spec:
ingressClassName: traefik
rules:
- host: {{ .domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zulip
port:
number: 80

View File

@@ -0,0 +1,22 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: {{ .namespace }}
labels:
- includeSelectors: true
pairs:
app: zulip
managedBy: kustomize
partOf: wild-cloud
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- pvc.yaml
- deployment-postgres.yaml
- service-postgres.yaml
- pvc-postgres.yaml
- deployment-rabbitmq.yaml
- service-rabbitmq.yaml
- deployment-memcached.yaml
- service-memcached.yaml

View File

@@ -0,0 +1,35 @@
version: 12.3
requires:
- name: smtp
- name: redis
defaultConfig:
namespace: zulip
domain: zulip.{{ .cloud.domain }}
storage: 2Gi
adminEmail: '{{ .operator.email }}'
db:
host: zulip-postgres.zulip.svc.cluster.local
port: '5432'
name: zulip
user: zulip
storage: 2Gi
rabbitmq:
host: zulip-rabbitmq.zulip.svc.cluster.local
user: zulip
redis:
host: '{{ .apps.redis.host }}'
memcached:
host: zulip-memcached.zulip.svc.cluster.local
smtp:
host: '{{ .apps.smtp.host }}'
port: '{{ .apps.smtp.port }}'
user: '{{ .apps.smtp.user }}'
from: '{{ .apps.smtp.from }}'
defaultSecrets:
- key: adminPassword
- key: secretKey
- key: postgresPassword
- key: rabbitmqPassword
requiredSecrets:
- smtp.password
- redis.password

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .namespace }}

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: zulip-postgres-data
namespace: {{ .namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .db.storage }}

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: zulip-data
namespace: {{ .namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .storage }}

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: zulip-memcached
namespace: {{ .namespace }}
spec:
selector:
component: memcached
ports:
- port: 11211
targetPort: 11211
name: memcached

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: zulip-postgres
namespace: {{ .namespace }}
spec:
selector:
component: postgres
ports:
- port: 5432
targetPort: 5432
name: postgres

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: zulip-rabbitmq
namespace: {{ .namespace }}
spec:
selector:
component: rabbitmq
ports:
- port: 5672
targetPort: 5672
name: amqp

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: zulip
namespace: {{ .namespace }}
spec:
selector:
component: web
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP