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:
@@ -1,4 +1,4 @@
|
|||||||
version: v1.17.2-1
|
version: v1.21.2
|
||||||
requires:
|
requires:
|
||||||
- name: traefik
|
- name: traefik
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
|
|||||||
@@ -12981,7 +12981,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: cert-manager-cainjector
|
- name: cert-manager-cainjector
|
||||||
image: "quay.io/jetstack/cert-manager-cainjector:v1.17.2"
|
image: "quay.io/jetstack/cert-manager-cainjector:v1.21.2"
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
args:
|
args:
|
||||||
- --v=2
|
- --v=2
|
||||||
@@ -13044,7 +13044,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: cert-manager-controller
|
- name: cert-manager-controller
|
||||||
image: "quay.io/jetstack/cert-manager-controller:v1.17.2"
|
image: "quay.io/jetstack/cert-manager-controller:v1.21.2"
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
args:
|
args:
|
||||||
- --v=2
|
- --v=2
|
||||||
@@ -13126,7 +13126,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: cert-manager-webhook
|
- name: cert-manager-webhook
|
||||||
image: "quay.io/jetstack/cert-manager-webhook:v1.17.2"
|
image: "quay.io/jetstack/cert-manager-webhook:v1.21.2"
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
args:
|
args:
|
||||||
- --v=2
|
- --v=2
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v1.12.0-1
|
version: v1.14.7
|
||||||
requires:
|
requires:
|
||||||
- name: metallb
|
- name: metallb
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ is: discourse
|
|||||||
description: Discourse is a modern, open-source discussion platform designed for online communities and forums.
|
description: Discourse is a modern, open-source discussion platform designed for online communities and forums.
|
||||||
category: community
|
category: community
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/discourse.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/discourse.svg
|
||||||
latest: "3"
|
latest: "2026"
|
||||||
|
|||||||
35
discourse/versions/2026/README.md
Normal file
35
discourse/versions/2026/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Discourse
|
||||||
|
|
||||||
|
Discourse is a modern, open-source discussion platform designed for online communities and forums.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing application data
|
||||||
|
- **Redis** - Used for caching and background jobs
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings configured through your instance's `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Discourse will be accessible (default: `discourse.{your-cloud-domain}`)
|
||||||
|
- **adminEmail** - Admin account email (defaults to your operator email)
|
||||||
|
- **adminUsername** - Admin account username (default: `admin`)
|
||||||
|
- **siteName** - Your community name (default: `Community`)
|
||||||
|
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
After deployment, Discourse will be available at:
|
||||||
|
- `https://discourse.{your-cloud-domain}`
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add discourse
|
||||||
|
wild app deploy discourse
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in with the admin credentials configured during setup
|
||||||
|
|
||||||
|
3. Complete the setup wizard to configure your community
|
||||||
78
discourse/versions/2026/db-init-job.yaml
Normal file
78
discourse/versions/2026/db-init-job.yaml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: discourse-db-init
|
||||||
|
namespace: discourse
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: postgres:16-alpine
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: PGPORT
|
||||||
|
value: "5432"
|
||||||
|
- name: PGUSER
|
||||||
|
value: postgres
|
||||||
|
- name: PGPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: postgres.password
|
||||||
|
- name: DISCOURSE_DB_USER
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DISCOURSE_DB_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DISCOURSE_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: dbPassword
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Initializing Discourse database..."
|
||||||
|
|
||||||
|
# Create database if it doesn't exist
|
||||||
|
if ! psql -lqt | cut -d \| -f 1 | grep -qw "$DISCOURSE_DB_NAME"; then
|
||||||
|
echo "Creating database $DISCOURSE_DB_NAME..."
|
||||||
|
createdb "$DISCOURSE_DB_NAME"
|
||||||
|
else
|
||||||
|
echo "Database $DISCOURSE_DB_NAME already exists."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create user if it doesn't exist and grant permissions
|
||||||
|
psql -d "$DISCOURSE_DB_NAME" -c "
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '$DISCOURSE_DB_USER') THEN
|
||||||
|
CREATE USER $DISCOURSE_DB_USER WITH PASSWORD '$DISCOURSE_DB_PASSWORD';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
ALTER USER $DISCOURSE_DB_USER WITH PASSWORD '$DISCOURSE_DB_PASSWORD';
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE $DISCOURSE_DB_NAME TO $DISCOURSE_DB_USER;
|
||||||
|
GRANT ALL ON SCHEMA public TO $DISCOURSE_DB_USER;
|
||||||
|
GRANT USAGE ON SCHEMA public TO $DISCOURSE_DB_USER;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "Database initialization completed."
|
||||||
304
discourse/versions/2026/deployment.yaml
Normal file
304
discourse/versions/2026/deployment.yaml
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: discourse
|
||||||
|
namespace: discourse
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: web
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: web
|
||||||
|
spec:
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
serviceAccountName: discourse
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
fsGroupChangePolicy: Always
|
||||||
|
initContainers:
|
||||||
|
- name: discourse-migrate
|
||||||
|
image: discourse/discourse:2026.10.0
|
||||||
|
imagePullPolicy: "IfNotPresent"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- CHOWN
|
||||||
|
- FOWNER
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- DAC_OVERRIDE
|
||||||
|
privileged: false
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
runAsNonRoot: false
|
||||||
|
runAsUser: 0
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
cd /var/www/discourse
|
||||||
|
export HOME=/root
|
||||||
|
git config --global --add safe.directory /var/www/discourse
|
||||||
|
bundle exec rake db:migrate
|
||||||
|
bundle exec rake assets:precompile
|
||||||
|
env:
|
||||||
|
- name: RAILS_ENV
|
||||||
|
value: "production"
|
||||||
|
- name: DISCOURSE_DB_HOST
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: DISCOURSE_DB_PORT
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: DISCOURSE_DB_NAME
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: DISCOURSE_DB_USERNAME
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: DISCOURSE_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: DISCOURSE_REDIS_HOST
|
||||||
|
value: {{ .redis.host }}
|
||||||
|
- name: DISCOURSE_REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: redis.password
|
||||||
|
- name: DISCOURSE_HOSTNAME
|
||||||
|
value: {{ .domain }}
|
||||||
|
- name: DISCOURSE_SECRET_KEY_BASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: secretKeyBase
|
||||||
|
volumeMounts:
|
||||||
|
- name: discourse-data
|
||||||
|
mountPath: /shared
|
||||||
|
containers:
|
||||||
|
- name: discourse
|
||||||
|
image: discourse/discourse:2026.10.0
|
||||||
|
imagePullPolicy: "IfNotPresent"
|
||||||
|
command:
|
||||||
|
- /sbin/boot
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- CHOWN
|
||||||
|
- FOWNER
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- DAC_OVERRIDE
|
||||||
|
privileged: false
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
runAsNonRoot: false
|
||||||
|
runAsUser: 0
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
env:
|
||||||
|
- name: RAILS_ENV
|
||||||
|
value: "production"
|
||||||
|
# Discourse database configuration
|
||||||
|
- name: DISCOURSE_DB_HOST
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: DISCOURSE_DB_PORT
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: DISCOURSE_DB_NAME
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: DISCOURSE_DB_USERNAME
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: DISCOURSE_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: dbPassword
|
||||||
|
# Redis configuration
|
||||||
|
- name: DISCOURSE_REDIS_HOST
|
||||||
|
value: {{ .redis.host }}
|
||||||
|
- name: DISCOURSE_REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: redis.password
|
||||||
|
# Site configuration
|
||||||
|
- name: DISCOURSE_HOSTNAME
|
||||||
|
value: {{ .domain }}
|
||||||
|
- name: DISCOURSE_DEVELOPER_EMAILS
|
||||||
|
value: {{ .adminEmail }}
|
||||||
|
- name: DISCOURSE_SECRET_KEY_BASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: secretKeyBase
|
||||||
|
# SMTP configuration
|
||||||
|
- name: DISCOURSE_SMTP_ADDRESS
|
||||||
|
value: {{ .smtp.host }}
|
||||||
|
- name: DISCOURSE_SMTP_PORT
|
||||||
|
value: "{{ .smtp.port }}"
|
||||||
|
- name: DISCOURSE_SMTP_USER_NAME
|
||||||
|
value: {{ .smtp.user }}
|
||||||
|
- name: DISCOURSE_SMTP_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: smtpPassword
|
||||||
|
- name: DISCOURSE_SMTP_ENABLE_START_TLS
|
||||||
|
value: "{{ .smtp.startTls }}"
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /srv/status
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 500
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /srv/status
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 360
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 6
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 2000m
|
||||||
|
ephemeral-storage: 10Gi
|
||||||
|
memory: 8Gi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 512Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: discourse-data
|
||||||
|
mountPath: /shared
|
||||||
|
- name: sidekiq
|
||||||
|
image: discourse/discourse:2026.10.0
|
||||||
|
imagePullPolicy: "IfNotPresent"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
add:
|
||||||
|
- CHOWN
|
||||||
|
- FOWNER
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- DAC_OVERRIDE
|
||||||
|
privileged: false
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
runAsNonRoot: false
|
||||||
|
runAsUser: 0
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- "cd /var/www/discourse && export HOME=/root && exec bundle exec sidekiq"
|
||||||
|
env:
|
||||||
|
- name: RAILS_ENV
|
||||||
|
value: "production"
|
||||||
|
# Discourse database configuration
|
||||||
|
- name: DISCOURSE_DB_HOST
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: DISCOURSE_DB_PORT
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: DISCOURSE_DB_NAME
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: DISCOURSE_DB_USERNAME
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: DISCOURSE_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: dbPassword
|
||||||
|
# Redis configuration
|
||||||
|
- name: DISCOURSE_REDIS_HOST
|
||||||
|
value: {{ .redis.host }}
|
||||||
|
- name: DISCOURSE_REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: redis.password
|
||||||
|
# Site configuration
|
||||||
|
- name: DISCOURSE_HOSTNAME
|
||||||
|
value: {{ .domain }}
|
||||||
|
- name: DISCOURSE_DEVELOPER_EMAILS
|
||||||
|
value: {{ .adminEmail }}
|
||||||
|
- name: DISCOURSE_SECRET_KEY_BASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: secretKeyBase
|
||||||
|
# SMTP configuration
|
||||||
|
- name: DISCOURSE_SMTP_ADDRESS
|
||||||
|
value: {{ .smtp.host }}
|
||||||
|
- name: DISCOURSE_SMTP_PORT
|
||||||
|
value: "{{ .smtp.port }}"
|
||||||
|
- name: DISCOURSE_SMTP_USER_NAME
|
||||||
|
value: {{ .smtp.user }}
|
||||||
|
- name: DISCOURSE_SMTP_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: discourse-secrets
|
||||||
|
key: smtpPassword
|
||||||
|
- name: DISCOURSE_SMTP_ENABLE_START_TLS
|
||||||
|
value: "{{ .smtp.startTls }}"
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- "pgrep -f sidekiq"
|
||||||
|
initialDelaySeconds: 500
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- "pgrep -f sidekiq"
|
||||||
|
initialDelaySeconds: 180
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 6
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
ephemeral-storage: 2Gi
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 512Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: discourse-data
|
||||||
|
mountPath: /shared
|
||||||
|
volumes:
|
||||||
|
- name: discourse-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: discourse-data
|
||||||
20
discourse/versions/2026/ingress.yaml
Normal file
20
discourse/versions/2026/ingress.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
# Source: discourse/templates/ingress.yaml
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: discourse
|
||||||
|
namespace: "{{ .namespace }}"
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: "{{ .domain }}"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: ImplementationSpecific
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: discourse
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
17
discourse/versions/2026/kustomization.yaml
Normal file
17
discourse/versions/2026/kustomization.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: discourse
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: discourse
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- serviceaccount.yaml
|
||||||
|
- pvc.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
39
discourse/versions/2026/manifest.yaml
Normal file
39
discourse/versions/2026/manifest.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
version: 2026.10.0
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
- name: redis
|
||||||
|
- name: smtp
|
||||||
|
defaultConfig:
|
||||||
|
namespace: discourse
|
||||||
|
storage: 2Gi
|
||||||
|
adminEmail: '{{ .operator.email }}'
|
||||||
|
adminUsername: admin
|
||||||
|
siteName: Community
|
||||||
|
domain: discourse.{{ .cloud.domain }}
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
name: discourse
|
||||||
|
user: discourse
|
||||||
|
redis:
|
||||||
|
host: '{{ .apps.redis.host }}'
|
||||||
|
smtp:
|
||||||
|
enabled: false
|
||||||
|
host: '{{ .apps.smtp.host }}'
|
||||||
|
port: '{{ .apps.smtp.port }}'
|
||||||
|
user: '{{ .apps.smtp.user }}'
|
||||||
|
from: '{{ .apps.smtp.from }}'
|
||||||
|
tls: '{{ .apps.smtp.tls }}'
|
||||||
|
startTls: '{{ .apps.smtp.startTls }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: adminPassword
|
||||||
|
- key: secretKeyBase
|
||||||
|
default: '{{ random.Hex 32 }}'
|
||||||
|
- key: smtpPassword
|
||||||
|
- key: dbPassword
|
||||||
|
- key: dbUrl
|
||||||
|
default: postgres://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host
|
||||||
|
}}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
|
- redis.password
|
||||||
4
discourse/versions/2026/namespace.yaml
Normal file
4
discourse/versions/2026/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
13
discourse/versions/2026/pvc.yaml
Normal file
13
discourse/versions/2026/pvc.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: discourse-data
|
||||||
|
namespace: discourse
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
|
storageClassName: longhorn
|
||||||
18
discourse/versions/2026/service.yaml
Normal file
18
discourse/versions/2026/service.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
# Source: discourse/templates/service.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: discourse
|
||||||
|
namespace: discourse
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
sessionAffinity: None
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
|
nodePort: null
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
8
discourse/versions/2026/serviceaccount.yaml
Normal file
8
discourse/versions/2026/serviceaccount.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
# Source: discourse/templates/serviceaccount.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: discourse
|
||||||
|
namespace: discourse
|
||||||
|
automountServiceAccountToken: false
|
||||||
@@ -22,7 +22,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: external-dns
|
- name: external-dns
|
||||||
image: registry.k8s.io/external-dns/external-dns:v0.13.4
|
image: registry.k8s.io/external-dns/external-dns:v0.23.0
|
||||||
args:
|
args:
|
||||||
- --source=service
|
- --source=service
|
||||||
- --source=ingress
|
- --source=ingress
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v0.13.4-6
|
version: v0.23.0
|
||||||
deploymentName: external-dns
|
deploymentName: external-dns
|
||||||
requires:
|
requires:
|
||||||
- name: cert-manager
|
- name: cert-manager
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ is: formbricks
|
|||||||
description: Formbricks is an open-source survey and form platform for collecting and analyzing user feedback. A self-hosted alternative to Typeform and SurveyMonkey.
|
description: Formbricks is an open-source survey and form platform for collecting and analyzing user feedback. A self-hosted alternative to Typeform and SurveyMonkey.
|
||||||
category: business
|
category: business
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/formbricks.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/formbricks.svg
|
||||||
latest: "3"
|
latest: "6"
|
||||||
|
|||||||
36
formbricks/versions/6/README.md
Normal file
36
formbricks/versions/6/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Formbricks
|
||||||
|
|
||||||
|
Formbricks is an open-source survey and feedback platform for building in-app microsurveys, NPS scores, and user research forms.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing surveys and responses
|
||||||
|
- **Redis** - Used for caching and background jobs
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings in `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Formbricks will be accessible
|
||||||
|
- **storage** - Persistent volume size (default: `2Gi`)
|
||||||
|
- **db.name** - Database name (default: `formbricks`)
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add formbricks
|
||||||
|
wild app deploy formbricks
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Visit the app URL and sign up to create your admin account.
|
||||||
|
|
||||||
|
3. The first user to sign up becomes the organization owner.
|
||||||
|
|
||||||
|
4. Create your first survey from the dashboard and embed it in your apps using the provided JavaScript snippet.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Formbricks can be embedded in web apps or used as a standalone survey link
|
||||||
|
- The `nextauthSecret` and `encryptionKey` are auto-generated in `secrets.yaml`
|
||||||
|
- The `cronSecret` secures the internal cron endpoint used for scheduled tasks
|
||||||
61
formbricks/versions/6/db-init-job.yaml
Normal file
61
formbricks/versions/6/db-init-job.yaml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: formbricks-db-init
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: postgres:17
|
||||||
|
command: ["/bin/bash", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres <<EOF
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USER}') THEN
|
||||||
|
CREATE USER ${DB_USER} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
ELSE
|
||||||
|
ALTER USER ${DB_USER} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
|
||||||
|
SELECT 'CREATE DATABASE ${DB_NAME}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_NAME}')\gexec
|
||||||
|
ALTER DATABASE ${DB_NAME} OWNER TO ${DB_USER};
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};
|
||||||
|
EOF
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};"
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres -d ${DB_NAME} -c "CREATE EXTENSION IF NOT EXISTS vector;"
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_ADMIN_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: postgres.password
|
||||||
|
- name: DB_HOST
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DB_USER
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: dbPassword
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
restartPolicy: OnFailure
|
||||||
102
formbricks/versions/6/deployment.yaml
Normal file
102
formbricks/versions/6/deployment.yaml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: formbricks
|
||||||
|
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: formbricks
|
||||||
|
image: formbricks/formbricks:6.1.0
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: NODE_OPTIONS
|
||||||
|
value: "--max-old-space-size=768"
|
||||||
|
- name: WEBAPP_URL
|
||||||
|
value: "https://{{ .domain }}"
|
||||||
|
- name: NEXTAUTH_URL
|
||||||
|
value: "https://{{ .domain }}"
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: dbUrl
|
||||||
|
- name: NEXTAUTH_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: nextauthSecret
|
||||||
|
- name: ENCRYPTION_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: encryptionKey
|
||||||
|
- name: CRON_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: cronSecret
|
||||||
|
- name: REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: formbricks-secrets
|
||||||
|
key: redis.password
|
||||||
|
- name: REDIS_URL
|
||||||
|
value: "redis://:$(REDIS_PASSWORD)@{{ .redis.host }}:6379"
|
||||||
|
- name: EMAIL_VERIFICATION_DISABLED
|
||||||
|
value: "1"
|
||||||
|
- name: PASSWORD_RESET_DISABLED
|
||||||
|
value: "1"
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: "1"
|
||||||
|
ephemeral-storage: 1Gi
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 256Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: formbricks-uploads
|
||||||
|
mountPath: /home/nextjs/apps/web/uploads
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 90
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 15
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 60
|
||||||
|
timeoutSeconds: 3
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumes:
|
||||||
|
- name: formbricks-uploads
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: formbricks-uploads
|
||||||
|
restartPolicy: Always
|
||||||
18
formbricks/versions/6/ingress.yaml
Normal file
18
formbricks/versions/6/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: formbricks
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: {{ .domain }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: formbricks
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
16
formbricks/versions/6/kustomization.yaml
Normal file
16
formbricks/versions/6/kustomization.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: formbricks
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- pvc.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
26
formbricks/versions/6/manifest.yaml
Normal file
26
formbricks/versions/6/manifest.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
version: 6.1.0
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
- name: redis
|
||||||
|
defaultConfig:
|
||||||
|
namespace: formbricks
|
||||||
|
domain: formbricks.{{ .cloud.domain }}
|
||||||
|
storage: 2Gi
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
name: formbricks
|
||||||
|
user: formbricks
|
||||||
|
redis:
|
||||||
|
host: '{{ .apps.redis.host }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
- key: dbUrl
|
||||||
|
default: postgresql://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host
|
||||||
|
}}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable
|
||||||
|
- key: nextauthSecret
|
||||||
|
- key: encryptionKey
|
||||||
|
- key: cronSecret
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
|
- redis.password
|
||||||
4
formbricks/versions/6/namespace.yaml
Normal file
4
formbricks/versions/6/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ .namespace }}
|
||||||
11
formbricks/versions/6/pvc.yaml
Normal file
11
formbricks/versions/6/pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: formbricks-uploads
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
13
formbricks/versions/6/service.yaml
Normal file
13
formbricks/versions/6/service.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: formbricks
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 3000
|
||||||
|
protocol: TCP
|
||||||
@@ -3,4 +3,4 @@ is: ghost
|
|||||||
description: Ghost is a powerful app for new-media creators to publish, share, and grow a business around their content.
|
description: Ghost is a powerful app for new-media creators to publish, share, and grow a business around their content.
|
||||||
category: social
|
category: social
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/ghost.png
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/ghost.png
|
||||||
latest: "5"
|
latest: "6"
|
||||||
|
|||||||
33
ghost/versions/6/README.md
Normal file
33
ghost/versions/6/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Ghost
|
||||||
|
|
||||||
|
Ghost is a powerful app for new-media creators to publish, share, and grow a business around their content. It provides a clean writing experience with built-in membership and subscription features.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **MySQL** - Database for storing content and configuration
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings configured through your instance's `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Ghost will be accessible (default: `ghost.{your-cloud-domain}`)
|
||||||
|
- **blogTitle** - Your blog's title (default: `My Blog`)
|
||||||
|
- **adminEmail** - Admin account email (defaults to your operator email)
|
||||||
|
- **storage** - Persistent volume size for content (default: `10Gi`)
|
||||||
|
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
After deployment, Ghost will be available at:
|
||||||
|
- `https://ghost.{your-cloud-domain}` - Public blog
|
||||||
|
- `https://ghost.{your-cloud-domain}/ghost` - Admin panel
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add ghost
|
||||||
|
wild app deploy ghost
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Navigate to the admin panel and create your first post
|
||||||
45
ghost/versions/6/db-init-job.yaml
Normal file
45
ghost/versions/6/db-init-job.yaml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: ghost-db-init
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: mysql:9.1.0
|
||||||
|
command: ["/bin/bash", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
mysql -h ${DB_HOSTNAME} -P ${DB_PORT} -u root -p${MYSQL_ROOT_PASSWORD} <<EOF
|
||||||
|
CREATE DATABASE IF NOT EXISTS ${DB_DATABASE_NAME};
|
||||||
|
CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
|
||||||
|
ALTER USER '${DB_USERNAME}'@'%' IDENTIFIED BY '${DB_PASSWORD}';
|
||||||
|
GRANT ALL PRIVILEGES ON ${DB_DATABASE_NAME}.* TO '${DB_USERNAME}'@'%';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EOF
|
||||||
|
env:
|
||||||
|
- name: MYSQL_ROOT_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ghost-secrets
|
||||||
|
key: mysql.rootPassword
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_PORT
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: DB_DATABASE_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ghost-secrets
|
||||||
|
key: dbPassword
|
||||||
|
restartPolicy: OnFailure
|
||||||
105
ghost/versions/6/deployment.yaml
Normal file
105
ghost/versions/6/deployment.yaml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: ghost
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: web
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: ghost
|
||||||
|
image: ghost:6.72.0-alpine
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 2368
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: NODE_ENV
|
||||||
|
value: production
|
||||||
|
- name: url
|
||||||
|
value: "https://{{ .domain }}"
|
||||||
|
- name: database__client
|
||||||
|
value: mysql
|
||||||
|
- name: database__connection__host
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: database__connection__port
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: database__connection__database
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: database__connection__user
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: database__connection__password
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ghost-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: mail__transport
|
||||||
|
value: SMTP
|
||||||
|
- name: mail__options__host
|
||||||
|
value: "{{ .smtp.host }}"
|
||||||
|
- name: mail__options__port
|
||||||
|
value: "{{ .smtp.port }}"
|
||||||
|
- name: mail__options__auth__user
|
||||||
|
value: "{{ .smtp.user }}"
|
||||||
|
- name: mail__options__auth__pass
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ghost-secrets
|
||||||
|
key: smtpPassword
|
||||||
|
- name: mail__from
|
||||||
|
value: "{{ .smtp.from }}"
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
ephemeral-storage: 2Gi
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 256Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: ghost-data
|
||||||
|
mountPath: /var/lib/ghost/content
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ghost/api/admin/site/
|
||||||
|
port: 2368
|
||||||
|
initialDelaySeconds: 120
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 30
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ghost/api/admin/site/
|
||||||
|
port: 2368
|
||||||
|
initialDelaySeconds: 60
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 15
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumes:
|
||||||
|
- name: ghost-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: ghost-data
|
||||||
|
restartPolicy: Always
|
||||||
18
ghost/versions/6/ingress.yaml
Normal file
18
ghost/versions/6/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: ghost
|
||||||
|
namespace: ghost
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: {{ .domain }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: ghost
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
16
ghost/versions/6/kustomization.yaml
Normal file
16
ghost/versions/6/kustomization.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: ghost
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: ghost
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- pvc.yaml
|
||||||
23
ghost/versions/6/manifest.yaml
Normal file
23
ghost/versions/6/manifest.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
version: 6.72.0
|
||||||
|
requires:
|
||||||
|
- name: mysql
|
||||||
|
- name: smtp
|
||||||
|
defaultConfig:
|
||||||
|
namespace: ghost
|
||||||
|
domain: ghost.{{ .cloud.domain }}
|
||||||
|
storage: 2Gi
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.mysql.host }}'
|
||||||
|
port: '3306'
|
||||||
|
name: ghost
|
||||||
|
user: ghost
|
||||||
|
smtp:
|
||||||
|
host: '{{ .apps.smtp.host }}'
|
||||||
|
port: '{{ .apps.smtp.port }}'
|
||||||
|
from: '{{ .apps.smtp.from }}'
|
||||||
|
user: '{{ .apps.smtp.user }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
- key: smtpPassword
|
||||||
|
requiredSecrets:
|
||||||
|
- mysql.rootPassword
|
||||||
4
ghost/versions/6/namespace.yaml
Normal file
4
ghost/versions/6/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
11
ghost/versions/6/pvc.yaml
Normal file
11
ghost/versions/6/pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: ghost-data
|
||||||
|
namespace: ghost
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
14
ghost/versions/6/service.yaml
Normal file
14
ghost/versions/6/service.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: ghost
|
||||||
|
namespace: ghost
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 2368
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
@@ -3,4 +3,4 @@ is: gitea
|
|||||||
description: Gitea is a painless self-hosted Git service written in Go
|
description: Gitea is a painless self-hosted Git service written in Go
|
||||||
category: developer
|
category: developer
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/gitea.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/gitea.svg
|
||||||
latest: "1"
|
latest: "28"
|
||||||
|
|||||||
85
gitea/versions/28/README.md
Normal file
85
gitea/versions/28/README.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Gitea Configuration
|
||||||
|
|
||||||
|
This Gitea deployment uses a hybrid configuration approach combining environment variables with Gitea's self-managed configuration file.
|
||||||
|
|
||||||
|
## Configuration Architecture
|
||||||
|
|
||||||
|
### Environment Variables (gitea.env)
|
||||||
|
Non-secret configuration is stored in `gitea.env` and automatically loaded via kustomize's `configMapGenerator`. This includes:
|
||||||
|
- Server settings (domain, URLs, ports)
|
||||||
|
- Database connection details (except password)
|
||||||
|
- SMTP settings (except password)
|
||||||
|
- Service settings (registration, notifications)
|
||||||
|
- Repository and storage paths
|
||||||
|
|
||||||
|
### Kubernetes Secrets (gitea-secrets)
|
||||||
|
Sensitive configuration is stored in the `gitea-secrets` secret and managed by the wild-cloud deployment system:
|
||||||
|
- `adminPassword` - Gitea admin user password
|
||||||
|
- `secretKey` - Application secret key
|
||||||
|
- `jwtSecret` - JWT signing secret
|
||||||
|
- `dbPassword` - Database password
|
||||||
|
- `smtpPassword` - SMTP authentication password
|
||||||
|
|
||||||
|
Secrets are defined in `secrets.yaml` and listed in `manifest.yaml` under `defaultSecrets`. When deploying, the system automatically ensures all required secrets exist in the `gitea-secrets` secret before deployment.
|
||||||
|
|
||||||
|
### Persistent Configuration (app.ini)
|
||||||
|
Gitea manages its own `app.ini` file on persistent storage for:
|
||||||
|
- Generated security tokens
|
||||||
|
- Runtime configuration changes made via web UI
|
||||||
|
- Database migration state
|
||||||
|
- User-modified settings
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. **Startup**: Kustomize generates a ConfigMap from `gitea.env`
|
||||||
|
2. **Environment Loading**: Pod loads non-secret config from ConfigMap via `envFrom`
|
||||||
|
3. **Secret Loading**: Pod loads sensitive config from Kubernetes secrets via `env`
|
||||||
|
4. **Configuration Merge**: Gitea's environment-to-ini process merges environment variables into `app.ini`
|
||||||
|
5. **Persistence**: Gitea writes the merged configuration plus generated tokens to persistent storage
|
||||||
|
|
||||||
|
## Making Configuration Changes
|
||||||
|
|
||||||
|
### Non-Secret Settings
|
||||||
|
1. Edit `gitea.env` with your changes
|
||||||
|
2. Deploy the app via the web app, CLI, or API to apply changes
|
||||||
|
3. Pod will restart and pick up new configuration
|
||||||
|
|
||||||
|
### Secret Settings
|
||||||
|
1. Edit `secrets.yaml` with your secret values
|
||||||
|
2. Ensure the secret key is listed in `manifest.yaml` under `defaultSecrets`
|
||||||
|
3. Deploy the app via the web app, CLI, or API - this will automatically update the `gitea-secrets` secret and restart the pod
|
||||||
|
|
||||||
|
### Web UI Changes
|
||||||
|
Configuration changes made through Gitea's admin web interface are automatically persisted to the `app.ini` file on persistent storage and will survive pod restarts.
|
||||||
|
|
||||||
|
## Configuration Precedence
|
||||||
|
|
||||||
|
1. **Kubernetes Secrets** (highest priority)
|
||||||
|
2. **Environment Variables** (from gitea.env)
|
||||||
|
3. **Persistent app.ini** (lowest priority)
|
||||||
|
|
||||||
|
Environment variables override file settings, and secrets override everything.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check Current Configuration
|
||||||
|
```bash
|
||||||
|
# View environment variables
|
||||||
|
kubectl describe pod -n gitea -l app=gitea | grep -A 20 "Environment"
|
||||||
|
|
||||||
|
# View current app.ini
|
||||||
|
kubectl exec -it deployment/gitea -n gitea -- cat /data/gitea/conf/app.ini
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Not Applied
|
||||||
|
- Verify the ConfigMap was generated: `kubectl get configmap -n gitea`
|
||||||
|
- Check pod restart: `kubectl get pods -n gitea`
|
||||||
|
- Review startup logs: `kubectl logs -n gitea -l app=gitea`
|
||||||
|
|
||||||
|
|
||||||
|
## External Dependencies
|
||||||
|
|
||||||
|
- **Database**: PostgreSQL instance in `postgres` namespace
|
||||||
|
- **Storage**: Longhorn distributed storage
|
||||||
|
- **Ingress**: Traefik with Let's Encrypt certificates
|
||||||
|
- **DNS**: External-DNS with Cloudflare integration
|
||||||
51
gitea/versions/28/db-init-job.yaml
Normal file
51
gitea/versions/28/db-init-job.yaml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: gitea-db-init
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: postgres:17
|
||||||
|
command: ["/bin/bash", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOSTNAME} -U postgres <<EOF
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USERNAME}') THEN
|
||||||
|
CREATE USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
ELSE
|
||||||
|
ALTER USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
|
||||||
|
SELECT 'CREATE DATABASE ${DB_DATABASE_NAME}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_DATABASE_NAME}')\gexec
|
||||||
|
ALTER DATABASE ${DB_DATABASE_NAME} OWNER TO ${DB_USERNAME};
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE ${DB_DATABASE_NAME} TO ${DB_USERNAME};
|
||||||
|
EOF
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_ADMIN_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: postgres-secrets
|
||||||
|
key: password
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_DATABASE_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: dbPassword
|
||||||
|
restartPolicy: OnFailure
|
||||||
99
gitea/versions/28/deployment.yaml
Normal file
99
gitea/versions/28/deployment.yaml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: gitea
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: gitea
|
||||||
|
component: web
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
terminationGracePeriodSeconds: 60
|
||||||
|
containers:
|
||||||
|
- name: gitea
|
||||||
|
image: "gitea/gitea:28.2.0"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: gitea-env
|
||||||
|
env:
|
||||||
|
- name: GITEA_ADMIN_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: adminPassword
|
||||||
|
- name: GITEA__security__SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: secretKey
|
||||||
|
- name: GITEA__security__INTERNAL_TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: jwtSecret
|
||||||
|
- name: GITEA__database__PASSWD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: GITEA__mailer__PASSWD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: gitea-secrets
|
||||||
|
key: smtpPassword
|
||||||
|
ports:
|
||||||
|
- name: ssh
|
||||||
|
containerPort: 2222
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 10
|
||||||
|
initialDelaySeconds: 200
|
||||||
|
periodSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
timeoutSeconds: 1
|
||||||
|
readinessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
timeoutSeconds: 1
|
||||||
|
resources:
|
||||||
|
{}
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: [ALL]
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumeMounts:
|
||||||
|
- name: temp
|
||||||
|
mountPath: /tmp
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: temp
|
||||||
|
emptyDir: {}
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: gitea-data
|
||||||
60
gitea/versions/28/gitea.env
Normal file
60
gitea/versions/28/gitea.env
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
SSH_LISTEN_PORT=2222
|
||||||
|
SSH_PORT=22
|
||||||
|
GITEA_WORK_DIR=/data
|
||||||
|
GITEA_TEMP=/tmp/gitea
|
||||||
|
TMPDIR=/tmp/gitea
|
||||||
|
GITEA_ADMIN_USERNAME={{ .adminUser }}
|
||||||
|
GITEA_ADMIN_PASSWORD_MODE=keepUpdated
|
||||||
|
|
||||||
|
# Core app settings
|
||||||
|
GITEA____APP_NAME={{ .appName }}
|
||||||
|
GITEA____RUN_MODE=prod
|
||||||
|
GITEA____RUN_USER=git
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
GITEA__security__INSTALL_LOCK=true
|
||||||
|
GITEA__security__PASSWORD_HASH_ALGO=pbkdf2
|
||||||
|
|
||||||
|
# Database settings (except password which comes from secret)
|
||||||
|
GITEA__database__DB_TYPE=postgres
|
||||||
|
GITEA__database__HOST={{ .db.host }}:{{ .db.port }}
|
||||||
|
GITEA__database__NAME={{ .db.name }}
|
||||||
|
GITEA__database__USER={{ .db.user }}
|
||||||
|
GITEA__database__SSL_MODE=disable
|
||||||
|
GITEA__database__LOG_SQL=false
|
||||||
|
|
||||||
|
# Server settings
|
||||||
|
GITEA__server__DOMAIN={{ .domain }}
|
||||||
|
GITEA__server__HTTP_PORT=3000
|
||||||
|
GITEA__server__ROOT_URL=https://{{ .domain }}/
|
||||||
|
GITEA__server__DISABLE_SSH=false
|
||||||
|
GITEA__server__SSH_DOMAIN={{ .domain }}
|
||||||
|
GITEA__server__SSH_PORT=22
|
||||||
|
GITEA__server__SSH_LISTEN_PORT=2222
|
||||||
|
GITEA__server__LFS_START_SERVER=true
|
||||||
|
GITEA__server__OFFLINE_MODE=true
|
||||||
|
|
||||||
|
# Service settings
|
||||||
|
GITEA__service__REGISTER_EMAIL_CONFIRM=true
|
||||||
|
GITEA__service__DISABLE_REGISTRATION=false
|
||||||
|
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=false
|
||||||
|
GITEA__service__ENABLE_NOTIFY_MAIL=true
|
||||||
|
GITEA__service__ENABLE_BASIC_AUTHENTICATION=false
|
||||||
|
GITEA__service__ENABLE_REVERSE_PROXY_AUTHENTICATION=false
|
||||||
|
GITEA__service__ENABLE_CAPTCHA=false
|
||||||
|
GITEA__service__REQUIRE_SIGNIN_VIEW=false
|
||||||
|
GITEA__service__DEFAULT_KEEP_EMAIL_PRIVATE=false
|
||||||
|
GITEA__service__DEFAULT_ALLOW_CREATE_ORGANIZATION=true
|
||||||
|
GITEA__service__DEFAULT_ENABLE_TIMETRACKING=true
|
||||||
|
GITEA__service__NO_REPLY_ADDRESS=noreply.localhost
|
||||||
|
|
||||||
|
# Webhook settings
|
||||||
|
GITEA__webhook__ALLOWED_HOST_LIST=*
|
||||||
|
|
||||||
|
# Mailer settings (enabled via env vars, password from secret)
|
||||||
|
GITEA__mailer__ENABLED=true
|
||||||
|
GITEA__mailer__SMTP_ADDR={{ .smtp.host }}
|
||||||
|
GITEA__mailer__SMTP_PORT={{ .smtp.port }}
|
||||||
|
GITEA__mailer__FROM={{ .smtp.from }}
|
||||||
|
GITEA__mailer__USER={{ .smtp.user }}
|
||||||
|
|
||||||
18
gitea/versions/28/ingress.yaml
Normal file
18
gitea/versions/28/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: gitea-public
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: "{{ .domain }}"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gitea-http
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
20
gitea/versions/28/kustomization.yaml
Normal file
20
gitea/versions/28/kustomization.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: gitea
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: gitea
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- pvc.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
|
configMapGenerator:
|
||||||
|
- name: gitea-env
|
||||||
|
envs:
|
||||||
|
- gitea.env
|
||||||
29
gitea/versions/28/manifest.yaml
Normal file
29
gitea/versions/28/manifest.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
version: 28.2.0
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
- name: smtp
|
||||||
|
defaultConfig:
|
||||||
|
namespace: gitea
|
||||||
|
appName: Gitea
|
||||||
|
domain: gitea.{{ .cloud.domain }}
|
||||||
|
storage: 2Gi
|
||||||
|
adminUser: admin
|
||||||
|
adminEmail: '{{ .operator.email }}'
|
||||||
|
db:
|
||||||
|
name: gitea
|
||||||
|
user: gitea
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
smtp:
|
||||||
|
host: '{{ .apps.smtp.host }}'
|
||||||
|
port: '{{ .apps.smtp.port }}'
|
||||||
|
user: '{{ .apps.smtp.user }}'
|
||||||
|
from: '{{ .apps.smtp.from }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: adminPassword
|
||||||
|
- key: dbPassword
|
||||||
|
- key: secretKey
|
||||||
|
- key: jwtSecret
|
||||||
|
- key: smtpPassword
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
4
gitea/versions/28/namespace.yaml
Normal file
4
gitea/versions/28/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
12
gitea/versions/28/pvc.yaml
Normal file
12
gitea/versions/28/pvc.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: gitea-data
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: "{{ .storage }}"
|
||||||
28
gitea/versions/28/service.yaml
Normal file
28
gitea/versions/28/service.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: gitea-http
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: gitea-ssh
|
||||||
|
namespace: gitea
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
ports:
|
||||||
|
- name: ssh
|
||||||
|
port: 22
|
||||||
|
targetPort: 2222
|
||||||
|
protocol: TCP
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
@@ -3,4 +3,4 @@ is: immich
|
|||||||
description: Immich is a self-hosted photo and video backup solution that allows you to store, manage, and share your media files securely.
|
description: Immich is a self-hosted photo and video backup solution that allows you to store, manage, and share your media files securely.
|
||||||
category: media
|
category: media
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/immich.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/immich.svg
|
||||||
latest: "1"
|
latest: "3"
|
||||||
|
|||||||
41
immich/versions/3/README.md
Normal file
41
immich/versions/3/README.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Immich
|
||||||
|
|
||||||
|
Immich is a self-hosted photo and video backup solution that allows you to store, manage, and share your media files securely. It provides a mobile-first experience similar to Google Photos.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing metadata and search indexes
|
||||||
|
- **Redis** - Used for caching and background job queuing
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
Immich runs two services:
|
||||||
|
|
||||||
|
- **Server** - Main API and web server
|
||||||
|
- **Machine Learning** - Handles facial recognition and smart search
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings configured through your instance's `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Immich will be accessible (default: `immich.{your-cloud-domain}`)
|
||||||
|
- **storage** - Persistent volume for photos and videos (default: `250Gi`)
|
||||||
|
- **cacheStorage** - Persistent volume for ML cache (default: `10Gi`)
|
||||||
|
- **timezone** - Server timezone (default: `UTC`)
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
After deployment, Immich will be available at:
|
||||||
|
- `https://immich.{your-cloud-domain}`
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add immich
|
||||||
|
wild app deploy immich
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create your account through the web interface
|
||||||
|
|
||||||
|
3. Download the Immich mobile app and connect it to your server for automatic photo backup
|
||||||
68
immich/versions/3/db-init-job.yaml
Normal file
68
immich/versions/3/db-init-job.yaml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: immich-db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: postgres:17
|
||||||
|
command: ["/bin/bash", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOSTNAME} -U postgres <<EOF
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USERNAME}') THEN
|
||||||
|
CREATE USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
ELSE
|
||||||
|
ALTER USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
|
||||||
|
SELECT 'CREATE DATABASE ${DB_DATABASE_NAME}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_DATABASE_NAME}')\gexec
|
||||||
|
ALTER DATABASE ${DB_DATABASE_NAME} OWNER TO ${DB_USERNAME};
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE ${DB_DATABASE_NAME} TO ${DB_USERNAME};
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Connect to the immich database and enable required extensions
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOSTNAME} -U postgres -d ${DB_DATABASE_NAME} <<EOF
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
-- Create vector extension if it doesn't exist
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'vector') THEN
|
||||||
|
CREATE EXTENSION vector;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Create cube extension if it doesn't exist
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'cube') THEN
|
||||||
|
CREATE EXTENSION cube;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Create earthdistance extension if it doesn't exist (depends on cube)
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'earthdistance') THEN
|
||||||
|
CREATE EXTENSION earthdistance;
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
EOF
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_ADMIN_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: postgres.password
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_DATABASE_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: dbPassword
|
||||||
|
restartPolicy: OnFailure
|
||||||
45
immich/versions/3/deployment-machine-learning.yaml
Normal file
45
immich/versions/3/deployment-machine-learning.yaml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: immich-machine-learning
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: immich-machine-learning
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: immich-machine-learning
|
||||||
|
component: machine-learning
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- image: "ghcr.io/immich-app/immich-machine-learning:v3.3.5"
|
||||||
|
name: immich-machine-learning
|
||||||
|
ports:
|
||||||
|
- containerPort: 3003
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: TZ
|
||||||
|
value: "UTC"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: [ALL]
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /cache
|
||||||
|
name: immich-cache
|
||||||
|
readOnly: false
|
||||||
|
volumes:
|
||||||
|
- name: immich-cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: immich-cache-pvc
|
||||||
68
immich/versions/3/deployment-microservices.yaml
Normal file
68
immich/versions/3/deployment-microservices.yaml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: immich-microservices
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: immich-microservices
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: immich-microservices
|
||||||
|
component: microservices
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- image: "ghcr.io/immich-app/immich-server:v3.3.5"
|
||||||
|
name: immich-microservices
|
||||||
|
env:
|
||||||
|
- name: REDIS_HOSTNAME
|
||||||
|
value: "{{ .redis.host }}"
|
||||||
|
- name: REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: redis.password
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: TZ
|
||||||
|
value: "UTC"
|
||||||
|
- name: IMMICH_WORKERS_EXCLUDE
|
||||||
|
value: api
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: [ALL]
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /usr/src/app/upload
|
||||||
|
name: immich-storage
|
||||||
|
readOnly: false
|
||||||
|
volumes:
|
||||||
|
- name: immich-storage
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: immich-pvc
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: immich
|
||||||
|
component: server
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
63
immich/versions/3/deployment-server.yaml
Normal file
63
immich/versions/3/deployment-server.yaml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: immich-server
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: immich-server
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: immich-server
|
||||||
|
component: server
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- image: "ghcr.io/immich-app/immich-server:v3.3.5"
|
||||||
|
name: immich-server
|
||||||
|
ports:
|
||||||
|
- containerPort: 2283
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: REDIS_HOSTNAME
|
||||||
|
value: "{{ .redis.host }}"
|
||||||
|
- name: REDIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: redis.password
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: immich-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: TZ
|
||||||
|
value: "UTC"
|
||||||
|
- name: IMMICH_WORKERS_EXCLUDE
|
||||||
|
value: microservices
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: [ALL]
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /usr/src/app/upload
|
||||||
|
name: immich-storage
|
||||||
|
readOnly: false
|
||||||
|
volumes:
|
||||||
|
- name: immich-storage
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: immich-pvc
|
||||||
18
immich/versions/3/ingress.yaml
Normal file
18
immich/versions/3/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: immich-public
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: "{{ .domain }}"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: immich-server
|
||||||
|
port:
|
||||||
|
number: 3001
|
||||||
18
immich/versions/3/kustomization.yaml
Normal file
18
immich/versions/3/kustomization.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: immich
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: immich
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- deployment-server.yaml
|
||||||
|
- deployment-machine-learning.yaml
|
||||||
|
- deployment-microservices.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- namespace.yaml
|
||||||
|
- pvc.yaml
|
||||||
|
- service.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
20
immich/versions/3/manifest.yaml
Normal file
20
immich/versions/3/manifest.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
version: 3.3.5
|
||||||
|
requires:
|
||||||
|
- name: redis
|
||||||
|
- name: postgres
|
||||||
|
defaultConfig:
|
||||||
|
namespace: immich
|
||||||
|
storage: 5Gi
|
||||||
|
cacheStorage: 5Gi
|
||||||
|
domain: immich.{{ .cloud.domain }}
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
name: immich
|
||||||
|
user: immich
|
||||||
|
redis:
|
||||||
|
host: '{{ .apps.redis.host }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
requiredSecrets:
|
||||||
|
- redis.password
|
||||||
|
- postgres.password
|
||||||
4
immich/versions/3/namespace.yaml
Normal file
4
immich/versions/3/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
24
immich/versions/3/pvc.yaml
Normal file
24
immich/versions/3/pvc.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: immich-pvc
|
||||||
|
spec:
|
||||||
|
storageClassName: longhorn
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: immich-cache-pvc
|
||||||
|
spec:
|
||||||
|
storageClassName: longhorn
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .cacheStorage }}
|
||||||
33
immich/versions/3/service.yaml
Normal file
33
immich/versions/3/service.yaml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: immich-server
|
||||||
|
namespace: immich
|
||||||
|
labels:
|
||||||
|
app: immich-server
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 3001
|
||||||
|
targetPort: 2283
|
||||||
|
selector:
|
||||||
|
app: immich
|
||||||
|
component: server
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: immich-machine-learning
|
||||||
|
namespace: immich
|
||||||
|
labels:
|
||||||
|
app: immich-machine-learning
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 3003
|
||||||
|
selector:
|
||||||
|
app: immich
|
||||||
|
component: machine-learning
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
@@ -3,4 +3,4 @@ is: listmonk
|
|||||||
description: Listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary.
|
description: Listmonk is a standalone, self-hosted, newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary.
|
||||||
category: communication
|
category: communication
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/listmonk.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/listmonk.svg
|
||||||
latest: "5"
|
latest: "6"
|
||||||
|
|||||||
31
listmonk/versions/6/README.md
Normal file
31
listmonk/versions/6/README.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Listmonk
|
||||||
|
|
||||||
|
Listmonk is a standalone, self-hosted newsletter and mailing list manager. It is fast, feature-rich, and packed into a single binary.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing subscribers and campaigns
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings configured through your instance's `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Listmonk will be accessible (default: `listmonk.{your-cloud-domain}`)
|
||||||
|
- **storage** - Persistent volume size (default: `1Gi`)
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
After deployment, Listmonk will be available at:
|
||||||
|
- `https://listmonk.{your-cloud-domain}`
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add listmonk
|
||||||
|
wild app deploy listmonk
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in to the admin interface and configure your SMTP settings for sending emails
|
||||||
|
|
||||||
|
3. Create your first mailing list and start adding subscribers
|
||||||
66
listmonk/versions/6/db-init-job.yaml
Normal file
66
listmonk/versions/6/db-init-job.yaml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: listmonk-db-init
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: postgres-init
|
||||||
|
image: postgres:15
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: PGUSER
|
||||||
|
value: postgres
|
||||||
|
- name: PGPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: listmonk-secrets
|
||||||
|
key: postgres.password
|
||||||
|
- name: DB_NAME
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: DB_USER
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: listmonk-secrets
|
||||||
|
key: dbPassword
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
echo "Waiting for PostgreSQL to be ready..."
|
||||||
|
until pg_isready; do
|
||||||
|
echo "PostgreSQL is not ready - sleeping"
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
echo "PostgreSQL is ready"
|
||||||
|
|
||||||
|
echo "Creating database and user for Listmonk..."
|
||||||
|
psql -c "CREATE DATABASE ${DB_NAME};" || echo "Database ${DB_NAME} already exists"
|
||||||
|
psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" || echo "User ${DB_USER} already exists"
|
||||||
|
psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';"
|
||||||
|
psql -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};"
|
||||||
|
psql -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};"
|
||||||
|
echo "Database initialization complete"
|
||||||
88
listmonk/versions/6/deployment.yaml
Normal file
88
listmonk/versions/6/deployment.yaml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: listmonk
|
||||||
|
namespace: listmonk
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: web
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: listmonk
|
||||||
|
image: listmonk/listmonk:v6.1.0
|
||||||
|
command: ["/bin/sh"]
|
||||||
|
args: ["-c", "./listmonk --install --idempotent --yes && ./listmonk --upgrade --yes && ./listmonk"]
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 9000
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: LISTMONK_app__address
|
||||||
|
value: "0.0.0.0:9000"
|
||||||
|
- name: LISTMONK_app__root_url
|
||||||
|
value: "https://{{ .domain }}"
|
||||||
|
- name: LISTMONK_db__host
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: LISTMONK_db__port
|
||||||
|
value: "{{ .db.port }}"
|
||||||
|
- name: LISTMONK_db__user
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: LISTMONK_db__database
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: LISTMONK_db__ssl_mode
|
||||||
|
value: disable
|
||||||
|
- name: LISTMONK_db__password
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: listmonk-secrets
|
||||||
|
key: dbPassword
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
ephemeral-storage: 1Gi
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 128Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: listmonk-data
|
||||||
|
mountPath: /listmonk/data
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 9000
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 9000
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
|
periodSeconds: 5
|
||||||
|
successThreshold: 1
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumes:
|
||||||
|
- name: listmonk-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: listmonk-data
|
||||||
|
restartPolicy: Always
|
||||||
18
listmonk/versions/6/ingress.yaml
Normal file
18
listmonk/versions/6/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: listmonk
|
||||||
|
namespace: listmonk
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: {{ .domain }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: listmonk
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
16
listmonk/versions/6/kustomization.yaml
Normal file
16
listmonk/versions/6/kustomization.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: listmonk
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: listmonk
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- pvc.yaml
|
||||||
19
listmonk/versions/6/manifest.yaml
Normal file
19
listmonk/versions/6/manifest.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
version: 6.1.0
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
defaultConfig:
|
||||||
|
namespace: listmonk
|
||||||
|
domain: listmonk.{{ .cloud.domain }}
|
||||||
|
storage: 1Gi
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
name: listmonk
|
||||||
|
user: listmonk
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
- key: dbUrl
|
||||||
|
default: postgres://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host
|
||||||
|
}}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
4
listmonk/versions/6/namespace.yaml
Normal file
4
listmonk/versions/6/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
11
listmonk/versions/6/pvc.yaml
Normal file
11
listmonk/versions/6/pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: listmonk-data
|
||||||
|
namespace: listmonk
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
14
listmonk/versions/6/service.yaml
Normal file
14
listmonk/versions/6/service.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: listmonk
|
||||||
|
namespace: listmonk
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
@@ -4950,7 +4950,7 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: longhorn-manager
|
- name: longhorn-manager
|
||||||
image: longhornio/longhorn-manager:v1.8.1
|
image: longhornio/longhorn-manager:v1.13.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
@@ -4963,13 +4963,13 @@ spec:
|
|||||||
- --instance-manager-image
|
- --instance-manager-image
|
||||||
- "longhornio/longhorn-instance-manager:v1.8.1"
|
- "longhornio/longhorn-instance-manager:v1.8.1"
|
||||||
- --share-manager-image
|
- --share-manager-image
|
||||||
- "longhornio/longhorn-share-manager:v1.8.1"
|
- "longhornio/longhorn-share-manager:v1.13.0"
|
||||||
- --backing-image-manager-image
|
- --backing-image-manager-image
|
||||||
- "longhornio/backing-image-manager:v1.8.1"
|
- "longhornio/backing-image-manager:v1.8.1"
|
||||||
- --support-bundle-manager-image
|
- --support-bundle-manager-image
|
||||||
- "longhornio/support-bundle-kit:v0.0.52"
|
- "longhornio/support-bundle-kit:v0.0.52"
|
||||||
- --manager-image
|
- --manager-image
|
||||||
- "longhornio/longhorn-manager:v1.8.1"
|
- "longhornio/longhorn-manager:v1.13.0"
|
||||||
- --service-account
|
- --service-account
|
||||||
- longhorn-service-account
|
- longhorn-service-account
|
||||||
- --upgrade-version-check
|
- --upgrade-version-check
|
||||||
@@ -5023,7 +5023,7 @@ spec:
|
|||||||
fieldPath: spec.nodeName
|
fieldPath: spec.nodeName
|
||||||
- name: pre-pull-share-manager-image
|
- name: pre-pull-share-manager-image
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
image: longhornio/longhorn-share-manager:v1.8.1
|
image: longhornio/longhorn-share-manager:v1.13.0
|
||||||
command: ["sh", "-c", "echo share-manager image pulled && sleep infinity"]
|
command: ["sh", "-c", "echo share-manager image pulled && sleep infinity"]
|
||||||
volumes:
|
volumes:
|
||||||
- name: boot
|
- name: boot
|
||||||
@@ -5076,18 +5076,18 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: wait-longhorn-manager
|
- name: wait-longhorn-manager
|
||||||
image: longhornio/longhorn-manager:v1.8.1
|
image: longhornio/longhorn-manager:v1.13.0
|
||||||
command: ['sh', '-c', 'while [ $(curl -m 1 -s -o /dev/null -w "%{http_code}" http://longhorn-backend:9500/v1) != "200" ]; do echo waiting; sleep 2; done']
|
command: ['sh', '-c', 'while [ $(curl -m 1 -s -o /dev/null -w "%{http_code}" http://longhorn-backend:9500/v1) != "200" ]; do echo waiting; sleep 2; done']
|
||||||
containers:
|
containers:
|
||||||
- name: longhorn-driver-deployer
|
- name: longhorn-driver-deployer
|
||||||
image: longhornio/longhorn-manager:v1.8.1
|
image: longhornio/longhorn-manager:v1.13.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- longhorn-manager
|
- longhorn-manager
|
||||||
- -d
|
- -d
|
||||||
- deploy-driver
|
- deploy-driver
|
||||||
- --manager-image
|
- --manager-image
|
||||||
- "longhornio/longhorn-manager:v1.8.1"
|
- "longhornio/longhorn-manager:v1.13.0"
|
||||||
- --manager-url
|
- --manager-url
|
||||||
- http://longhorn-backend:9500/v1
|
- http://longhorn-backend:9500/v1
|
||||||
env:
|
env:
|
||||||
@@ -5159,7 +5159,7 @@ spec:
|
|||||||
topologyKey: kubernetes.io/hostname
|
topologyKey: kubernetes.io/hostname
|
||||||
containers:
|
containers:
|
||||||
- name: longhorn-ui
|
- name: longhorn-ui
|
||||||
image: longhornio/longhorn-ui:v1.8.1
|
image: longhornio/longhorn-ui:v1.13.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name : nginx-cache
|
- name : nginx-cache
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v1.8.1-5
|
version: v1.13.0
|
||||||
deploymentName: longhorn-ui
|
deploymentName: longhorn-ui
|
||||||
requires:
|
requires:
|
||||||
- name: nfs
|
- name: nfs
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ is: mattermost
|
|||||||
description: Mattermost is a self-hosted, open-source team messaging platform offering secure channels, file sharing, and integrations as a Slack alternative.
|
description: Mattermost is a self-hosted, open-source team messaging platform offering secure channels, file sharing, and integrations as a Slack alternative.
|
||||||
category: communication
|
category: communication
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mattermost.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mattermost.svg
|
||||||
latest: "10"
|
latest: "12"
|
||||||
|
|||||||
33
mattermost/versions/12/README.md
Normal file
33
mattermost/versions/12/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Mattermost
|
||||||
|
|
||||||
|
Mattermost is an open-source team messaging platform, a self-hosted alternative to Slack.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing messages and team data
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings in `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where Mattermost will be accessible
|
||||||
|
- **storage** - Persistent volume size (default: `2Gi`)
|
||||||
|
- **db.name** - Database name (default: `mattermost`)
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add mattermost
|
||||||
|
wild app deploy mattermost
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Visit the app URL — on first load you will be prompted to create an administrator account (email + password).
|
||||||
|
|
||||||
|
3. After creating the admin account, complete the onboarding wizard to set up your first team.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The setup wizard only runs on first launch
|
||||||
|
- Email invitations require SMTP to be configured in **System Console → Environment → SMTP**
|
||||||
|
- Push notifications for mobile apps require a push proxy (or Mattermost Cloud push notification service)
|
||||||
59
mattermost/versions/12/db-init-job.yaml
Normal file
59
mattermost/versions/12/db-init-job.yaml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: mattermost-db-init
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: postgres-init
|
||||||
|
image: postgres:15
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: {{ .db.host }}
|
||||||
|
- name: PGUSER
|
||||||
|
value: postgres
|
||||||
|
- name: PGPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mattermost-secrets
|
||||||
|
key: postgres.password
|
||||||
|
- name: DB_NAME
|
||||||
|
value: {{ .db.name }}
|
||||||
|
- name: DB_USER
|
||||||
|
value: {{ .db.user }}
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mattermost-secrets
|
||||||
|
key: dbPassword
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
until pg_isready; do sleep 2; done
|
||||||
|
psql -c "CREATE DATABASE ${DB_NAME};" || echo "Database already exists"
|
||||||
|
psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" || echo "User already exists"
|
||||||
|
psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';"
|
||||||
|
psql -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};"
|
||||||
|
psql -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};"
|
||||||
|
echo "Done"
|
||||||
93
mattermost/versions/12/deployment.yaml
Normal file
93
mattermost/versions/12/deployment.yaml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mattermost
|
||||||
|
namespace: mattermost
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: web
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 2000
|
||||||
|
runAsGroup: 2000
|
||||||
|
fsGroup: 2000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: mattermost
|
||||||
|
image: mattermost/mattermost-team-edition:12.0.1
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8065
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: MM_SERVICESETTINGS_SITEURL
|
||||||
|
value: https://{{ .domain }}
|
||||||
|
- name: MM_SQLSETTINGS_DRIVERNAME
|
||||||
|
value: postgres
|
||||||
|
- name: MM_SQLSETTINGS_DATASOURCE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mattermost-secrets
|
||||||
|
key: dbUrl
|
||||||
|
- name: MM_FILESETTINGS_DIRECTORY
|
||||||
|
value: /mattermost/data/
|
||||||
|
- name: MM_PLUGINSETTINGS_PLUGINDIRECTORY
|
||||||
|
value: /mattermost/plugins
|
||||||
|
- name: MM_CLIENTPLUGINSSETTINGS_PLUGINDIRECTORY
|
||||||
|
value: /mattermost/client/plugins
|
||||||
|
- name: MM_LOGSETTINGS_CONSOLELEVEL
|
||||||
|
value: INFO
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
ephemeral-storage: 1Gi
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
ephemeral-storage: 50Mi
|
||||||
|
memory: 256Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: mattermost-data
|
||||||
|
mountPath: /mattermost/data
|
||||||
|
- name: mattermost-plugins
|
||||||
|
mountPath: /mattermost/plugins
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v4/system/ping
|
||||||
|
port: 8065
|
||||||
|
initialDelaySeconds: 60
|
||||||
|
timeoutSeconds: 5
|
||||||
|
periodSeconds: 15
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v4/system/ping
|
||||||
|
port: 8065
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
timeoutSeconds: 3
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
volumes:
|
||||||
|
- name: mattermost-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mattermost-data
|
||||||
|
- name: mattermost-plugins
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mattermost-plugins
|
||||||
|
restartPolicy: Always
|
||||||
18
mattermost/versions/12/ingress.yaml
Normal file
18
mattermost/versions/12/ingress.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: mattermost
|
||||||
|
namespace: mattermost
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: {{ .domain }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: mattermost
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
16
mattermost/versions/12/kustomization.yaml
Normal file
16
mattermost/versions/12/kustomization.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: mattermost
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: mattermost
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
- pvc.yaml
|
||||||
19
mattermost/versions/12/manifest.yaml
Normal file
19
mattermost/versions/12/manifest.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
version: 12.0.1
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
defaultConfig:
|
||||||
|
namespace: mattermost
|
||||||
|
domain: mattermost.{{ .cloud.domain }}
|
||||||
|
storage: 2Gi
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
name: mattermost
|
||||||
|
user: mattermost
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
- key: dbUrl
|
||||||
|
default: postgres://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host
|
||||||
|
}}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable&connect_timeout=10
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
4
mattermost/versions/12/namespace.yaml
Normal file
4
mattermost/versions/12/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: mattermost
|
||||||
23
mattermost/versions/12/pvc.yaml
Normal file
23
mattermost/versions/12/pvc.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mattermost-data
|
||||||
|
namespace: mattermost
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mattermost-plugins
|
||||||
|
namespace: mattermost
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
13
mattermost/versions/12/service.yaml
Normal file
13
mattermost/versions/12/service.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mattermost
|
||||||
|
namespace: mattermost
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: web
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 8065
|
||||||
|
protocol: TCP
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v0.15.0-1
|
version: v0.16.1
|
||||||
deploymentName: controller
|
deploymentName: controller
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
namespace: metallb-system
|
namespace: metallb-system
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: 9.1.0-4
|
version: 9.7.4
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
namespace: mysql
|
namespace: mysql
|
||||||
host: mysql.mysql.svc.cluster.local
|
host: mysql.mysql.svc.cluster.local
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: mysql
|
- name: mysql
|
||||||
image: mysql:9.1.0
|
image: mysql:9.7.4
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: worker
|
- name: worker
|
||||||
image: registry.k8s.io/nfd/node-feature-discovery:v0.17.3
|
image: registry.k8s.io/nfd/node-feature-discovery:v0.20.1
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
capabilities:
|
capabilities:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v0.17.3
|
version: v0.20.1
|
||||||
deploymentName: node-feature-discovery-master
|
deploymentName: node-feature-discovery-master
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
namespace: node-feature-discovery
|
namespace: node-feature-discovery
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: master
|
- name: master
|
||||||
image: registry.k8s.io/nfd/node-feature-discovery:v0.17.3
|
image: registry.k8s.io/nfd/node-feature-discovery:v0.20.1
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
capabilities:
|
capabilities:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ spec:
|
|||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- image: nvcr.io/nvidia/k8s-device-plugin:v0.17.1
|
- image: nvcr.io/nvidia/k8s-device-plugin:v0.20.1
|
||||||
name: nvidia-device-plugin-ctr
|
name: nvidia-device-plugin-ctr
|
||||||
env:
|
env:
|
||||||
- name: MPS_ROOT
|
- name: MPS_ROOT
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: v0.17.1-1
|
version: v0.20.1
|
||||||
deploymentName: nvidia-device-plugin-daemonset
|
deploymentName: nvidia-device-plugin-daemonset
|
||||||
requires:
|
requires:
|
||||||
- name: node-feature-discovery
|
- name: node-feature-discovery
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ is: openproject
|
|||||||
description: OpenProject is an open-source project management software that provides comprehensive features for project planning, tracking, and collaboration.
|
description: OpenProject is an open-source project management software that provides comprehensive features for project planning, tracking, and collaboration.
|
||||||
category: productivity
|
category: productivity
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/openproject.svg
|
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/openproject.svg
|
||||||
latest: "16"
|
latest: "17"
|
||||||
|
|||||||
34
openproject/versions/17/README.md
Normal file
34
openproject/versions/17/README.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# OpenProject
|
||||||
|
|
||||||
|
OpenProject is an open-source project management software that provides comprehensive features for project planning, tracking, and collaboration.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **PostgreSQL** - Database for storing project data
|
||||||
|
- **Memcached** - Caching layer for improved performance
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key settings configured through your instance's `config.yaml`:
|
||||||
|
|
||||||
|
- **domain** - Where OpenProject will be accessible (default: `openproject.{your-cloud-domain}`)
|
||||||
|
- **adminUserEmail** - Admin account email (defaults to your operator email)
|
||||||
|
- **seedLocale** - Default language (default: `en`)
|
||||||
|
- **storage** - Persistent volume size (default: `5Gi`)
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
After deployment, OpenProject will be available at:
|
||||||
|
- `https://openproject.{your-cloud-domain}`
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
1. Add and deploy the app:
|
||||||
|
```bash
|
||||||
|
wild app add openproject
|
||||||
|
wild app deploy openproject
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Log in with the admin credentials (password reset will be required on first login)
|
||||||
|
|
||||||
|
3. Create your first project and invite team members
|
||||||
24
openproject/versions/17/configmap_core.yaml
Normal file
24
openproject/versions/17/configmap_core.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
# Source: openproject/templates/secret_core.yaml
|
||||||
|
apiVersion: "v1"
|
||||||
|
kind: "ConfigMap"
|
||||||
|
metadata:
|
||||||
|
name: "openproject-core"
|
||||||
|
data:
|
||||||
|
DATABASE_HOST: "{{ .db.host }}"
|
||||||
|
DATABASE_PORT: "{{ .db.port }}"
|
||||||
|
DATABASE_NAME: "{{ .db.name }}"
|
||||||
|
DATABASE_USERNAME: "{{ .db.user }}"
|
||||||
|
DATABASE_URL: "postgresql://{{ .db.user }}@{{ .db.host }}:{{ .db.port }}/{{ .db.name }}"
|
||||||
|
OPENPROJECT_SEED_ADMIN_USER_PASSWORD_RESET: "true"
|
||||||
|
OPENPROJECT_SEED_ADMIN_USER_NAME: "{{ .adminUserName }}"
|
||||||
|
OPENPROJECT_SEED_ADMIN_USER_MAIL: "{{ .adminUserEmail }}"
|
||||||
|
OPENPROJECT_HTTPS: "true"
|
||||||
|
OPENPROJECT_SEED_LOCALE: "en"
|
||||||
|
OPENPROJECT_HOST__NAME: "{{ .domain }}"
|
||||||
|
OPENPROJECT_HSTS: "true"
|
||||||
|
OPENPROJECT_RAILS__CACHE__STORE: "memcache"
|
||||||
|
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: ""
|
||||||
|
POSTGRES_STATEMENT_TIMEOUT: "120s"
|
||||||
|
WEB_CONCURRENCY: "1"
|
||||||
|
...
|
||||||
9
openproject/versions/17/configmap_memcached.yaml
Normal file
9
openproject/versions/17/configmap_memcached.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
# Source: openproject/templates/secret_memcached.yaml
|
||||||
|
apiVersion: "v1"
|
||||||
|
kind: "ConfigMap"
|
||||||
|
metadata:
|
||||||
|
name: "openproject-memcached"
|
||||||
|
data:
|
||||||
|
OPENPROJECT_CACHE__MEMCACHE__SERVER: "{{ .memcached.host }}:{{ .memcached.port }}"
|
||||||
|
...
|
||||||
51
openproject/versions/17/db-init-job.yaml
Normal file
51
openproject/versions/17/db-init-job.yaml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: openproject-db-init
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: db-init
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: db-init
|
||||||
|
image: postgres:17
|
||||||
|
command: ["/bin/bash", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOSTNAME} -U postgres <<EOF
|
||||||
|
DO \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USERNAME}') THEN
|
||||||
|
CREATE USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
ELSE
|
||||||
|
ALTER USER ${DB_USERNAME} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
\$\$;
|
||||||
|
|
||||||
|
SELECT 'CREATE DATABASE ${DB_DATABASE_NAME}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_DATABASE_NAME}')\gexec
|
||||||
|
ALTER DATABASE ${DB_DATABASE_NAME} OWNER TO ${DB_USERNAME};
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE ${DB_DATABASE_NAME} TO ${DB_USERNAME};
|
||||||
|
EOF
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_ADMIN_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: postgres-secrets
|
||||||
|
key: password
|
||||||
|
- name: DB_HOSTNAME
|
||||||
|
value: "{{ .db.host }}"
|
||||||
|
- name: DB_DATABASE_NAME
|
||||||
|
value: "{{ .db.name }}"
|
||||||
|
- name: DB_USERNAME
|
||||||
|
value: "{{ .db.user }}"
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: openproject-secrets
|
||||||
|
key: dbPassword
|
||||||
|
restartPolicy: OnFailure
|
||||||
20
openproject/versions/17/ingress.yaml
Normal file
20
openproject/versions/17/ingress.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
# Source: openproject/templates/ingress.yaml
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: openproject
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: "{{ .domain }}"
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: openproject
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
|
...
|
||||||
21
openproject/versions/17/kustomization.yaml
Normal file
21
openproject/versions/17/kustomization.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: openproject
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: openproject
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- serviceaccount.yaml
|
||||||
|
- configmap_core.yaml
|
||||||
|
- configmap_memcached.yaml
|
||||||
|
- persistentvolumeclaim.yaml
|
||||||
|
- service.yaml
|
||||||
|
- db-init-job.yaml
|
||||||
|
- web-deployment.yaml
|
||||||
|
- worker-deployment.yaml
|
||||||
|
- seeder-job.yaml
|
||||||
|
- ingress.yaml
|
||||||
23
openproject/versions/17/manifest.yaml
Normal file
23
openproject/versions/17/manifest.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
version: 17.9.3
|
||||||
|
requires:
|
||||||
|
- name: postgres
|
||||||
|
- name: memcached
|
||||||
|
defaultConfig:
|
||||||
|
namespace: openproject
|
||||||
|
storage: 2Gi
|
||||||
|
adminUserName: OpenProject Admin
|
||||||
|
adminUserEmail: '{{ .operator.email }}'
|
||||||
|
domain: openproject.{{ .cloud.domain }}
|
||||||
|
db:
|
||||||
|
host: '{{ .apps.postgres.host }}'
|
||||||
|
port: '{{ .apps.postgres.port }}'
|
||||||
|
name: openproject
|
||||||
|
user: openproject
|
||||||
|
memcached:
|
||||||
|
host: '{{ .apps.memcached.host }}'
|
||||||
|
port: '{{ .apps.memcached.port }}'
|
||||||
|
defaultSecrets:
|
||||||
|
- key: dbPassword
|
||||||
|
- key: adminPassword
|
||||||
|
requiredSecrets:
|
||||||
|
- postgres.password
|
||||||
4
openproject/versions/17/namespace.yaml
Normal file
4
openproject/versions/17/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ .namespace }}"
|
||||||
12
openproject/versions/17/persistentvolumeclaim.yaml
Normal file
12
openproject/versions/17/persistentvolumeclaim.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
# Source: openproject/templates/persistentvolumeclaim.yaml
|
||||||
|
apiVersion: "v1"
|
||||||
|
kind: "PersistentVolumeClaim"
|
||||||
|
metadata:
|
||||||
|
name: openproject
|
||||||
|
spec:
|
||||||
|
accessModes: [ReadWriteMany]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: "{{ .storage }}"
|
||||||
|
...
|
||||||
138
openproject/versions/17/seeder-job.yaml
Normal file
138
openproject/versions/17/seeder-job.yaml
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
---
|
||||||
|
# Source: openproject/templates/seeder-job.yaml
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: openproject-seeder-1
|
||||||
|
labels:
|
||||||
|
component: seeder
|
||||||
|
spec:
|
||||||
|
ttlSecondsAfterFinished: 86400
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: seeder
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
# we can't use emptyDir due to the sticky bit issue
|
||||||
|
# see: https://github.com/kubernetes/kubernetes/issues/110835
|
||||||
|
ephemeral:
|
||||||
|
volumeClaimTemplate:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 2Gi
|
||||||
|
- name: app-tmp
|
||||||
|
# we can't use emptyDir due to the sticky bit / world writable issue
|
||||||
|
# see: https://github.com/kubernetes/kubernetes/issues/110835
|
||||||
|
ephemeral:
|
||||||
|
volumeClaimTemplate:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 2Gi
|
||||||
|
- name: "data"
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: openproject
|
||||||
|
initContainers:
|
||||||
|
- name: check-db-ready
|
||||||
|
image: "postgres:17"
|
||||||
|
imagePullPolicy: Always
|
||||||
|
command: [
|
||||||
|
'sh',
|
||||||
|
'-c',
|
||||||
|
'until pg_isready -h $DATABASE_HOST -p $DATABASE_PORT -U openproject; do echo "waiting for database $DATABASE_HOST:$DATABASE_PORT"; sleep 2; done;'
|
||||||
|
]
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: openproject-core
|
||||||
|
- configMapRef:
|
||||||
|
name: openproject-memcached
|
||||||
|
env:
|
||||||
|
- name: OPENPROJECT_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: openproject-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: OPENPROJECT_SEED_ADMIN_USER_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: openproject-secrets
|
||||||
|
key: adminPassword
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 200Mi
|
||||||
|
requests:
|
||||||
|
memory: 200Mi
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp
|
||||||
|
name: tmp
|
||||||
|
- mountPath: /app/tmp
|
||||||
|
name: app-tmp
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsGroup: 1000
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: seeder
|
||||||
|
image: "openproject/openproject:17.9.3-slim"
|
||||||
|
imagePullPolicy: Always
|
||||||
|
args:
|
||||||
|
- bash
|
||||||
|
- /app/docker/prod/seeder
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: openproject-core
|
||||||
|
- configMapRef:
|
||||||
|
name: openproject-memcached
|
||||||
|
env:
|
||||||
|
- name: OPENPROJECT_DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: openproject-secrets
|
||||||
|
key: dbPassword
|
||||||
|
- name: OPENPROJECT_SEED_ADMIN_USER_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: openproject-secrets
|
||||||
|
key: adminPassword
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
memory: 256Mi
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp
|
||||||
|
name: tmp
|
||||||
|
- mountPath: /app/tmp
|
||||||
|
name: app-tmp
|
||||||
|
- name: "data"
|
||||||
|
mountPath: "/var/openproject/assets"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsGroup: 1000
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
restartPolicy: OnFailure
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user