Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b0c56f720 |
@@ -1,75 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: communitarian-api
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
component: api
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
component: api
|
|
||||||
spec:
|
|
||||||
securityContext:
|
|
||||||
runAsNonRoot: true
|
|
||||||
runAsUser: 1000
|
|
||||||
runAsGroup: 1000
|
|
||||||
fsGroup: 1000
|
|
||||||
seccompProfile:
|
|
||||||
type: RuntimeDefault
|
|
||||||
initContainers:
|
|
||||||
- name: fix-permissions
|
|
||||||
image: busybox:1.36
|
|
||||||
command: ['sh', '-c']
|
|
||||||
args:
|
|
||||||
- |
|
|
||||||
mkdir -p /app/api/data/citizens /app/api/data/communities /app/api/data/content /app/api/data/memberships /app/api/data/reactions
|
|
||||||
chmod -R 777 /app/api/data
|
|
||||||
echo "Permissions fixed"
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /app/api/data
|
|
||||||
securityContext:
|
|
||||||
runAsUser: 0
|
|
||||||
runAsNonRoot: false
|
|
||||||
containers:
|
|
||||||
- name: communitarian-api
|
|
||||||
image: "{{ .apiImage }}"
|
|
||||||
ports:
|
|
||||||
- containerPort: {{ .apiPort }}
|
|
||||||
name: http
|
|
||||||
env:
|
|
||||||
- name: TZ
|
|
||||||
value: "{{ .timezone }}"
|
|
||||||
- name: API_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: communitarian-secrets
|
|
||||||
key: apiKey
|
|
||||||
- name: JWT_SECRET
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: communitarian-secrets
|
|
||||||
key: jwtSecret
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /app/api/data
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "1Gi"
|
|
||||||
cpu: "500m"
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop: [ALL]
|
|
||||||
readOnlyRootFilesystem: false
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: communitarian-data
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: communitarian-app
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
component: app
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
component: app
|
|
||||||
spec:
|
|
||||||
securityContext:
|
|
||||||
runAsNonRoot: true
|
|
||||||
runAsUser: 1000
|
|
||||||
runAsGroup: 1000
|
|
||||||
fsGroup: 1000
|
|
||||||
seccompProfile:
|
|
||||||
type: RuntimeDefault
|
|
||||||
containers:
|
|
||||||
- name: communitarian-app
|
|
||||||
image: "{{ .appImage }}"
|
|
||||||
ports:
|
|
||||||
- containerPort: {{ .appPort }}
|
|
||||||
name: http
|
|
||||||
env:
|
|
||||||
- name: TZ
|
|
||||||
value: "{{ .timezone }}"
|
|
||||||
- name: API_URL
|
|
||||||
value: "http://communitarian-api:{{ .apiPort }}"
|
|
||||||
- name: NEXT_PUBLIC_API_URL
|
|
||||||
value: "/api"
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "128Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop: [ALL]
|
|
||||||
readOnlyRootFilesystem: false
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: communitarian
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
annotations:
|
|
||||||
external-dns.alpha.kubernetes.io/target: "{{ .externalDnsDomain }}"
|
|
||||||
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
|
|
||||||
traefik.ingress.kubernetes.io/router.middlewares: "{{ .namespace }}-strip-api@kubernetescrd"
|
|
||||||
spec:
|
|
||||||
ingressClassName: traefik
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "{{ .domain }}"
|
|
||||||
secretName: "{{ .tlsSecretName }}"
|
|
||||||
rules:
|
|
||||||
- host: "{{ .domain }}"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /api
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: communitarian-api
|
|
||||||
port:
|
|
||||||
number: {{ .apiPort }}
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: communitarian-app
|
|
||||||
port:
|
|
||||||
number: {{ .appPort }}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
labels:
|
|
||||||
- includeSelectors: true
|
|
||||||
pairs:
|
|
||||||
app: communitarian
|
|
||||||
managedBy: kustomize
|
|
||||||
partOf: wild-cloud
|
|
||||||
resources:
|
|
||||||
- namespace.yaml
|
|
||||||
- deployment-app.yaml
|
|
||||||
- deployment-api.yaml
|
|
||||||
- service-app.yaml
|
|
||||||
- service-api.yaml
|
|
||||||
- middleware.yaml
|
|
||||||
- ingress.yaml
|
|
||||||
- pvc.yaml
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: communitarian
|
|
||||||
is: communitarian
|
|
||||||
description: Communitarian is a community-focused application with a web frontend and API backend for collaborative features.
|
|
||||||
version: 1.0.0
|
|
||||||
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/community.svg
|
|
||||||
defaultConfig:
|
|
||||||
namespace: communitarian
|
|
||||||
appImage: payneio/communitarian-app:latest
|
|
||||||
apiImage: payneio/communitarian-api:latest
|
|
||||||
appPort: 3000
|
|
||||||
apiPort: 8000
|
|
||||||
domain: communitarian.{{ .cloud.domain }}
|
|
||||||
externalDnsDomain: "{{ .cloud.domain }}"
|
|
||||||
tlsSecretName: wildcard-wild-cloud-tls
|
|
||||||
storage: 10Gi
|
|
||||||
timezone: UTC
|
|
||||||
defaultSecrets:
|
|
||||||
- key: apiKey
|
|
||||||
- key: jwtSecret
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
apiVersion: traefik.io/v1alpha1
|
|
||||||
kind: Middleware
|
|
||||||
metadata:
|
|
||||||
name: strip-api
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
stripPrefix:
|
|
||||||
prefixes:
|
|
||||||
- /api
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: communitarian-data
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: "{{ .storage }}"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: communitarian-api
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
component: api
|
|
||||||
ports:
|
|
||||||
- port: {{ .apiPort }}
|
|
||||||
targetPort: {{ .apiPort }}
|
|
||||||
protocol: TCP
|
|
||||||
name: http
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: communitarian-app
|
|
||||||
namespace: "{{ .namespace }}"
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
component: app
|
|
||||||
ports:
|
|
||||||
- port: {{ .appPort }}
|
|
||||||
targetPort: {{ .appPort }}
|
|
||||||
protocol: TCP
|
|
||||||
name: http
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Decidim
|
|
||||||
|
|
||||||
Decidim is a participatory democracy framework for cities and organizations. Built in Ruby on Rails, it enables citizen participation through proposals, debates, and voting. Includes Sidekiq for background job processing.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- **PostgreSQL** - Database for storing participatory processes and user data
|
|
||||||
- **Redis** - Used for Sidekiq background job processing
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where Decidim will be accessible (default: `decidim.{your-cloud-domain}`)
|
|
||||||
- **siteName** - Display name for your platform (default: `Decidim`)
|
|
||||||
- **systemAdminEmail** - System admin email (defaults to your operator email)
|
|
||||||
- **storage** - Persistent volume size (default: `20Gi`)
|
|
||||||
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, Decidim will be available at:
|
|
||||||
- `https://decidim.{your-cloud-domain}`
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add decidim
|
|
||||||
wild app deploy decidim
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Log in with the system admin credentials configured during setup
|
|
||||||
|
|
||||||
3. Create your first organization and configure participatory processes
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# Example Admin App
|
|
||||||
|
|
||||||
An example application deployed with internal-only access. This app is useful for testing Wild Cloud's internal ingress and TLS configuration.
|
|
||||||
|
|
||||||
The app uses the internal wildcard TLS certificate and is only accessible within your local network.
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, the app will be available at an internal domain on your Wild Cloud instance.
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Example App
|
|
||||||
|
|
||||||
An example application deployed with public access. This app is useful for testing Wild Cloud's public ingress, TLS, and external DNS configuration.
|
|
||||||
|
|
||||||
The app uses the public wildcard TLS certificate and is accessible from the internet.
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, the app will be available at:
|
|
||||||
- `https://example-app.{your-cloud-domain}`
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,41 +1,7 @@
|
|||||||
# Immich
|
# Immich App
|
||||||
|
|
||||||
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.
|
## To Do
|
||||||
|
|
||||||
## Dependencies
|
- We need a full uninstall script.
|
||||||
|
- We need full backup and restore scripts.
|
||||||
- **PostgreSQL** - Database for storing metadata and search indexes
|
- When recreating the app (uninstall/reinstall), db-init needs to re-run (currently the previous one blocks).
|
||||||
- **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
|
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# Keila
|
|
||||||
|
|
||||||
Keila is an open-source email marketing platform that allows you to send newsletters and manage mailing lists with privacy and control.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- **PostgreSQL** - Database for storing contacts and campaigns
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where Keila will be accessible (default: `keila.{your-cloud-domain}`)
|
|
||||||
- **adminUser** - Admin account email (default: `admin@{your-cloud-domain}`)
|
|
||||||
- **disableRegistration** - Whether to allow new signups (default: `true`)
|
|
||||||
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, Keila will be available at:
|
|
||||||
- `https://keila.{your-cloud-domain}`
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add keila
|
|
||||||
wild app deploy keila
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Log in with the admin credentials configured during setup
|
|
||||||
|
|
||||||
3. Configure your SMTP sender and create your first campaign
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Lemmy
|
|
||||||
|
|
||||||
Lemmy is a selfhosted social link aggregation and discussion platform. It is an open-source alternative to Reddit, designed for the fediverse.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- **PostgreSQL** - Database for storing communities, posts, and comments
|
|
||||||
|
|
||||||
## Components
|
|
||||||
|
|
||||||
Lemmy runs three separate services:
|
|
||||||
|
|
||||||
- **Backend** - Rust API server handling federation and data
|
|
||||||
- **UI** - Web frontend for browsing and interacting
|
|
||||||
- **pict-rs** - Image hosting and processing service
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where Lemmy will be accessible (default: `lemmy.{your-cloud-domain}`)
|
|
||||||
- **storage** - Persistent volume for application data (default: `10Gi`)
|
|
||||||
- **pictrsStorage** - Persistent volume for uploaded images (default: `50Gi`)
|
|
||||||
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, Lemmy will be available at:
|
|
||||||
- `https://lemmy.{your-cloud-domain}`
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add lemmy
|
|
||||||
wild app deploy lemmy
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create your admin account through the web interface
|
|
||||||
|
|
||||||
3. Set up your first community and customize your instance settings
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Loomio
|
|
||||||
|
|
||||||
Loomio is a collaborative decision-making tool that makes it easy for groups to make decisions together. It supports proposals, polls, and structured discussions.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- **PostgreSQL** - Database for storing groups, discussions, and decisions
|
|
||||||
- **Redis** - Used for caching and background jobs
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where Loomio will be accessible (default: `loomio.{your-cloud-domain}`)
|
|
||||||
- **appName** - Display name for your instance (default: `Loomio`)
|
|
||||||
- **adminEmail** - Admin contact email (defaults to your operator email)
|
|
||||||
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, Loomio will be available at:
|
|
||||||
- `https://loomio.{your-cloud-domain}`
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add loomio
|
|
||||||
wild app deploy loomio
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create your account and set up your first group
|
|
||||||
|
|
||||||
3. Invite members and start a discussion or poll
|
|
||||||
30
mailu/configmap.yaml
Normal file
30
mailu/configmap.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: mailu-config
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
data:
|
||||||
|
DOMAIN: "{{ .domain }}"
|
||||||
|
HOSTNAMES: "{{ .hostname }}"
|
||||||
|
POSTMASTER: "admin"
|
||||||
|
TZ: "{{ .timezone }}"
|
||||||
|
TLS_FLAVOR: "cert"
|
||||||
|
MESSAGE_SIZE_LIMIT: "50000000"
|
||||||
|
MESSAGE_RATELIMIT: "200/day"
|
||||||
|
RELAYNETS: ""
|
||||||
|
RELAYHOST: "{{ .relayHost }}"
|
||||||
|
RELAYPORT: "{{ .relayPort }}"
|
||||||
|
FETCHMAIL_ENABLED: "false"
|
||||||
|
RECIPIENT_DELIMITER: "+"
|
||||||
|
DMARC_RUA: "admin"
|
||||||
|
DMARC_RUF: "admin"
|
||||||
|
WELCOME: "false"
|
||||||
|
WELCOME_SUBJECT: "Welcome to your new email account"
|
||||||
|
WELCOME_BODY: "Welcome! You can now use your email account."
|
||||||
|
ADMIN: "true"
|
||||||
|
WEB_ADMIN: "/admin"
|
||||||
|
WEB_WEBMAIL: "/webmail"
|
||||||
|
WEBMAIL: "roundcube"
|
||||||
|
SITENAME: "Mailu"
|
||||||
|
WEBSITE: "https://{{ .hostname }}"
|
||||||
|
LOG_LEVEL: "{{ .logLevel }}"
|
||||||
103
mailu/deployment-admin.yaml
Normal file
103
mailu/deployment-admin.yaml
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: admin
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: admin
|
||||||
|
spec:
|
||||||
|
dnsPolicy: "None"
|
||||||
|
dnsConfig:
|
||||||
|
nameservers:
|
||||||
|
- {{ .unbound.ip }}
|
||||||
|
searches:
|
||||||
|
- {{ .namespace }}.svc.cluster.local
|
||||||
|
- svc.cluster.local
|
||||||
|
- cluster.local
|
||||||
|
options:
|
||||||
|
- name: ndots
|
||||||
|
value: "5"
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox:latest
|
||||||
|
command: ['sh', '-c', 'chown -R 999:999 /data /dkim']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: admin
|
||||||
|
mountPath: /data
|
||||||
|
- name: data
|
||||||
|
subPath: dkim
|
||||||
|
mountPath: /dkim
|
||||||
|
containers:
|
||||||
|
- name: admin
|
||||||
|
image: {{ .images.admin }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- SYS_CHROOT
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
env:
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mailu-secrets
|
||||||
|
key: secretKey
|
||||||
|
- name: REDIS_ADDRESS
|
||||||
|
value: "{{ .redis.host }}"
|
||||||
|
- name: I_KNOW_MY_SETUP_DOESNT_FIT_REQUIREMENTS_AND_WONT_FILE_ISSUES_WITHOUT_PATCHES
|
||||||
|
value: "true"
|
||||||
|
- name: INITIAL_ADMIN_ACCOUNT
|
||||||
|
value: "{{ .initialAccount.username }}"
|
||||||
|
- name: INITIAL_ADMIN_DOMAIN
|
||||||
|
value: "{{ .initialAccount.domain }}"
|
||||||
|
- name: INITIAL_ADMIN_PW
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mailu-secrets
|
||||||
|
key: initialAccountPassword
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: admin
|
||||||
|
mountPath: /data
|
||||||
|
- name: data
|
||||||
|
subPath: dkim
|
||||||
|
mountPath: /dkim
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "250m"
|
||||||
|
limits:
|
||||||
|
memory: "1Gi"
|
||||||
|
cpu: "1000m"
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ping
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ping
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mailu-storage
|
||||||
70
mailu/deployment-dovecot.yaml
Normal file
70
mailu/deployment-dovecot.yaml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dovecot
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: dovecot
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: dovecot
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox:latest
|
||||||
|
command: ['sh', '-c', 'chown -R 999:999 /data /mail']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: mail
|
||||||
|
mountPath: /mail
|
||||||
|
- name: data
|
||||||
|
subPath: dovecot
|
||||||
|
mountPath: /data
|
||||||
|
containers:
|
||||||
|
- name: dovecot
|
||||||
|
image: {{ .images.dovecot }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- SYS_CHROOT
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: imap
|
||||||
|
containerPort: 143
|
||||||
|
- name: imaps
|
||||||
|
containerPort: 993
|
||||||
|
- name: pop3
|
||||||
|
containerPort: 110
|
||||||
|
- name: pop3s
|
||||||
|
containerPort: 995
|
||||||
|
- name: sieve
|
||||||
|
containerPort: 4190
|
||||||
|
- name: auth
|
||||||
|
containerPort: 2102
|
||||||
|
- name: lmtp
|
||||||
|
containerPort: 2525
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: mail
|
||||||
|
mountPath: /mail
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "1Gi"
|
||||||
|
cpu: "500m"
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mailu-storage
|
||||||
70
mailu/deployment-front.yaml
Normal file
70
mailu/deployment-front.yaml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: front
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: front
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: front
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: front
|
||||||
|
image: {{ .images.front }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- SYS_CHROOT
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
env:
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mailu-secrets
|
||||||
|
key: secretKey
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
- name: https
|
||||||
|
containerPort: 443
|
||||||
|
- name: smtp
|
||||||
|
containerPort: 25
|
||||||
|
- name: smtps
|
||||||
|
containerPort: 465
|
||||||
|
- name: submission
|
||||||
|
containerPort: 587
|
||||||
|
- name: imap
|
||||||
|
containerPort: 143
|
||||||
|
- name: imaps
|
||||||
|
containerPort: 993
|
||||||
|
- name: pop3
|
||||||
|
containerPort: 110
|
||||||
|
- name: pop3s
|
||||||
|
containerPort: 995
|
||||||
|
volumeMounts:
|
||||||
|
- name: certs
|
||||||
|
mountPath: /certs
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "256Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
volumes:
|
||||||
|
- name: certs
|
||||||
|
secret:
|
||||||
|
secretName: {{ .tlsSecretName }}
|
||||||
|
optional: true
|
||||||
60
mailu/deployment-postfix.yaml
Normal file
60
mailu/deployment-postfix.yaml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: postfix
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: postfix
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: postfix
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox:latest
|
||||||
|
command: ['sh', '-c', 'chown -R 999:999 /queue']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: mailqueue
|
||||||
|
mountPath: /queue
|
||||||
|
containers:
|
||||||
|
- name: postfix
|
||||||
|
image: {{ .images.postfix }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- SYS_CHROOT
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: smtp
|
||||||
|
containerPort: 25
|
||||||
|
- name: smtps
|
||||||
|
containerPort: 465
|
||||||
|
- name: submission
|
||||||
|
containerPort: 587
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: mailqueue
|
||||||
|
mountPath: /queue
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "250m"
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
cpu: "1000m"
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mailu-storage
|
||||||
56
mailu/deployment-redis.yaml
Normal file
56
mailu/deployment-redis.yaml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: redis
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: {{ .images.redis }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: [ALL]
|
||||||
|
readOnlyRootFilesystem: false
|
||||||
|
ports:
|
||||||
|
- name: redis
|
||||||
|
containerPort: 6379
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "256Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
45
mailu/deployment-rspamd.yaml
Normal file
45
mailu/deployment-rspamd.yaml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: rspamd
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: rspamd
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: rspamd
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: rspamd
|
||||||
|
image: {{ .images.rspamd }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
env:
|
||||||
|
- name: REDIS_ADDRESS
|
||||||
|
value: "{{ .redis.host }}:{{ .redis.port }}"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: rspamd
|
||||||
|
containerPort: 11332
|
||||||
|
- name: http
|
||||||
|
containerPort: 11334
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: rspamd
|
||||||
|
mountPath: /var/lib/rspamd
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "250m"
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mailu-storage
|
||||||
49
mailu/deployment-unbound.yaml
Normal file
49
mailu/deployment-unbound.yaml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: unbound
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: unbound
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: unbound
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: unbound
|
||||||
|
image: {{ .unbound.image }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
env:
|
||||||
|
- name: UNBOUND_TLS_NAME
|
||||||
|
value: "dns"
|
||||||
|
ports:
|
||||||
|
- name: dns
|
||||||
|
containerPort: 53
|
||||||
|
protocol: UDP
|
||||||
|
- name: dns-tcp
|
||||||
|
containerPort: 53
|
||||||
|
protocol: TCP
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "50m"
|
||||||
|
limits:
|
||||||
|
memory: "256Mi"
|
||||||
|
cpu: "200m"
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 53
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 53
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
61
mailu/deployment-webmail.yaml
Normal file
61
mailu/deployment-webmail.yaml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: webmail
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
component: webmail
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
component: webmail
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox:latest
|
||||||
|
command: ['sh', '-c', 'chown -R 999:999 /data']
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: webmail
|
||||||
|
mountPath: /data
|
||||||
|
containers:
|
||||||
|
- name: webmail
|
||||||
|
image: {{ .images.webmail }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- SYS_CHROOT
|
||||||
|
- CHOWN
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
env:
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mailu-secrets
|
||||||
|
key: secretKey
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: mailu-config
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
subPath: webmail
|
||||||
|
mountPath: /data
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "250m"
|
||||||
|
limits:
|
||||||
|
memory: "1Gi"
|
||||||
|
cpu: "1000m"
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mailu-storage
|
||||||
42
mailu/ingress.yaml
Normal file
42
mailu/ingress.yaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: mailu
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }}
|
||||||
|
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .hostname }}
|
||||||
|
secretName: {{ .tlsSecretName }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .hostname }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /admin
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: admin
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- path: /webmail
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: webmail
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: front
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
25
mailu/kustomization.yaml
Normal file
25
mailu/kustomization.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: mailu
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
app: mailu
|
||||||
|
managedBy: kustomize
|
||||||
|
partOf: wild-cloud
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- pvc.yaml
|
||||||
|
- configmap.yaml
|
||||||
|
- deployment-redis.yaml
|
||||||
|
- service-redis.yaml
|
||||||
|
- deployment-unbound.yaml
|
||||||
|
- service-unbound.yaml
|
||||||
|
- deployment-admin.yaml
|
||||||
|
- deployment-front.yaml
|
||||||
|
- deployment-postfix.yaml
|
||||||
|
- deployment-dovecot.yaml
|
||||||
|
- deployment-rspamd.yaml
|
||||||
|
- deployment-webmail.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
60
mailu/manifest.yaml
Normal file
60
mailu/manifest.yaml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: mailu
|
||||||
|
is: mailu
|
||||||
|
description: Mailu is a simple yet full-featured mail server as a set of Docker images. It includes a mail transfer agent, mail delivery agent, webmail, antispam, antivirus, and admin interface.
|
||||||
|
version: 2024.06
|
||||||
|
icon: https://mailu.io/master/_static/mailu_logo.svg
|
||||||
|
defaultConfig:
|
||||||
|
namespace: mailu
|
||||||
|
|
||||||
|
# Domain configuration
|
||||||
|
domain: "{{ .cloud.baseDomain }}"
|
||||||
|
hostname: mail.{{ .cloud.domain }}
|
||||||
|
|
||||||
|
# Container images (from ghcr.io)
|
||||||
|
images:
|
||||||
|
admin: ghcr.io/mailu/admin:2024.06
|
||||||
|
front: ghcr.io/mailu/nginx:2024.06
|
||||||
|
postfix: ghcr.io/mailu/postfix:2024.06
|
||||||
|
dovecot: ghcr.io/mailu/dovecot:2024.06
|
||||||
|
rspamd: ghcr.io/mailu/rspamd:2024.06
|
||||||
|
clamav: ghcr.io/mailu/clamav:2024.06
|
||||||
|
webmail: ghcr.io/mailu/webmail:2024.06
|
||||||
|
redis: redis:alpine
|
||||||
|
|
||||||
|
# Redis configuration (built-in Redis without authentication)
|
||||||
|
redis:
|
||||||
|
host: redis.mailu.svc.cluster.local
|
||||||
|
port: 6379
|
||||||
|
|
||||||
|
# Unbound DNS resolver (for DNSSEC validation)
|
||||||
|
unbound:
|
||||||
|
image: ghcr.io/mailu/unbound:2024.06
|
||||||
|
ip: 10.96.200.1
|
||||||
|
|
||||||
|
# Timezone
|
||||||
|
timezone: UTC
|
||||||
|
|
||||||
|
# Storage
|
||||||
|
storage: 100Gi
|
||||||
|
|
||||||
|
# Initial admin account
|
||||||
|
initialAccount:
|
||||||
|
enabled: true
|
||||||
|
username: admin
|
||||||
|
domain: "{{ .cloud.baseDomain }}"
|
||||||
|
email: "{{ .operator.email }}"
|
||||||
|
|
||||||
|
# TLS configuration
|
||||||
|
tlsSecretName: mailu-tls
|
||||||
|
externalDnsDomain: "{{ .cloud.domain }}"
|
||||||
|
|
||||||
|
# Log level
|
||||||
|
logLevel: WARNING
|
||||||
|
|
||||||
|
# SMTP relay (optional)
|
||||||
|
relayHost: ""
|
||||||
|
relayPort: 25
|
||||||
|
|
||||||
|
defaultSecrets:
|
||||||
|
- key: secretKey
|
||||||
|
- key: initialAccountPassword
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: "{{ .namespace }}"
|
name: {{ .namespace }}
|
||||||
11
mailu/pvc.yaml
Normal file
11
mailu/pvc.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mailu-storage
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .storage }}
|
||||||
14
mailu/service-redis.yaml
Normal file
14
mailu/service-redis.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: redis
|
||||||
|
ports:
|
||||||
|
- name: redis
|
||||||
|
port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
protocol: TCP
|
||||||
|
type: ClusterIP
|
||||||
19
mailu/service-unbound.yaml
Normal file
19
mailu/service-unbound.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: unbound
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
clusterIP: {{ .unbound.ip }}
|
||||||
|
selector:
|
||||||
|
component: unbound
|
||||||
|
ports:
|
||||||
|
- name: dns
|
||||||
|
port: 53
|
||||||
|
targetPort: 53
|
||||||
|
protocol: UDP
|
||||||
|
- name: dns-tcp
|
||||||
|
port: 53
|
||||||
|
targetPort: 53
|
||||||
|
protocol: TCP
|
||||||
|
type: ClusterIP
|
||||||
123
mailu/service.yaml
Normal file
123
mailu/service.yaml
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: admin
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: front
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
component: front
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
- name: https
|
||||||
|
port: 443
|
||||||
|
targetPort: 443
|
||||||
|
- name: smtp
|
||||||
|
port: 25
|
||||||
|
targetPort: 25
|
||||||
|
- name: smtps
|
||||||
|
port: 465
|
||||||
|
targetPort: 465
|
||||||
|
- name: submission
|
||||||
|
port: 587
|
||||||
|
targetPort: 587
|
||||||
|
- name: imap
|
||||||
|
port: 143
|
||||||
|
targetPort: 143
|
||||||
|
- name: imaps
|
||||||
|
port: 993
|
||||||
|
targetPort: 993
|
||||||
|
- name: pop3
|
||||||
|
port: 110
|
||||||
|
targetPort: 110
|
||||||
|
- name: pop3s
|
||||||
|
port: 995
|
||||||
|
targetPort: 995
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postfix
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: postfix
|
||||||
|
ports:
|
||||||
|
- name: smtp
|
||||||
|
port: 25
|
||||||
|
targetPort: 25
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dovecot
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: dovecot
|
||||||
|
ports:
|
||||||
|
- name: imap
|
||||||
|
port: 143
|
||||||
|
targetPort: 143
|
||||||
|
- name: imaps
|
||||||
|
port: 993
|
||||||
|
targetPort: 993
|
||||||
|
- name: pop3
|
||||||
|
port: 110
|
||||||
|
targetPort: 110
|
||||||
|
- name: pop3s
|
||||||
|
port: 995
|
||||||
|
targetPort: 995
|
||||||
|
- name: sieve
|
||||||
|
port: 4190
|
||||||
|
targetPort: 4190
|
||||||
|
- name: auth
|
||||||
|
port: 2102
|
||||||
|
targetPort: 2102
|
||||||
|
- name: lmtp
|
||||||
|
port: 2525
|
||||||
|
targetPort: 2525
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: rspamd
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: rspamd
|
||||||
|
ports:
|
||||||
|
- name: rspamd
|
||||||
|
port: 11332
|
||||||
|
targetPort: 11332
|
||||||
|
- name: http
|
||||||
|
port: 11334
|
||||||
|
targetPort: 11334
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: webmail
|
||||||
|
namespace: {{ .namespace }}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
component: webmail
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Matrix (Synapse)
|
|
||||||
|
|
||||||
Matrix is an open standard for secure, decentralized, real-time communication. This deploys the Synapse homeserver for self-hosted Matrix federation and messaging.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- **PostgreSQL** - Database for storing messages and account data
|
|
||||||
- **Redis** - Used for inter-worker communication
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where the Synapse web client will be accessible (default: `matrix.{your-cloud-domain}`)
|
|
||||||
- **serverName** - Your Matrix server identity, used in user IDs like `@user:{serverName}` (default: `{your-cloud-domain}`)
|
|
||||||
- **enableRegistration** - Whether to allow public account creation (default: `false`)
|
|
||||||
- **storage** - Persistent volume for Synapse data (default: `50Gi`)
|
|
||||||
- **mediaStorage** - Persistent volume for uploaded media (default: `100Gi`)
|
|
||||||
- **SMTP** - Email delivery settings inherited from your Wild Cloud instance
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, the Synapse homeserver will be available at:
|
|
||||||
- `https://matrix.{your-cloud-domain}`
|
|
||||||
|
|
||||||
Connect using any Matrix client (Element, FluffyChat, etc.) with your server name.
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add matrix
|
|
||||||
wild app deploy matrix
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Use the registration shared secret (in your `secrets.yaml`) to create your first admin account, or enable public registration temporarily
|
|
||||||
|
|
||||||
3. Connect with a Matrix client and start messaging
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Memcached
|
|
||||||
|
|
||||||
Memcached is an in-memory key-value store for small chunks of arbitrary data, commonly used as a cache layer to speed up applications.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None. Memcached is a standalone infrastructure service.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **memoryLimit** - Maximum memory usage (default: `64m`)
|
|
||||||
- **maxConnections** - Maximum concurrent connections (default: `1024`)
|
|
||||||
- **replicas** - Number of instances (default: `1`)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Other apps that depend on Memcached (such as OpenProject) will connect to it automatically at `memcached.memcached.svc.cluster.local:11211`.
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# MySQL
|
|
||||||
|
|
||||||
MySQL is an open-source relational database management system. This deploys a shared MySQL instance used by apps that require MySQL (such as Ghost).
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None. MySQL is a standalone infrastructure service.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **storage** - Persistent volume size (default: `20Gi`)
|
|
||||||
- **port** - Service port (default: `3306`)
|
|
||||||
- **timezone** - Server timezone (default: `UTC`)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Apps that depend on MySQL will connect to it at `mysql.mysql.svc.cluster.local:3306`. Database credentials are managed automatically through the secrets system.
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Open WebUI
|
|
||||||
|
|
||||||
Open WebUI is a comprehensive, open-source web interface for AI models. It features a user-friendly design similar to ChatGPT and can connect to local or hosted LLM backends.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None required, but works best with a local LLM backend like **vLLM** deployed on your cluster.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **domain** - Where the UI will be accessible (default: `chat.{your-cloud-domain}`)
|
|
||||||
- **vllmApiUrl** - URL of your LLM backend (default: connects to vLLM on the cluster)
|
|
||||||
- **enableSignup** - Whether to allow new account creation (default: `false`)
|
|
||||||
- **storage** - Persistent volume size (default: `10Gi`)
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, Open WebUI will be available at:
|
|
||||||
- `https://chat.{your-cloud-domain}`
|
|
||||||
|
|
||||||
## First-Time Setup
|
|
||||||
|
|
||||||
1. Deploy a local LLM backend (e.g., vLLM) if you haven't already
|
|
||||||
|
|
||||||
2. Add and deploy the app:
|
|
||||||
```bash
|
|
||||||
wild app add open-webui
|
|
||||||
wild app deploy open-webui
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Create your account and start chatting with your local AI models
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# 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
|
|
||||||
@@ -1,19 +1 @@
|
|||||||
# PostgreSQL
|
# Postgress app
|
||||||
|
|
||||||
PostgreSQL is a powerful, open-source relational database system. This deploys a shared PostgreSQL instance used by many Wild Cloud apps.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None. PostgreSQL is a standalone infrastructure service.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **storage** - Persistent volume size (default: `20Gi`)
|
|
||||||
- **port** - Service port (default: `5432`)
|
|
||||||
- **timezone** - Server timezone (default: `UTC`)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Apps that depend on PostgreSQL (such as Immich, Gitea, Discourse, Mastodon, and others) will connect to it at `postgres.postgres.svc.cluster.local:5432`. Each app creates its own database and user via a db-init job during deployment. Root credentials are managed through the secrets system.
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
# Redis
|
|
||||||
|
|
||||||
Redis is an open-source, in-memory data structure store used as a database, cache, and message broker. This deploys a shared Redis instance used by apps that require it.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None. Redis is a standalone infrastructure service.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **port** - Service port (default: `6379`)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Apps that depend on Redis (such as Immich, Mastodon, Discourse, and others) will connect to it automatically at `redis.redis.svc.cluster.local:6379`. Authentication is managed through the secrets system.
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# vLLM
|
|
||||||
|
|
||||||
vLLM is a fast and easy-to-use library for LLM inference and serving with an OpenAI-compatible API. Use it to run large language models on your own hardware.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
None, but requires a GPU node in your cluster.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Key settings configured through your instance's `config.yaml`:
|
|
||||||
|
|
||||||
- **model** - Hugging Face model to serve (default: `Qwen/Qwen2.5-7B-Instruct`)
|
|
||||||
- **maxModelLen** - Maximum sequence length (default: `8192`)
|
|
||||||
- **gpuProduct** - Required GPU type (default: `RTX 4090`)
|
|
||||||
- **gpuCount** - Number of GPUs to use (default: `1`)
|
|
||||||
- **gpuMemoryUtilization** - Fraction of GPU memory to use (default: `0.9`)
|
|
||||||
- **domain** - Where the API will be accessible (default: `vllm.{your-cloud-domain}`)
|
|
||||||
|
|
||||||
## Access
|
|
||||||
|
|
||||||
After deployment, the OpenAI-compatible API will be available at:
|
|
||||||
- `https://vllm.{your-cloud-domain}/v1`
|
|
||||||
|
|
||||||
Other apps on the cluster (such as Open WebUI) can connect internally at `http://vllm-service.llm.svc.cluster.local:8000/v1`.
|
|
||||||
|
|
||||||
## Hardware Requirements
|
|
||||||
|
|
||||||
This app requires a GPU node in your cluster. Adjust the `gpuProduct`, `gpuCount`, and memory settings to match your available hardware.
|
|
||||||
Reference in New Issue
Block a user