refactor: remove La Suite services (except Meet + Collabora), delete local overlay

La Suite Messages, Calendars, Drive, Projects, Hive, Integration, and
Postfix are replaced by Stalwart (mail) and Tuwunel (messaging). Meet
and Collabora remain for video conferencing and document editing.

Local overlay was POC only — all deployment targets production now.

Deleted: 37 La Suite manifests, Drive Helm chart, 7 local overlay files,
stale MTA-in hostPort patch. Cleaned up production image overrides and
resource patches for removed services.
This commit is contained in:
2026-04-06 18:03:55 +01:00
parent 8662c79212
commit 6acf598f92
49 changed files with 0 additions and 2577 deletions

View File

@@ -1,163 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: calendars-backend
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: calendars-backend
template:
metadata:
labels:
app: calendars-backend
spec:
initContainers:
- name: migrate
image: calendars-backend
command: ["python", "manage.py", "migrate", "--no-input"]
envFrom:
- configMapRef:
name: calendars-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: calendars-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: SALT_KEY
- name: CALDAV_INBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INBOUND_API_KEY
- name: CALDAV_OUTBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_OUTBOUND_API_KEY
- name: CALDAV_INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INTERNAL_API_KEY
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_SECRET
resources:
limits:
memory: 512Mi
cpu: 500m
requests:
memory: 128Mi
cpu: 100m
containers:
- name: calendars-backend
image: calendars-backend
command:
- gunicorn
- -c
- /app/gunicorn.conf.py
- calendars.wsgi:application
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: calendars-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: calendars-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: SALT_KEY
- name: CALDAV_INBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INBOUND_API_KEY
- name: CALDAV_OUTBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_OUTBOUND_API_KEY
- name: CALDAV_INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INTERNAL_API_KEY
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_SECRET
volumeMounts:
- name: theme
mountPath: /app/theme.json
subPath: theme.json
- name: translations
mountPath: /data/translations.json
subPath: translations.json
livenessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
resources:
limits:
memory: 512Mi
cpu: 500m
requests:
memory: 256Mi
cpu: 100m
volumes:
- name: theme
configMap:
name: calendars-theme
- name: translations
configMap:
name: calendars-translations

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: calendars-backend
namespace: lasuite
spec:
selector:
app: calendars-backend
ports:
- port: 80
targetPort: 8000

View File

@@ -1,97 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: calendars-caldav
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: calendars-caldav
template:
metadata:
labels:
app: calendars-caldav
spec:
initContainers:
- name: init-database
image: calendars-caldav
command: ["/usr/local/bin/init-database.sh"]
env:
- name: PGHOST
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_HOST
- name: PGPORT
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_PORT
- name: PGDATABASE
value: calendars_db
- name: PGUSER
value: calendars
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: calendars-db-credentials
key: password
resources:
limits:
memory: 128Mi
cpu: 100m
requests:
memory: 64Mi
cpu: 10m
containers:
- name: calendars-caldav
image: calendars-caldav
ports:
- containerPort: 80
env:
- name: PGHOST
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_HOST
- name: PGPORT
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_PORT
- name: PGDATABASE
value: calendars_db
- name: PGUSER
value: calendars
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: calendars-db-credentials
key: password
- name: CALDAV_INBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INBOUND_API_KEY
- name: CALDAV_OUTBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_OUTBOUND_API_KEY
- name: CALDAV_INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INTERNAL_API_KEY
- name: CALDAV_BASE_URI
value: /caldav/
- name: CALLBACK_BASE_URL
value: http://calendars-backend.lasuite.svc.cluster.local:8000
resources:
limits:
memory: 256Mi
cpu: 300m
requests:
memory: 128Mi
cpu: 50m

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: calendars-caldav
namespace: lasuite
spec:
selector:
app: calendars-caldav
ports:
- port: 80
targetPort: 80

View File

@@ -1,30 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: calendars-config
namespace: lasuite
data:
DJANGO_CONFIGURATION: Production
DJANGO_SETTINGS_MODULE: calendars.settings
DJANGO_ALLOWED_HOSTS: cal.DOMAIN_SUFFIX,calendars-backend.lasuite.svc.cluster.local,localhost
DJANGO_CSRF_TRUSTED_ORIGINS: https://cal.DOMAIN_SUFFIX
DB_NAME: calendars_db
DB_USER: calendars
CALDAV_URL: http://calendars-caldav.lasuite.svc.cluster.local:80
CALDAV_CALLBACK_BASE_URL: http://calendars-backend.lasuite.svc.cluster.local:8000
REDIS_URL: redis://valkey.data.svc.cluster.local:6379/5
DRAMATIQ_BROKER_URL: redis://valkey.data.svc.cluster.local:6379/5
DRAMATIQ_RESULT_BACKEND_URL: redis://valkey.data.svc.cluster.local:6379/6
APP_URL: https://cal.DOMAIN_SUFFIX
DEFAULT_FROM_EMAIL: noreply@sunbeam.pt
CALENDAR_INVITATION_FROM_EMAIL: calendar@sunbeam.pt
CALENDAR_ITIP_ENABLED: "True"
LOGIN_REDIRECT_URL: /
LOGIN_REDIRECT_URL_FAILURE: /
LOGOUT_REDIRECT_URL: /
FRONTEND_THEME: sunbeam
FRONTEND_HIDE_GAUFRE: "False"
NEXT_PUBLIC_VISIO_BASE_URL: https://meet.DOMAIN_SUFFIX
FRONTEND_CSS_URL: https://integration.DOMAIN_SUFFIX/api/v2/theme.css
OIDC_USERINFO_FULLNAME_FIELDS: given_name,family_name
THEME_CUSTOMIZATION_FILE_PATH: /app/theme.json

View File

@@ -1,26 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: calendars-frontend-caddyfile
namespace: lasuite
data:
Caddyfile: |
{
auto_https off
admin off
}
:8080 {
root * /srv
header X-Frame-Options DENY
route {
try_files {path} {path}.html /index.html
file_server
}
handle_errors {
rewrite * /404.html
file_server
}
}

View File

@@ -1,35 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: calendars-frontend
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: calendars-frontend
template:
metadata:
labels:
app: calendars-frontend
spec:
containers:
- name: calendars-frontend
image: calendars-frontend
ports:
- containerPort: 8080
volumeMounts:
- name: caddyfile
mountPath: /etc/caddy/Caddyfile
subPath: Caddyfile
resources:
limits:
memory: 128Mi
cpu: 100m
requests:
memory: 64Mi
cpu: 10m
volumes:
- name: caddyfile
configMap:
name: calendars-frontend-caddyfile

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: calendars-frontend
namespace: lasuite
spec:
selector:
app: calendars-frontend
ports:
- port: 80
targetPort: 8080

View File

@@ -1,17 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: calendars-theme
namespace: lasuite
data:
theme.json: |
{
"css_url": "https://integration.DOMAIN_SUFFIX/api/v2/theme.css",
"waffle": {
"apiUrl": "https://integration.DOMAIN_SUFFIX/api/v2/services.json",
"widgetPath": "https://integration.DOMAIN_SUFFIX/api/v2/lagaufre.js",
"label": "O Estúdio",
"closeLabel": "Fechar",
"newWindowLabelSuffix": " · nova janela"
}
}

View File

@@ -1,88 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: calendars-worker
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: calendars-worker
template:
metadata:
labels:
app: calendars-worker
spec:
containers:
- name: calendars-worker
image: calendars-backend
command: ["python", "worker.py"]
envFrom:
- configMapRef:
name: calendars-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: calendars-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: SALT_KEY
- name: CALDAV_INBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INBOUND_API_KEY
- name: CALDAV_OUTBOUND_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_OUTBOUND_API_KEY
- name: CALDAV_INTERNAL_API_KEY
valueFrom:
secretKeyRef:
name: calendars-django-secret
key: CALDAV_INTERNAL_API_KEY
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-calendars
key: CLIENT_SECRET
volumeMounts:
- name: theme
mountPath: /app/theme.json
subPath: theme.json
- name: translations
mountPath: /data/translations.json
subPath: translations.json
resources:
limits:
memory: 256Mi
cpu: 300m
requests:
memory: 128Mi
cpu: 50m
volumes:
- name: theme
configMap:
name: calendars-theme
- name: translations
configMap:
name: calendars-translations

View File

@@ -1,88 +0,0 @@
# nginx config for drive-frontend.
#
# /media/ requests are validated via auth_request to the Drive backend before
# being proxied to SeaweedFS. This avoids exposing S3 credentials to the browser
# while still serving private files through the CDN path.
apiVersion: v1
kind: ConfigMap
metadata:
name: drive-frontend-nginx-conf
namespace: lasuite
data:
default.conf: |
server {
listen 8080;
server_name localhost;
server_tokens off;
root /usr/share/nginx/html;
# Rewrite hardcoded upstream La Gaufre widget and services API URLs to our
# integration service. sub_filter doesn't work on gzip-compressed responses.
gzip off;
sub_filter_once off;
sub_filter_types text/html application/javascript;
sub_filter 'https://static.suite.anct.gouv.fr/widgets/lagaufre.js'
'https://integration.DOMAIN_SUFFIX/api/v2/lagaufre.js';
sub_filter 'https://lasuite.numerique.gouv.fr/api/services'
'https://integration.DOMAIN_SUFFIX/api/v2/services.json';
sub_filter 'https://operateurs.suite.anct.gouv.fr/api/v1.0/lagaufre/services/?operator=9f5624fc-ef99-4d10-ae3f-403a81eb16ef&siret=21870030000013'
'https://integration.DOMAIN_SUFFIX/api/v2/services.json';
sub_filter '</head>' '<link rel="stylesheet" href="https://integration.DOMAIN_SUFFIX/api/v2/theme.css"></head>';
# Public file viewer — Next.js static export generates a literal [id].html
# template for this dynamic route. Serve it for any file UUID so the
# client-side router hydrates the correct FilePage component without auth.
location ~ ^/explorer/items/files/[^/]+$ {
try_files $uri $uri.html /explorer/items/files/[id].html;
}
# Item detail routes (folders, workspaces, shared items).
location ~ ^/explorer/items/[^/]+$ {
try_files $uri $uri.html /explorer/items/[id].html;
}
location / {
# Try the exact path, then path + .html (Next.js static export generates
# e.g. explorer/items/my-files.html), then fall back to index.html for
# client-side routes that have no pre-rendered file.
try_files $uri $uri.html /index.html;
}
# Protected media: auth via Drive backend, then proxy to S3 with signed headers.
# media-auth returns SigV4 Authorization/X-Amz-Date/X-Amz-Content-SHA256
# headers signed for the S3 key (item/UUID/file). nginx captures them and
# forwards to SeaweedFS. The regex strips /media/ and optional /preview/
# so the proxy path matches the signed S3 key exactly.
location ~ ^/media/(preview/)?(.*) {
set $original_uri $request_uri;
set $s3_key $2;
resolver kube-dns.kube-system.svc.cluster.local valid=30s;
set $s3_backend http://seaweedfs-filer.storage.svc.cluster.local:8333;
auth_request /internal/media-auth;
auth_request_set $auth_header $upstream_http_authorization;
auth_request_set $amz_date $upstream_http_x_amz_date;
auth_request_set $amz_content $upstream_http_x_amz_content_sha256;
proxy_set_header Authorization $auth_header;
proxy_set_header X-Amz-Date $amz_date;
proxy_set_header X-Amz-Content-Sha256 $amz_content;
proxy_pass $s3_backend/sunbeam-drive/$s3_key;
}
# Internal subrequest: Django checks session and item access, returns S3 auth headers.
location = /internal/media-auth {
internal;
proxy_pass http://drive-backend.lasuite.svc.cluster.local:80/api/v1.0/items/media-auth/;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Cookie $http_cookie;
proxy_set_header Host drive.DOMAIN_SUFFIX;
proxy_set_header X-Original-URL https://drive.DOMAIN_SUFFIX$original_uri;
}
error_page 500 502 503 504 @blank_error;
location @blank_error {
return 200 '';
add_header Content-Type text/html;
}
}

View File

@@ -1,215 +0,0 @@
# La Suite Numérique — Drive (drive chart).
# Env vars use the chart's dict-based envVars schema:
# string value → rendered as env.value
# map value → rendered as env.valueFrom (configMapKeyRef / secretKeyRef)
# DOMAIN_SUFFIX is substituted by sed at deploy time.
#
# Required secrets (created by seed script):
# oidc-drive — CLIENT_ID, CLIENT_SECRET (created by Hydra Maester)
# drive-db-credentials — password (VaultDynamicSecret, DB engine)
# drive-django-secret — DJANGO_SECRET_KEY (VaultStaticSecret)
# seaweedfs-s3-credentials — S3_ACCESS_KEY, S3_SECRET_KEY (shared)
fullnameOverride: drive
backend:
livenessProbe:
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
createsuperuser:
# No superuser — users authenticate via OIDC.
# The chart always renders this Job; override command so it exits 0.
command: ["true"]
envVars: &backendEnvVars
# ── Database ──────────────────────────────────────────────────────────────
DB_NAME: drive_db
DB_USER: drive
DB_HOST:
configMapKeyRef:
name: lasuite-postgres
key: DB_HOST
DB_PORT:
configMapKeyRef:
name: lasuite-postgres
key: DB_PORT
# Drive uses psycopg3 backend (no _psycopg2 suffix).
DB_ENGINE: django.db.backends.postgresql
DB_PASSWORD:
secretKeyRef:
name: drive-db-credentials
key: password
# ── Redis / Celery ────────────────────────────────────────────────────────
REDIS_URL:
configMapKeyRef:
name: lasuite-valkey
key: REDIS_URL
# Drive uses DJANGO_CELERY_BROKER_URL (not CELERY_BROKER_URL).
DJANGO_CELERY_BROKER_URL:
configMapKeyRef:
name: lasuite-valkey
key: CELERY_BROKER_URL
# ── S3 (file storage) ─────────────────────────────────────────────────────
AWS_STORAGE_BUCKET_NAME: sunbeam-drive
AWS_S3_ENDPOINT_URL:
configMapKeyRef:
name: lasuite-s3
key: AWS_S3_ENDPOINT_URL
AWS_S3_REGION_NAME:
configMapKeyRef:
name: lasuite-s3
key: AWS_S3_REGION_NAME
AWS_DEFAULT_ACL:
configMapKeyRef:
name: lasuite-s3
key: AWS_DEFAULT_ACL
# Drive uses AWS_S3_ACCESS_KEY_ID / AWS_S3_SECRET_ACCESS_KEY (with _S3_ prefix).
AWS_S3_ACCESS_KEY_ID:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_ACCESS_KEY
AWS_S3_SECRET_ACCESS_KEY:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_SECRET_KEY
# Public S3 endpoint for browser-side presigned upload URLs.
AWS_S3_DOMAIN_REPLACE: https://s3.DOMAIN_SUFFIX
# Base URL for media file references so nginx auth proxy receives full paths.
MEDIA_BASE_URL: https://drive.DOMAIN_SUFFIX
# ── OIDC (Hydra) ──────────────────────────────────────────────────────────
OIDC_RP_CLIENT_ID:
secretKeyRef:
name: oidc-drive
key: CLIENT_ID
OIDC_RP_CLIENT_SECRET:
secretKeyRef:
name: oidc-drive
key: CLIENT_SECRET
OIDC_RP_SIGN_ALGO:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_RP_SIGN_ALGO
OIDC_RP_SCOPES:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_RP_SCOPES
OIDC_OP_JWKS_ENDPOINT:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_OP_JWKS_ENDPOINT
OIDC_OP_AUTHORIZATION_ENDPOINT:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_OP_AUTHORIZATION_ENDPOINT
OIDC_OP_TOKEN_ENDPOINT:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_OP_TOKEN_ENDPOINT
OIDC_OP_USER_ENDPOINT:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_OP_USER_ENDPOINT
OIDC_OP_LOGOUT_ENDPOINT:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_OP_LOGOUT_ENDPOINT
OIDC_VERIFY_SSL:
configMapKeyRef:
name: lasuite-oidc-provider
key: OIDC_VERIFY_SSL
# ── Resource Server (Drive as OAuth2 RS for Messages integration) ─────────
OIDC_RESOURCE_SERVER_ENABLED: "True"
# Hydra issuer URL — must match the `iss` claim in introspection responses.
OIDC_OP_URL: https://auth.DOMAIN_SUFFIX/
# Hydra token introspection endpoint (admin port — no client auth required).
OIDC_OP_INTROSPECTION_ENDPOINT: http://hydra-admin.ory.svc.cluster.local:4445/admin/oauth2/introspect
# Drive authenticates to Hydra introspection using its own OIDC client creds.
OIDC_RS_CLIENT_ID:
secretKeyRef:
name: oidc-drive
key: CLIENT_ID
OIDC_RS_CLIENT_SECRET:
secretKeyRef:
name: oidc-drive
key: CLIENT_SECRET
# Accept bearer tokens from Sunbeam CLI and Messages (server-to-server).
# OIDC_RS_ALLOWED_AUDIENCES is set by the sunbeam seed script which reads
# the messages client ID from the oidc-messages secret and combines it with
# the static sunbeam-cli audience. Stored in vault as secret/drive.
OIDC_RS_ALLOWED_AUDIENCES:
secretKeyRef:
name: drive-rs-audiences
key: OIDC_RS_ALLOWED_AUDIENCES
# ── Django ────────────────────────────────────────────────────────────────
DJANGO_SECRET_KEY:
secretKeyRef:
name: drive-django-secret
key: DJANGO_SECRET_KEY
DJANGO_CONFIGURATION: Production
ALLOWED_HOSTS: drive.DOMAIN_SUFFIX
DJANGO_ALLOWED_HOSTS: drive.DOMAIN_SUFFIX
DJANGO_CSRF_TRUSTED_ORIGINS: https://drive.DOMAIN_SUFFIX
LOGIN_REDIRECT_URL: /
LOGOUT_REDIRECT_URL: /
SESSION_COOKIE_AGE: "604800"
# Session cache TTL must match SESSION_COOKIE_AGE.
CACHES_SESSION_TIMEOUT: "604800"
# Silent login: when the Django session expires, the frontend redirects
# to the OIDC login endpoint which completes instantly (Hydra already
# has a session) and bounces the user back. This keeps users logged in
# seamlessly as long as their Hydra SSO session is valid.
FRONTEND_SILENT_LOGIN_ENABLED: "true"
# Redirect unauthenticated visitors at / straight to OIDC login instead of
# showing the La Suite marketing landing page. returnTo brings them to
# their files after successful auth.
FRONTEND_EXTERNAL_HOME_URL: "https://drive.DOMAIN_SUFFIX/api/v1.0/authenticate/?returnTo=https%3A%2F%2Fdrive.DOMAIN_SUFFIX%2Fexplorer%2Fitems%2Fmy-files"
# Allow Messages to call Drive SDK relay cross-origin.
SDK_CORS_ALLOWED_ORIGINS: "https://mail.DOMAIN_SUFFIX"
CORS_ALLOWED_ORIGINS: "https://mail.DOMAIN_SUFFIX"
# Allow all file types — self-hosted instance, no need to restrict uploads.
RESTRICT_UPLOAD_FILE_TYPE: "False"
# ── WOPI / Collabora ──────────────────────────────────────────────────────
# Comma-separated list of enabled WOPI client names.
# Inject Sunbeam theme CSS from the integration service.
FRONTEND_CSS_URL: "https://integration.DOMAIN_SUFFIX/api/v2/theme.css"
WOPI_CLIENTS: collabora
# Discovery XML endpoint — Collabora registers supported MIME types here.
WOPI_COLLABORA_DISCOVERY_URL: http://collabora.lasuite.svc.cluster.local:9980/hosting/discovery
# Base URL Drive uses when building wopi_src callback URLs for Collabora.
WOPI_SRC_BASE_URL: https://drive.DOMAIN_SUFFIX
themeCustomization:
enabled: true
file_content:
css_url: "https://integration.DOMAIN_SUFFIX/api/v2/theme.css"
waffle:
apiUrl: "https://integration.DOMAIN_SUFFIX/api/v2/services.json"
widgetPath: "https://integration.DOMAIN_SUFFIX/api/v2/lagaufre.js"
label: "O Estúdio"
closeLabel: "Fechar"
newWindowLabelSuffix: " · nova janela"
ingress:
enabled: false
ingressAdmin:
enabled: false
ingressMedia:
enabled: false

View File

@@ -1,28 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: hive-config
namespace: lasuite
data:
config.toml: |
[drive]
base_url = "http://drive-backend.lasuite.svc.cluster.local:80"
workspace = "Game Assets"
oidc_client_id = "hive"
oidc_token_url = "http://hydra.ory.svc.cluster.local:4444/oauth2/token"
# oidc_client_secret_file = "/run/secrets/hive-oidc" # mounted from Secret
[s3]
endpoint = "http://seaweedfs-filer.storage.svc.cluster.local:8333"
bucket = "sunbeam-game-assets"
region = "us-east-1"
# access_key_file = "/run/secrets/seaweedfs-key" # mounted from Secret
# secret_key_file = "/run/secrets/seaweedfs-secret" # mounted from Secret
[postgres]
# url_file = "/run/secrets/hive-db-url" # mounted from Secret
[sync]
interval_seconds = 30
temp_dir = "/tmp/hive"
large_file_threshold_mb = 50

View File

@@ -1,45 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hive
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: hive
template:
metadata:
labels:
app: hive
spec:
automountServiceAccountToken: false
containers:
- name: hive
image: nginx:alpine # placeholder until La Suite Hive image is built
volumeMounts:
- name: config
mountPath: /etc/hive
readOnly: true
- name: secrets
mountPath: /run/secrets
readOnly: true
resources:
limits:
memory: 64Mi
requests:
memory: 32Mi
cpu: 25m
volumes:
- name: config
configMap:
name: hive-config
- name: secrets
projected:
sources:
- secret:
name: hive-oidc
- secret:
name: seaweedfs-s3-credentials
- secret:
name: hive-db-url

View File

@@ -1,15 +0,0 @@
# Hive has no inbound HTTP API — it is a reconciliation daemon only.
# This Service exists for Linkerd observability (metrics scraping).
apiVersion: v1
kind: Service
metadata:
name: hive
namespace: lasuite
spec:
selector:
app: hive
ports:
- name: metrics
port: 9090
targetPort: 9090
protocol: TCP

View File

@@ -1,109 +0,0 @@
# La Gaufre integration service — O Estúdio app launcher (La Gaufre v2).
# Serves the lagaufre.js v2 widget, SVG logos, and the v2 services API.
# Apps load gaufre.js which in turn initialises the v2 widget with the
# button already rendered by @gouvfr-lasuite/ui-kit.
#
# Image: src.DOMAIN_SUFFIX/studio/integration:latest
# Built from sunbeam/integration-service/ (context: sunbeam/ root)
# Baked in: lagaufre.js v2, official La Suite logos, custom logos, gaufre.js, nginx.conf
#
# ConfigMap: only services.json (v2 format) — the one thing that varies per env
# DOMAIN_SUFFIX substituted at deploy time.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: integration-config
namespace: lasuite
data:
services.json: |
{
"services": [
{
"name": "Calendar",
"url": "https://cal.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/calendar.svg?v=1"
},
{
"name": "Drive",
"url": "https://drive.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/drive.svg?v=1"
},
{
"name": "Mail",
"url": "https://mail.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/mail.svg?v=1"
},
{
"name": "Meet",
"url": "https://meet.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/visio.svg?v=2"
},
{
"name": "Projects",
"url": "https://projects.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/projects.svg?v=1"
},
{
"name": "Source Code",
"url": "https://src.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/docs.svg?v=1"
},
{
"name": "Account",
"url": "https://auth.DOMAIN_SUFFIX",
"logo": "https://integration.DOMAIN_SUFFIX/logos/account.svg?v=1"
}
]
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: integration
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: integration
template:
metadata:
labels:
app: integration
spec:
containers:
- name: integration
image: integration
ports:
- name: http
containerPort: 80
volumeMounts:
- name: config
mountPath: /etc/integration/services.json
subPath: services.json
resources:
limits:
memory: 32Mi
requests:
memory: 16Mi
cpu: 5m
volumes:
- name: config
configMap:
name: integration-config
---
apiVersion: v1
kind: Service
metadata:
name: integration
namespace: lasuite
spec:
selector:
app: integration
ports:
- name: http
port: 80
targetPort: 80

View File

@@ -5,15 +5,9 @@ namespace: lasuite
resources:
- namespace.yaml
- postfix-deployment.yaml
- hive-config.yaml
- hive-deployment.yaml
- hive-service.yaml
- seaweedfs-buckets.yaml
- shared-config.yaml
- oidc-clients.yaml
- vault-secrets.yaml
- integration-deployment.yaml
- collabora-deployment.yaml
- collabora-service.yaml
- meet-config.yaml
@@ -23,50 +17,3 @@ resources:
- meet-frontend-nginx-configmap.yaml
- meet-frontend-deployment.yaml
- meet-frontend-service.yaml
- drive-frontend-nginx-configmap.yaml
- messages-config.yaml
- messages-backend-deployment.yaml
- messages-backend-service.yaml
- messages-frontend-theme-configmap.yaml
- messages-frontend-deployment.yaml
- messages-frontend-service.yaml
- messages-worker-deployment.yaml
- messages-mta-in-deployment.yaml
- messages-mta-in-service.yaml
- messages-mta-out-deployment.yaml
- messages-mta-out-service.yaml
- messages-mpa-dkim-config.yaml
- messages-mpa-deployment.yaml
- messages-mpa-service.yaml
- messages-socks-proxy-deployment.yaml
- messages-socks-proxy-service.yaml
- calendars-config.yaml
- calendars-theme-configmap.yaml
- calendars-backend-deployment.yaml
- calendars-backend-service.yaml
- calendars-caldav-deployment.yaml
- calendars-caldav-service.yaml
- calendars-worker-deployment.yaml
- calendars-frontend-caddyfile.yaml
- calendars-frontend-deployment.yaml
- calendars-frontend-service.yaml
- projects-config.yaml
- projects-deployment.yaml
patches:
# Mount media auth proxy nginx config in drive-frontend
- path: patch-drive-frontend-nginx.yaml
# Wait for Collabora + run trigger_wopi_configuration on every Drive pod start
- path: patch-drive-wopi-init.yaml
# La Suite Numérique Helm charts.
# Charts with a published Helm repo use helmCharts below.
# find has no published repo yet — deploy manually when OpenSearch is ready.
helmCharts:
# helm repo add drive https://suitenumerique.github.io/drive/
- name: drive
repo: https://suitenumerique.github.io/drive/
version: "0.14.0"
releaseName: drive
namespace: lasuite
valuesFile: drive-values.yaml

View File

@@ -1,183 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-backend
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-backend
template:
metadata:
labels:
app: messages-backend
spec:
initContainers:
- name: migrate
image: messages-backend
command: ["python", "manage.py", "migrate", "--no-input"]
envFrom:
- configMapRef:
name: messages-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-valkey
- configMapRef:
name: lasuite-s3
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: messages-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: SALT_KEY
- name: MDA_API_SECRET
valueFrom:
secretKeyRef:
name: messages-django-secret
key: MDA_API_SECRET
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_SECRET
- name: AWS_S3_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_ACCESS_KEY
- name: AWS_S3_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_SECRET_KEY
- name: RSPAMD_PASSWORD
valueFrom:
secretKeyRef:
name: messages-mpa-credentials
key: RSPAMD_password
- name: OIDC_STORE_REFRESH_TOKEN_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: OIDC_STORE_REFRESH_TOKEN_KEY
- name: OIDC_RP_SCOPES
value: "openid email profile offline_access"
resources:
limits:
memory: 1Gi
cpu: 500m
requests:
memory: 256Mi
cpu: 100m
containers:
- name: messages-backend
image: messages-backend
command:
- gunicorn
- -c
- /app/gunicorn.conf.py
- messages.wsgi:application
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: messages-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-valkey
- configMapRef:
name: lasuite-s3
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: messages-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: SALT_KEY
- name: MDA_API_SECRET
valueFrom:
secretKeyRef:
name: messages-django-secret
key: MDA_API_SECRET
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_SECRET
- name: AWS_S3_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_ACCESS_KEY
- name: AWS_S3_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_SECRET_KEY
- name: RSPAMD_PASSWORD
valueFrom:
secretKeyRef:
name: messages-mpa-credentials
key: RSPAMD_password
- name: OIDC_STORE_REFRESH_TOKEN_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: OIDC_STORE_REFRESH_TOKEN_KEY
- name: OIDC_RP_SCOPES
value: "openid email profile offline_access"
livenessProbe:
httpGet:
path: /__heartbeat__/
port: 8000
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /__heartbeat__/
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
resources:
limits:
memory: 1Gi
cpu: 500m
requests:
memory: 256Mi
cpu: 100m

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-backend
namespace: lasuite
spec:
selector:
app: messages-backend
ports:
- port: 80
targetPort: 8000

View File

@@ -1,45 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: messages-config
namespace: lasuite
data:
DJANGO_CONFIGURATION: Production
DJANGO_SETTINGS_MODULE: messages.settings
DJANGO_ALLOWED_HOSTS: mail.DOMAIN_SUFFIX,messages-backend.lasuite.svc.cluster.local
ALLOWED_HOSTS: mail.DOMAIN_SUFFIX,messages-backend.lasuite.svc.cluster.local
DJANGO_CSRF_TRUSTED_ORIGINS: https://mail.DOMAIN_SUFFIX
DB_NAME: messages_db
DB_USER: messages
OPENSEARCH_URL: http://opensearch.data.svc.cluster.local:9200
MDA_API_BASE_URL: http://messages-backend.lasuite.svc.cluster.local:80/api/v1.0/
MYHOSTNAME: mail.DOMAIN_SUFFIX
# rspamd URL (auth token injected separately from messages-mpa-credentials secret)
SPAM_RSPAMD_URL: http://messages-mpa.lasuite.svc.cluster.local:8010/_api
MESSAGES_FRONTEND_BACKEND_SERVER: messages-backend.lasuite.svc.cluster.local:80
STORAGE_MESSAGE_IMPORTS_BUCKET_NAME: sunbeam-messages-imports
STORAGE_MESSAGE_IMPORTS_ENDPOINT_URL: http://seaweedfs-filer.storage.svc.cluster.local:8333
AWS_STORAGE_BUCKET_NAME: sunbeam-messages
IDENTITY_PROVIDER: oidc
FRONTEND_THEME: default
DRIVE_BASE_URL: https://drive.DOMAIN_SUFFIX
LOGIN_REDIRECT_URL: https://mail.DOMAIN_SUFFIX
LOGOUT_REDIRECT_URL: https://mail.DOMAIN_SUFFIX
OIDC_REDIRECT_ALLOWED_HOSTS: '["https://auth.DOMAIN_SUFFIX"]'
MTA_OUT_MODE: direct
# Create user accounts on first OIDC login (required — no pre-provisioning)
OIDC_CREATE_USER: "True"
# Redirect to home on auth failure (avoids HttpResponseRedirect(None) → /callback/None 404)
LOGIN_REDIRECT_URL_FAILURE: https://mail.DOMAIN_SUFFIX
# Store OIDC tokens in session so the Drive integration can proxy requests on behalf of the user.
OIDC_STORE_ACCESS_TOKEN: "True"
OIDC_STORE_REFRESH_TOKEN: "True"
# Session lives 7 days — long enough to survive overnight/weekend without re-auth.
# Default is 43200 (12h) which forces a login after a browser restart.
SESSION_COOKIE_AGE: "604800"
# Renew the id token 60 s before it expires (access_token TTL = 1h).
# Without this the default falls back to SESSION_COOKIE_AGE (7 days), which means
# every request sees the 1h token as "expiring within 7 days" and triggers a
# prompt=none renewal on every page load — causing repeated auth loops.
OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS: "60"
# offline_access scope is set directly in the deployment env (overrides lasuite-oidc-provider envFrom).

View File

@@ -1,53 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-frontend
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-frontend
template:
metadata:
labels:
app: messages-frontend
spec:
containers:
- name: messages-frontend
image: messages-frontend
ports:
- containerPort: 8080
env:
- name: MESSAGES_FRONTEND_BACKEND_SERVER
value: messages-backend.lasuite.svc.cluster.local:80
- name: PORT
value: "8080"
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 10
periodSeconds: 20
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumeMounts:
- name: theme
mountPath: /app/sunbeam-theme.css
subPath: sunbeam-theme.css
readOnly: true
resources:
limits:
memory: 256Mi
cpu: 250m
requests:
memory: 64Mi
cpu: 50m
volumes:
- name: theme
configMap:
name: messages-frontend-theme

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-frontend
namespace: lasuite
spec:
selector:
app: messages-frontend
ports:
- port: 80
targetPort: 8080

View File

@@ -1,50 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: messages-frontend-theme
namespace: lasuite
data:
sunbeam-theme.css: |
/*
* O Estúdio — runtime brand overrides for messages-frontend.
* Loaded via <link href="/sunbeam-theme.css"> injected in _document.tsx.
* Override Cunningham v4 --c--globals--* variables (no rebuild for updates).
*/
@import url('https://fonts.googleapis.com/css2?family=Ysabeau:ital,wght@0,100..900;1,100..900&display=swap');
:root {
--c--globals--font--families--base: 'Ysabeau Variable', Inter, sans-serif;
--c--globals--font--families--accent: 'Ysabeau Variable', Inter, sans-serif;
/* Brand — amber/gold palette */
--c--globals--colors--brand-050: #fffbeb;
--c--globals--colors--brand-100: #fef3c7;
--c--globals--colors--brand-150: #fde9a0;
--c--globals--colors--brand-200: #fde68a;
--c--globals--colors--brand-250: #fde047;
--c--globals--colors--brand-300: #fcd34d;
--c--globals--colors--brand-350: #fbcf3f;
--c--globals--colors--brand-400: #fbbf24;
--c--globals--colors--brand-450: #f8b31a;
--c--globals--colors--brand-500: #f59e0b;
--c--globals--colors--brand-550: #e8920a;
--c--globals--colors--brand-600: #d97706;
--c--globals--colors--brand-650: #c26d05;
--c--globals--colors--brand-700: #b45309;
--c--globals--colors--brand-750: #9a4508;
--c--globals--colors--brand-800: #92400e;
--c--globals--colors--brand-850: #7c370c;
--c--globals--colors--brand-900: #78350f;
--c--globals--colors--brand-950: #451a03;
/* Logo gradient */
--c--globals--colors--logo-1: #f59e0b;
--c--globals--colors--logo-2: #d97706;
--c--globals--colors--logo-1-light: #f59e0b;
--c--globals--colors--logo-2-light: #d97706;
--c--globals--colors--logo-1-dark: #fcd34d;
--c--globals--colors--logo-2-dark: #fbbf24;
/* PWA theme color */
--sunbeam-brand: #f59e0b;
}

View File

@@ -1,56 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-mpa
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-mpa
template:
metadata:
labels:
app: messages-mpa
spec:
containers:
- name: messages-mpa
image: messages-mpa
ports:
- containerPort: 8010
env:
- name: RSPAMD_password
valueFrom:
secretKeyRef:
name: messages-mpa-credentials
key: RSPAMD_password
- name: PORT
value: "8010"
- name: REDIS_HOST
value: valkey.data.svc.cluster.local
- name: REDIS_PORT
value: "6379"
volumeMounts:
- name: dkim-key
mountPath: /etc/rspamd/dkim
readOnly: true
- name: dkim-signing-conf
mountPath: /etc/rspamd/local.d
readOnly: true
resources:
limits:
memory: 768Mi
cpu: 250m
requests:
memory: 256Mi
cpu: 50m
volumes:
- name: dkim-key
secret:
secretName: messages-dkim-key
items:
- key: dkim-private-key
path: default.sunbeam.pt.key
- name: dkim-signing-conf
configMap:
name: messages-mpa-rspamd-config

View File

@@ -1,13 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: messages-mpa-rspamd-config
namespace: lasuite
data:
dkim_signing.conf: |
enabled = true;
selector = "default";
path = "/etc/rspamd/dkim/$domain.$selector.key";
sign_authenticated = true;
sign_local = true;
use_domain = "header";

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-mpa
namespace: lasuite
spec:
selector:
app: messages-mpa
ports:
- port: 8010
targetPort: 8010

View File

@@ -1,67 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-mta-in
namespace: lasuite
spec:
replicas: 1
# Recreate: hostPort 25 blocks RollingUpdate — the new pod can't
# schedule while the old one still holds the port.
strategy:
type: Recreate
selector:
matchLabels:
app: messages-mta-in
template:
metadata:
labels:
app: messages-mta-in
spec:
containers:
- name: messages-mta-in
image: messages-mta-in
ports:
- containerPort: 25
env:
- name: MDA_API_BASE_URL
valueFrom:
configMapKeyRef:
name: messages-config
key: MDA_API_BASE_URL
- name: MDA_API_SECRET
valueFrom:
secretKeyRef:
name: messages-django-secret
key: MDA_API_SECRET
- name: MAX_INCOMING_EMAIL_SIZE
value: "30000000"
# Liveness: verify the delivery milter process is running and the
# unix socket exists. The milter is a long-lived Python process that
# can hang silently after days of uptime (COE-2026-002 addendum).
# Without this probe, postfix returns 451 to all inbound mail and
# nobody notices until senders complain.
livenessProbe:
exec:
command:
- sh
- -c
- "test -S /var/spool/postfix/milter/delivery.sock && kill -0 $(cat /var/run/milter.pid 2>/dev/null || pgrep -f delivery_milter.py)"
initialDelaySeconds: 15
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 25
initialDelaySeconds: 10
periodSeconds: 15
securityContext:
capabilities:
add: ["NET_BIND_SERVICE"]
resources:
limits:
memory: 256Mi
cpu: 250m
requests:
memory: 64Mi
cpu: 50m

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-mta-in
namespace: lasuite
spec:
selector:
app: messages-mta-in
ports:
- port: 25
targetPort: 25

View File

@@ -1,43 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-mta-out
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-mta-out
template:
metadata:
labels:
app: messages-mta-out
spec:
containers:
- name: messages-mta-out
image: messages-mta-out
ports:
- containerPort: 587
env:
- name: MYHOSTNAME
valueFrom:
configMapKeyRef:
name: messages-config
key: MYHOSTNAME
- name: SMTP_USERNAME
valueFrom:
secretKeyRef:
name: messages-mta-out-credentials
key: SMTP_USERNAME
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: messages-mta-out-credentials
key: SMTP_PASSWORD
resources:
limits:
memory: 256Mi
cpu: 250m
requests:
memory: 64Mi
cpu: 50m

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-mta-out
namespace: lasuite
spec:
selector:
app: messages-mta-out
ports:
- port: 587
targetPort: 587

View File

@@ -1,35 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-socks-proxy
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-socks-proxy
template:
metadata:
labels:
app: messages-socks-proxy
spec:
containers:
- name: messages-socks-proxy
image: messages-socks-proxy
ports:
- containerPort: 1080
env:
- name: PROXY_USERS
valueFrom:
secretKeyRef:
name: messages-socks-credentials
key: PROXY_USERS
- name: PROXY_SOURCE_IP_WHITELIST
value: 10.0.0.0/8
resources:
limits:
memory: 128Mi
cpu: 100m
requests:
memory: 32Mi
cpu: 25m

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: messages-socks-proxy
namespace: lasuite
spec:
selector:
app: messages-socks-proxy
ports:
- port: 1080
targetPort: 1080

View File

@@ -1,90 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-worker
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: messages-worker
template:
metadata:
labels:
app: messages-worker
spec:
containers:
- name: messages-worker
image: messages-backend
command: ["python", "worker.py", "--loglevel=INFO", "--concurrency=3"]
envFrom:
- configMapRef:
name: messages-config
- configMapRef:
name: lasuite-postgres
- configMapRef:
name: lasuite-valkey
- configMapRef:
name: lasuite-s3
- configMapRef:
name: lasuite-oidc-provider
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: messages-db-credentials
key: password
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: DJANGO_SECRET_KEY
- name: SALT_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: SALT_KEY
- name: MDA_API_SECRET
valueFrom:
secretKeyRef:
name: messages-django-secret
key: MDA_API_SECRET
- name: OIDC_RP_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_ID
- name: OIDC_RP_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-messages
key: CLIENT_SECRET
- name: AWS_S3_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_ACCESS_KEY
- name: AWS_S3_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_SECRET_KEY
- name: RSPAMD_PASSWORD
valueFrom:
secretKeyRef:
name: messages-mpa-credentials
key: RSPAMD_password
- name: OIDC_STORE_REFRESH_TOKEN_KEY
valueFrom:
secretKeyRef:
name: messages-django-secret
key: OIDC_STORE_REFRESH_TOKEN_KEY
- name: OIDC_RP_SCOPES
value: "openid email profile offline_access"
resources:
limits:
memory: 1Gi
cpu: "1"
requests:
memory: 256Mi
cpu: 100m

View File

@@ -1,20 +0,0 @@
# Patch: mount the nginx ConfigMap into drive-frontend to enable the media
# auth_request proxy (validates Drive session before serving S3 files).
apiVersion: apps/v1
kind: Deployment
metadata:
name: drive-frontend
namespace: lasuite
spec:
template:
spec:
containers:
- name: drive
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
volumes:
- name: nginx-conf
configMap:
name: drive-frontend-nginx-conf

View File

@@ -1,89 +0,0 @@
# Init container that waits for Collabora and configures WOPI on every pod start.
#
# The Drive chart's configure_wopi Job is designed for ArgoCD PostSync hooks
# and only runs on `sunbeam apply`. On server restart, no one re-triggers it,
# so WOPI editing silently breaks. This init container fixes that — every time
# a Drive backend pod starts (restart, rollout, scale-up), it waits for
# Collabora and runs trigger_wopi_configuration before the main container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: drive-backend
namespace: lasuite
spec:
template:
spec:
initContainers:
- name: configure-wopi
image: lasuite/drive-backend:latest
command:
- "/bin/sh"
- "-c"
- |
echo "Waiting for Collabora..."
for i in $(seq 1 36); do
if wget -qO /dev/null --timeout=5 http://collabora.lasuite.svc.cluster.local:9980/hosting/discovery 2>/dev/null; then
echo "Collabora ready — configuring WOPI..."
python manage.py trigger_wopi_configuration
exit $?
fi
echo "Attempt $i/36: not ready, retrying in 5s..."
sleep 5
done
echo "WARN: Collabora not ready after 3 minutes — starting without WOPI"
exit 0
env:
# Database — minimum needed for Django manage.py
- name: DB_ENGINE
value: django.db.backends.postgresql
- name: DB_NAME
value: drive_db
- name: DB_USER
value: drive
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: lasuite-postgres
key: DB_PORT
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: drive-db-credentials
key: password
# Django
- name: DJANGO_CONFIGURATION
value: Production
- name: DJANGO_SECRET_KEY
valueFrom:
secretKeyRef:
name: drive-django-secret
key: DJANGO_SECRET_KEY
# Redis/Celery — trigger_wopi_configuration dispatches a Celery task
- name: REDIS_URL
valueFrom:
configMapKeyRef:
name: lasuite-valkey
key: REDIS_URL
- name: DJANGO_CELERY_BROKER_URL
valueFrom:
configMapKeyRef:
name: lasuite-valkey
key: CELERY_BROKER_URL
# WOPI
- name: WOPI_CLIENTS
value: collabora
- name: WOPI_COLLABORA_DISCOVERY_URL
value: http://collabora.lasuite.svc.cluster.local:9980/hosting/discovery
- name: WOPI_SRC_BASE_URL
value: https://drive.DOMAIN_SUFFIX
resources:
limits:
memory: 128Mi
requests:
memory: 64Mi
cpu: 25m

View File

@@ -1,81 +0,0 @@
# Postfix MTA for the Messages email platform.
#
# MTA-out: accepts SMTP from cluster-internal services (Kratos, Messages Django),
# signs with DKIM, and relays outbound via Scaleway TEM.
#
# MTA-in: receives inbound email from the internet (routed via Pingora on port 25).
# In local dev, no MX record points here so inbound never arrives.
#
# Credentials: Secret "postfix-tem-credentials" with keys:
# smtp_user — Scaleway TEM SMTP username (project ID)
# smtp_password — Scaleway TEM SMTP password (API key)
#
# DKIM keys: Secret "postfix-dkim" with key:
# private.key — DKIM private key for sunbeam.pt (generated once; add DNS TXT record)
# selector — DKIM selector (e.g. "mail")
#
apiVersion: apps/v1
kind: Deployment
metadata:
name: postfix
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: postfix
template:
metadata:
labels:
app: postfix
spec:
automountServiceAccountToken: false
containers:
- name: postfix
image: boky/postfix:latest
ports:
- name: smtp
containerPort: 25
protocol: TCP
env:
# Accept mail from all cluster-internal pods.
- name: MYNETWORKS
value: "10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 127.0.0.0/8"
# Sending domain — replaced by sed at deploy time.
- name: ALLOWED_SENDER_DOMAINS
value: "DOMAIN_SUFFIX"
# Scaleway TEM outbound relay.
- name: RELAYHOST
value: "[smtp.tem.scw.cloud]:587"
- name: SASL_USER
valueFrom:
secretKeyRef:
name: postfix-tem-credentials
key: smtp_user
optional: true # allows pod to start before secret exists
- name: SASL_PASSWORD
valueFrom:
secretKeyRef:
name: postfix-tem-credentials
key: smtp_password
optional: true
resources:
limits:
memory: 64Mi
requests:
memory: 32Mi
cpu: 10m
---
apiVersion: v1
kind: Service
metadata:
name: postfix
namespace: lasuite
spec:
selector:
app: postfix
ports:
- name: smtp
port: 25
targetPort: 25
protocol: TCP

View File

@@ -1,44 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: projects-config
namespace: lasuite
data:
BASE_URL: "https://projects.DOMAIN_SUFFIX"
TRUST_PROXY: "1"
NODE_ENV: "production"
# OIDC — Hydra as the identity provider
OIDC_ISSUER: "https://auth.DOMAIN_SUFFIX/"
OIDC_SCOPES: "openid email profile"
OIDC_ENFORCED: "true"
OIDC_IGNORE_USERNAME: "true"
OIDC_IGNORE_ROLES: "true"
OIDC_ADMIN_ROLES: "*"
OIDC_FULLNAME_ATTRIBUTES: "given_name,family_name"
# Planka defaults to response_mode=fragment, which returns the auth code in the
# URL hash (#code=...). The SPA callback handler doesn't parse fragments correctly,
# causing a silent auth loop. Use query mode so the code comes as ?code=...
OIDC_RESPONSE_MODE: "query"
# S3 file storage via SeaweedFS
S3_ENDPOINT: "http://seaweedfs-filer.storage.svc.cluster.local:8333"
S3_BUCKET: "projects"
S3_REGION: "us-east-1"
S3_FORCE_PATH_STYLE: "true"
# SMTP via in-cluster Postfix relay
SMTP_HOST: "postfix.lasuite.svc.cluster.local"
SMTP_PORT: "25"
SMTP_SECURE: "false"
SMTP_FROM: "Projects <noreply@DOMAIN_SUFFIX>"
# La Gaufre waffle menu widget
REACT_APP_LAGAUFRE_WIDGET_API_URL: "https://integration.DOMAIN_SUFFIX/api/v2/services.json"
REACT_APP_LAGAUFRE_WIDGET_PATH: "https://integration.DOMAIN_SUFFIX/api/v2/"
# Default language for new OIDC users (browser detection fallback if unset)
DEFAULT_LANGUAGE: "en-US"
# Permissions
ALLOW_ALL_TO_CREATE_PROJECTS: "true"

View File

@@ -1,121 +0,0 @@
# Planka-based Kanban project management — single container (SPA bundled into Sails backend).
# Image: src.DOMAIN_SUFFIX/studio/projects:latest
# Built from projects/Dockerfile
#
# Secrets injected via env vars:
# - projects-db-url (VaultDynamicSecret): DATABASE_URL
# - projects-app-secrets (VaultStaticSecret): SECRET_KEY
# - oidc-projects (Hydra Maester): CLIENT_ID, CLIENT_SECRET
# - seaweedfs-s3-credentials (VaultStaticSecret): S3_ACCESS_KEY, S3_SECRET_KEY
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: projects
namespace: lasuite
spec:
replicas: 1
selector:
matchLabels:
app: projects
template:
metadata:
labels:
app: projects
spec:
initContainers:
- name: db-migrate
image: projects
command: ["node", "db/init.js"]
envFrom:
- configMapRef:
name: projects-config
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: projects-db-url
key: url
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: projects-app-secrets
key: SECRET_KEY
resources:
limits:
memory: 256Mi
requests:
memory: 128Mi
cpu: 50m
containers:
- name: projects
image: projects
command: ["node", "app.js", "--prod"]
ports:
- name: http
containerPort: 1337
envFrom:
- configMapRef:
name: projects-config
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: projects-db-url
key: url
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: projects-app-secrets
key: SECRET_KEY
- name: OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: oidc-projects
key: CLIENT_ID
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oidc-projects
key: CLIENT_SECRET
- name: S3_ACCESS_KEY
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_ACCESS_KEY
- name: S3_SECRET_KEY
valueFrom:
secretKeyRef:
name: seaweedfs-s3-credentials
key: S3_SECRET_KEY
resources:
limits:
memory: 512Mi
requests:
memory: 256Mi
cpu: 50m
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 30
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: projects
namespace: lasuite
spec:
selector:
app: projects
ports:
- name: http
port: 80
targetPort: 1337

View File

@@ -1,45 +0,0 @@
apiVersion: batch/v1
kind: Job
metadata:
name: seaweedfs-bucket-init
namespace: lasuite
annotations:
# Run once on first deploy; manually delete to re-run if needed.
helm.sh/hook: post-install
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: mc
image: minio/mc:latest
command:
- /bin/sh
- -c
- |
set -e
ENDPOINT=http://seaweedfs-filer.storage.svc.cluster.local:8333
mc alias set weed "$ENDPOINT" "$S3_ACCESS_KEY" "$S3_SECRET_KEY"
for bucket in \
sunbeam-meet \
sunbeam-drive \
sunbeam-messages \
sunbeam-messages-imports \
sunbeam-conversations \
sunbeam-git-lfs \
sunbeam-game-assets \
sunbeam-ml-models \
sunbeam-stalwart \
sunbeam-sccache; do
mc mb --ignore-existing "weed/$bucket"
echo "Ensured bucket: $bucket"
done
# Enable object versioning on buckets that require it.
# Drive's WOPI GetFile response includes X-WOPI-ItemVersion from S3 VersionId.
# SeaweedFS doesn't support `mc versioning` — use the S3 API directly.
mc versioning enable weed/sunbeam-drive || echo "Versioning not supported by SeaweedFS mc, skipping (filer handles versioning natively)"
envFrom:
- secretRef:
name: seaweedfs-s3-credentials

View File

@@ -1,85 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Local dev overlay — targets Lima VM running k3s on macOS
# Deploy with: kubectl apply -k overlays/local/
#
# NOTE: base/mesh (Linkerd) is excluded here. Linkerd is bootstrapped
# separately by scripts/local-up.sh via the Linkerd CLI, which avoids
# the identity cert bootstrapping problem at kustomize render time.
#
# DOMAIN_SUFFIX substitution: local-up.sh pipes `kustomize build | sed` to
# replace DOMAIN_SUFFIX with <LIMA_IP>.sslip.io before kubectl apply.
resources:
- ../../base/build
- ../../base/ingress
- ../../base/ory
- ../../base/data
- ../../base/storage
- ../../base/lasuite
- ../../base/media
- ../../base/devtools
- ../../base/stalwart
- ../../base/vso
images:
# La Gaufre v2 integration service — lagaufre.js widget + SVG logos + nginx
- name: integration
newName: src.DOMAIN_SUFFIX/studio/integration
newTag: latest
# amd64-only La Suite images — mirrored to our Gitea registry with a patched
# OCI index that adds an arm64 alias so Rosetta can run them on the Lima VM.
# DOMAIN_SUFFIX is substituted by local-up.py at deploy time (sed replacement).
# Meet — built from source and pushed to Gitea registry.
- name: meet-backend
newName: src.DOMAIN_SUFFIX/studio/meet-backend
newTag: latest
- name: meet-frontend
newName: src.DOMAIN_SUFFIX/studio/meet-frontend
newTag: latest
# Projects (Kanban) — built and pushed by `sunbeam build projects`
- name: projects
newName: src.DOMAIN_SUFFIX/studio/projects
newTag: latest
# Calendars — built from source and pushed to Gitea registry.
- name: calendars-backend
newName: src.DOMAIN_SUFFIX/studio/calendars-backend
newTag: latest
- name: calendars-caldav
newName: src.DOMAIN_SUFFIX/studio/calendars-caldav
newTag: latest
- name: calendars-frontend
newName: src.DOMAIN_SUFFIX/studio/calendars-frontend
newTag: latest
patches:
# Disable SSL verification for OIDC server-side calls — mkcert CA not trusted in pods
- path: patch-oidc-verify-ssl.yaml
target:
kind: ConfigMap
name: lasuite-oidc-provider
# Add hostPort for TURN relay range + bind :80/:443 on Lima VM
- path: values-pingora.yaml
target:
kind: Deployment
name: pingora
# Downgrade LiveKit TURN service from LoadBalancer → ClusterIP (klipper would take hostPort 443)
- path: values-livekit.yaml
target:
kind: Service
name: livekit-server-turn
# Set SSL_CERT_FILE so Gitea's Go TLS trusts the mkcert wildcard CA for OIDC calls
- path: patch-gitea-mkcert-ca.yaml
target:
kind: Deployment
name: gitea
# Apply §10.7 memory limits to all Deployments
- path: values-resources.yaml

View File

@@ -1,13 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: devtools
spec:
template:
spec:
containers:
- name: gitea
env:
- name: SSL_CERT_FILE
value: /run/ca/ca.crt

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: lasuite-oidc-provider
namespace: lasuite
data:
OIDC_VERIFY_SSL: "false"

View File

@@ -1,21 +0,0 @@
# Patch: replace DOMAIN_SUFFIX placeholder with <LIMA_IP>.sslip.io
# in the Pingora ConfigMap's routing table.
#
# How to apply: the local-up.sh script calls:
# LIMA_IP=$(limactl shell sunbeam hostname -I | awk '{print $1}')
# sed "s/DOMAIN_SUFFIX/${LIMA_IP}.sslip.io/g" overlays/local/values-domain.yaml | kubectl apply -f -
#
# Or use kustomize's replacements feature if the IP is known at kustomize time.
#
# This is a strategic merge patch on the pingora-config ConfigMap.
apiVersion: v1
kind: ConfigMap
metadata:
name: pingora-config
namespace: ingress
data:
# DOMAIN_SUFFIX is substituted at deploy time by local-up.sh.
# The local overlay domain is: <LIMA_IP>.sslip.io
# Example: 192.168.5.2.sslip.io
domain-suffix: "LIMA_IP.sslip.io"

View File

@@ -1,10 +0,0 @@
# Local override: change LiveKit TURN service type from LoadBalancer to ClusterIP.
# k3s klipper-lb would otherwise bind hostPort 443, conflicting with Pingora.
# External TURN on port 443 is not needed in local dev (no NAT traversal required).
apiVersion: v1
kind: Service
metadata:
name: livekit-server-turn
namespace: media
spec:
type: ClusterIP

View File

@@ -1,37 +0,0 @@
# Patch: local Pingora overrides
# - ACME disabled (mkcert wildcard cert from pingora-tls Secret)
# - hostPort for TURN relay range on the Lima VM
apiVersion: apps/v1
kind: Deployment
metadata:
name: pingora
namespace: ingress
spec:
template:
spec:
containers:
- name: pingora
imagePullPolicy: IfNotPresent
ports:
# Bind HTTP/HTTPS directly to the Lima VM's host network
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
- name: https
containerPort: 443
hostPort: 443
protocol: TCP
# Expose full TURN relay range as hostPort so the Lima VM forwards UDP
- name: turn-start
containerPort: 49152
hostPort: 49152
protocol: UDP
- name: turn-end
containerPort: 49252
hostPort: 49252
protocol: UDP
# acme.enabled = false is the default in pingora-config.yaml.
# The mkcert cert Secret (pingora-tls) is created by scripts/local-certs.sh
# before kustomize runs, so it is always present on first apply.

View File

@@ -1,188 +0,0 @@
# Patch: apply §10.7 memory limits to all Deployments in the local overlay.
# These are intentionally tight to stay within the 12 GB Lima VM budget.
#
# Applied as a strategic merge patch. Each stanza targets one Deployment by name.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloudnative-pg
namespace: data
spec:
template:
spec:
containers:
- name: manager
resources:
limits:
memory: 256Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: livekit-server
namespace: media
spec:
template:
spec:
containers:
- name: livekit-server
resources:
limits:
memory: 128Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pingora
namespace: ingress
spec:
template:
spec:
containers:
- name: pingora
resources:
limits:
memory: 128Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: valkey
namespace: data
spec:
template:
spec:
containers:
- name: valkey
resources:
limits:
memory: 64Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: opensearch
namespace: data
spec:
template:
spec:
containers:
- name: opensearch
env:
# Reduce JVM heap so it fits within the 512Mi container limit.
# Base sets -Xms512m -Xmx1g which immediately OOMs the container.
- name: OPENSEARCH_JAVA_OPTS
value: "-Xms192m -Xmx256m"
resources:
limits:
memory: 512Mi
requests:
memory: 256Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: seaweedfs-filer
namespace: storage
spec:
template:
spec:
containers:
- name: filer
resources:
limits:
memory: 512Mi
requests:
memory: 128Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hydra-hydra-maester
namespace: ory
spec:
template:
spec:
containers:
- name: hydra-maester
resources:
limits:
memory: 64Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: login-ui
namespace: ory
spec:
template:
spec:
containers:
- name: login-ui
resources:
limits:
memory: 192Mi
requests:
memory: 64Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hive
namespace: lasuite
spec:
template:
spec:
containers:
- name: hive
resources:
limits:
memory: 64Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: collabora
namespace: lasuite
spec:
template:
spec:
containers:
- name: collabora
resources:
limits:
memory: 512Mi
cpu: 500m
requests:
memory: 256Mi
cpu: 50m
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: buildkitd
namespace: build
spec:
template:
spec:
containers:
- name: buildkitd
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "2"
memory: "2Gi"

View File

@@ -27,11 +27,6 @@ resources:
- postgres-scheduled-backup.yaml
images:
# La Gaufre integration service — built and pushed by `sunbeam build integration`
- name: integration
newName: src.DOMAIN_SUFFIX/studio/integration
newTag: latest
# Meet — built from source and pushed to Gitea registry.
- name: meet-backend
newName: src.DOMAIN_SUFFIX/studio/meet-backend
@@ -40,42 +35,6 @@ images:
newName: src.DOMAIN_SUFFIX/studio/meet-frontend
newTag: latest
# Messages — built from source and pushed to Gitea registry.
- name: messages-backend
newName: src.DOMAIN_SUFFIX/studio/messages-backend
newTag: latest
- name: messages-frontend
newName: src.DOMAIN_SUFFIX/studio/messages-frontend
newTag: latest
- name: messages-mta-in
newName: src.DOMAIN_SUFFIX/studio/messages-mta-in
newTag: latest
- name: messages-mta-out
newName: src.DOMAIN_SUFFIX/studio/messages-mta-out
newTag: latest
- name: messages-mpa
newName: src.DOMAIN_SUFFIX/studio/messages-mpa
newTag: latest
- name: messages-socks-proxy
newName: src.DOMAIN_SUFFIX/studio/messages-socks-proxy
newTag: latest
# Calendars — built from source and pushed to Gitea registry.
- name: calendars-backend
newName: src.DOMAIN_SUFFIX/studio/calendars-backend
newTag: latest
- name: calendars-caldav
newName: src.DOMAIN_SUFFIX/studio/calendars-caldav
newTag: latest
- name: calendars-frontend
newName: src.DOMAIN_SUFFIX/studio/calendars-frontend
newTag: latest
# Projects (Kanban) — built and pushed by `sunbeam build projects`
- name: projects
newName: src.DOMAIN_SUFFIX/studio/projects
newTag: latest
# Tuwunel Matrix homeserver — built and pushed by `sunbeam build tuwunel`
- name: tuwunel
newName: src.DOMAIN_SUFFIX/studio/tuwunel

View File

@@ -1,15 +0,0 @@
# Bind MTA-in port 25 to the host so inbound email reaches the pod directly.
apiVersion: apps/v1
kind: Deployment
metadata:
name: messages-mta-in
namespace: lasuite
spec:
template:
spec:
containers:
- name: messages-mta-in
ports:
- containerPort: 25
hostPort: 25
protocol: TCP

View File

@@ -149,23 +149,6 @@ spec:
limits:
memory: 128Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hive
namespace: lasuite
spec:
template:
spec:
containers:
- name: hive
resources:
requests:
memory: 64Mi
limits:
memory: 256Mi
---
apiVersion: apps/v1
kind: Deployment