The great reset, we moved infra into two clusters (sekibanki et seija)

This commit is contained in:
2025-07-16 10:39:09 -04:00
parent 68f1108c2d
commit 1df5459f70
145 changed files with 2431 additions and 576 deletions

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: etherpad-config
data:
TITLE: "🌻 Etherpad"
DEFAULT_PAD_TEXT: "Welcome to Etherpad! This pad text is provided by the prettysunflower collective, and is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents! Get involved with Etherpad at https://etherpad.org"
DB_TYPE: "postgres"
DB_HOST: "100.110.40.2"
DB_PORT: "5432"
TRUST_PROXY: "true"
AUTOMATIC_RECONNECTION_TIMEOUT: "5"

View File

@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: etherpad
labels:
app.kubernetes.io/name: etherpad
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: etherpad
template:
metadata:
labels:
app.kubernetes.io/name: etherpad
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: location
operator: In
values:
- fsn
containers:
- name: etherpad
image: etherpad/etherpad:2.3.2
ports:
- containerPort: 9001
name: http
envFrom:
- configMapRef:
name: etherpad-config
- secretRef:
name: etherpad-secrets
volumeMounts:
- name: etherpad-images
mountPath: /opt/etherpad-lite/src/static/skins/colibris/images
dnsPolicy: "None"
dnsConfig:
nameservers:
- 100.96.226.96
volumes:
- name: etherpad-images
persistentVolumeClaim:
claimName: etherpad-images-pvc

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

View File

@@ -0,0 +1,6 @@
resources:
- deployment.yaml
- configmap.yaml
- secrets.yaml
- svc.yaml
- pvc.yaml

View File

@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: etherpad-images-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 256M
storageClassName: nfs-csi

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Secret
metadata:
name: etherpad-secrets
type: Opaque
stringData:
DB_USER: ENC[AES256_GCM,data:8ewltKeF4XE=,iv:VEzUayqbRUGl3aPpIic56MLVaYymw9Rf/OUjdOsnlWk=,tag:w2BtxnVBVtQopPNxRr+rRQ==,type:str]
DB_PASS: ENC[AES256_GCM,data:/dppdINLe4fiEdyjbeE=,iv:5iO79O+81CV1UROtDPuoupd1HIk9x14RQ981ZdEe/GM=,tag:EQ/9Ugs/UGQur1+RvmVluw==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzWGM5T1VTUkdZanNNRTR3
bkprOEYzTGorSDh4a1Y3dytJT3p0QlBtQW1nCkdsVUEzUWxVckpiZjRkUHFpSFRM
bXFUNnk0TEFuYmd6WUdRM0swWE5FYlUKLS0tIFJlTmxkaXdJM1ZDeDd2ejB2czVw
SzYvV1RmYXpzdnZBU1RYaS9NYlAxaFkKEbbTjI6c2cr/NqGA4rZEmSpeVni1R1KP
7CPrKpPiV96vnG9NM37L2lpwZvig5H3JUtPdRzSdpJJDoQbBeAvpYg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:UPl5mlWdtTyXl6W+QINngFrMIPpMdOrnRPCREsFuMJqcU0Qb2udIBImZIeYdURXd/ymRr3hwC0E6bzRbQJBUEJpd9oWzOTv/IIsvdptnjuKjZz7Ojnpfrmd8FO8YuSnR9x/qHC4B05E14GPrOKHJIOuKrAv40ATSwrAl2PFdoTo=,iv:meWIlngiKEWHoivsDv4AUFOEJY4w75zuL9lVtv9VW2E=,tag:HpHKDB5Ux57YM5yeGgx4og==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: etherpad
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: etherpad
ports:
- protocol: TCP
port: 80
targetPort: http

View File

@@ -0,0 +1,64 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: gitea-config
data:
GITEA__DEFAULT__RUN_USER: git
GITEA__DEFAULT__RUN_MODE: prod
GITEA__DEFAULT__APP_NAME: prettysunflower's gitea
GITEA__DEFAULT__WORK_PATH: /var/lib/gitea
GITEA__repository__ROOT: /var/lib/gitea/git
GITEA__repository__SCRIPT_TYPE: sh
GITEA__repository__DISABLE_STARS: "true"
GITEA__server__STATIC_ROOT_PATH: /usr/share/webapps/gitea
GITEA__server__APP_DATA_PATH: /var/lib/gitea/data
GITEA__server__LFS_START_SERVER: "true"
GITEA__server__SSH_DOMAIN: git.default.svc.sekibanki.prettysunflower.moe
GITEA__server__DOMAIN: git.prettysunflower.moe
GITEA__server__HTTP_PORT: "3000"
GITEA__server__ROOT_URL: https://git.prettysunflower.moe/
GITEA__server__DISABLE_SSH: "false"
GITEA__server__SSH_PORT: "22"
GITEA__server__OFFLINE_MODE: "false"
GITEA__server__PUBLIC_URL_DETECTION: auto
GITEA__database__DB_TYPE: postgres
GITEA__database__SSL_MODE: disable
GITEA__database__HOST: 100.110.40.2:5432
GITEA__database__NAME: gitea
GITEA__database__SCHEMA: public
GITEA__database__LOG_SQL: "false"
GITEA__session__PROVIDER: redis
GITEA__log__MODE: console
GITEA__log__LEVEL: info
GITEA__mailer__ENABLED: "true"
GITEA__mailer__FROM: gitea@prettysunflower.moe
GITEA__mailer__PROTOCOL: smtp+starttls
GITEA__mailer__SMTP_ADDR: mail.prettysunflower.moe
GITEA__mailer__SMTP_PORT: "587"
GITEA__storage__STORAGE_TYPE: minio
GITEA__storage__MINIO_ENDPOINT: t3.storage.dev:443
GITEA__storage__MINIO_ACCESS_KEY_ID: tid_uCZAvxLOlpVdEusuMYvVmsOvMgVccrwxGJwqauuhSucI_MwddN
GITEA__storage__MINIO_BUCKET: prettysunflower-gitea
GITEA__storage__MINIO_LOCATION: auto
GITEA__storage__MINIO_USE_SSL : "true"
GITEA__storage__SERVE_DIRECT: "true"
GITEA__service__REGISTER_EMAIL_CONFIRM: "false"
GITEA__service__ENABLE_NOTIFY_MAIL: "false"
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "false"
GITEA__service__ENABLE_CAPTCHA: "false"
GITEA__service__REQUIRE_SIGNIN_VIEW: "false"
GITEA__service__DEFAULT_KEEP_EMAIL_PRIVATE: "false"
GITEA__service__DEFAULT_ALLOW_CREATE_ORGANIZATION: "true"
GITEA__service__DEFAULT_ENABLE_TIMETRACKING: "true"
GITEA__service__NO_REPLY_ADDRESS: noreply.localhost
GITEA__openid__ENABLE_OPENID_SIGNIN: "true"
GITEA__openid__ENABLE_OPENID_SIGNUP: "true"
GITEA__cron_0X2E_update_checker__ENABLED: "false"
GITEA__repository_0X2E_pull_0X2D_request__DEFAULT_MERGE_STYLE: merge
GITEA__repository_0X2E_signing__DEFAULT_TRUST_MODEL: committer
GITEA__security__INSTALL_LOCK: "true"
GITEA__security__PASSWORD_HASH_ALGO: argon2
GITEA__cache__ADAPTER: redis
GITEA__cache__HOST: redis://127.0.0.1:6379/0
GITEA__cache_0X2E_last_commit__COMMITS_COUNT: "1"

View File

@@ -0,0 +1,92 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
labels:
app.kubernetes.io/name: gitea
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: gitea
template:
metadata:
labels:
app.kubernetes.io/name: gitea
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-pvc
- name: config
persistentVolumeClaim:
claimName: gitea-config-pvc
- name: valkey
emptyDir:
sizeLimit: 128Mi
medium: Memory
dnsPolicy: "None"
dnsConfig:
nameservers:
- 100.96.226.96
containers:
- image: docker.gitea.com/gitea:1.24.3-rootless
name: gitea
ports:
- containerPort: 3000
protocol: TCP
name: http
- containerPort: 2222
protocol: TCP
name: ssh
volumeMounts:
- name: data
mountPath: /var/lib/gitea
- name: config
mountPath: /etc/gitea
envFrom:
- configMapRef:
name: gitea-config
- secretRef:
name: gitea-secrets
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
livenessProbe:
httpGet:
path: /api/healthz
port: http
initialDelaySeconds: 200
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 10
- image: valkey/valkey:alpine
name: valkey
command: ["valkey-server"]
ports:
- containerPort: 6379
protocol: TCP
env:
- name: VALKEY_EXTRA_FLAGS
value: "--save 60 1"
volumeMounts:
- name: valkey
mountPath: "/data"
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,6 @@
resources:
- deployment.yaml
- pvc.yaml
- svc.yaml
- secrets.yaml
- configmap.yaml

View File

@@ -0,0 +1,24 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50G
storageClassName: nfs-csi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-config-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 64M
storageClassName: nfs-csi

View File

@@ -0,0 +1,30 @@
apiVersion: v1
kind: Secret
metadata:
name: gitea-secrets
type: Opaque
stringData:
GITEA__server__LFS_JWT_SECRET: ENC[AES256_GCM,data:lUGklHzgVyGtW7YWHqQlOEs9TlcKrAp+wOHKmvrnUx7g9NzrUOarqVwwqg==,iv:Fyr5WFaFps60Sc735FkcdaTUfP4Rf++3ZGFC8/x/beI=,tag:D11RCpU8j1YkqJnJghzbPw==,type:str]
GITEA__database__USER: ENC[AES256_GCM,data:J1WUgvw=,iv:f/PIxtSVYJD0M6oQATy/cCcLqBska2KbqJu0LOdgCnQ=,tag:6J1NjGpVEKQY+eII5aM2kQ==,type:str]
GITEA__database__PASSWD: ENC[AES256_GCM,data:MDsAOxL3BDmZD2s8NPE=,iv:nbs4k3kqZbJXW3ptyQy04M8ZehxXzzRiaJpCFbmeGXA=,tag:+EXlilcYXFdU1flRV+Y+nw==,type:str]
GITEA__mailer__USER: ENC[AES256_GCM,data:h3aLMQygmPalb53QGe4KP2DvQxpUaw==,iv:nsTin6xBu6aGEfElOULW7ScdvMUNoM5fbX3x+WSpwgc=,tag:w8Nvm/XOBQqDHdRBgmDc4w==,type:str]
GITEA__mailer__PASSWD: ENC[AES256_GCM,data:aDuDhi8miweNKBYV2N7p5Q==,iv:WPur5yPGtKOUPQ+17MfihHljinBAKgpFTnXPW/HGuO4=,tag:fEAUy5bfxwIFEUs5oYljtQ==,type:str]
GITEA__storage__MINIO_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:gDC9Xk6k01sar/AdG6FA7topLA1yzBklpXB3v11u7PseRXKtxSzbjg3yRSxDKfS7dz0uuChTx/Fj4yR3+MZSKMR+Av1UU9dA0koS,iv:lMvi+NCmeZZz7AtVhFJpM1qjweGf9tNmA0pXSJdsdL0=,tag:NbCmn20JTrYSzmbc2kgnBQ==,type:str]
GITEA__security__INTERNAL_TOKEN: ENC[AES256_GCM,data:LBD8u8OsXhkO69XSvhfP0vDCeZRfY+Yc1nKfaacCF2QL/T6v2054ymbvGjTvR+DM5g+XezwZWLYrE+AfY5LEa35EpC4S2c7kQAGikyBvGo9ANAcP6NxfC6ShraUBnGg5njrjf4ZVBGrd,iv:xH5amSwdV5e4rqneqr/x62hCdOWnjoPHFA30LwM3260=,tag:LhK1heV4xe3qUXwZ+pgfwg==,type:str]
GITEA__security__SECRET_KEY: ENC[AES256_GCM,data:mRdk8gS0wrV6PYr9jiSwvZAql4SyUjXEc0UNLdZMV3FOZsRKPHVWAsiw443HwPZ8pyBH6ucNHj1Zdj9qTMonHg==,iv:k8EIL2n+EGT+Fz0wTP4u+Tczyv2la478x0oV/jAHa/o=,tag:0gfQNJ3YQ6EK5WAPfzd6dg==,type:str]
GITEA__oauth2__JWT_SECRET: ENC[AES256_GCM,data:JoU3xarzXINK1Vs0slgtdVYGG9ilTENLzt2ggT69zFoQppQKt2lZUmqw5g==,iv:nAd74z6iMwpYN++0FQ8Ow3cg03sYBrV6790NiV4y2lk=,tag:KAvL0ugsZDzRfhpdoqzo/A==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArUU5vdTVaS2t6OXpwaUEx
cUNTWFpUbkVmYStHT1VBRXBJWCsvZllzQWwwClZZV01aSFRaamI2VzR5SGNvR0ZE
VUQyU3hPVUZUY2dHT1NSMzdGdHVSeHMKLS0tIHRBRlVzRWR4b2tXb3o5UmxPdjNt
YXRHQkdHek1DTkM5WjhRenBaLzRxdEUKBypMt0YqbWUgzmcMgfWjEXDICOstdYya
sGqjC1GYuaffqCrpWScDq5ok/QXznbye3yEJwzV1opwbhKPrWmOgqQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:0N1JMKyxhHKsQ/Q5A9uCCAo+E5tvbhA75wJiVAX1fSRtPIfaJ7T6LdP7MLLxNXQTcl+LqcHn+XvIfU7z5XeZmH/qBZZEldgwj8CbEhPKjw3+kThoNWHV5nggxlIyFePE18bo/lpRV8Bqpyhocdd0F1fEDNEotnaO5Nle7SWAcWo=,iv:qWEv7WVf2v7aIr19S7OE/Q4Fu13FZ7hVF+bAdlZZv1s=,tag:/rzDd4uheETv+WugfaizEw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: git
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: gitea
ports:
- protocol: TCP
port: 22
targetPort: ssh
name: ssh
- protocol: TCP
port: 80
targetPort: http
name: http

View File

@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: glance
labels:
app.kubernetes.io/name: glance
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: glance
template:
metadata:
labels:
app.kubernetes.io/name: glance
spec:
volumes:
- name: config
configMap:
name: glance-config
containers:
- image: glanceapp/glance:v0.8.4
name: glance
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
volumeMounts:
- name: config
mountPath: /app/config
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,145 @@
pages:
- name: Home
columns:
- size: small
widgets:
- type: calendar
- type: rss
limit: 10
collapse-after: 3
cache: 30m
feeds:
- url: https://piranhaplant1.blogspot.com/feeds/posts/default
- url: https://www.nekomagic.com/feed/
- url: https://soatok.blog/feed
- url: http://feeds.feedburner.com/PythonInsider
- url: https://blog.thunderbird.net/feed/
- url: https://usesthis.com/feed.atom
- url: https://xeiaso.net/blog.rss
- url: https://touhou-project.news/feed.rss
- url: http://www.post.japanpost.jp/rss/int.xml
- url: https://www.reddit.com/user/AzulCrescent/submitted/.rss
- url: https://www.reddit.com/user/TheArchiveTerminal/submitted/.rss
- url: https://blog.gitea.com/rss.xml
- type: twitch-channels
channels:
- a_lillian_
- princessxen
- barry
- sylvysprit
- The8BitDrummer
- MataraKan
- nyanners
- DougDoug
- Touhou_Replay_Showcase
- size: full
widgets:
- type: search
search-engine: https://kagi.com/search?token=ygXAizA-9gY.ejxyFYbeHxOWVxBYgxMGtJPmAeu1pi1DCtOVTW5yFd8&q={QUERY}
autofocus: true
- type: group
widgets:
- type: lobsters
- type: hacker-news
- type: bookmarks
groups:
- title: Internal
color: 331 64 52
links:
- title: Hoarder
url: https://hoarder.remilia.ch
same-tab: true
- title: Actual Budget
url: https://actual.remilia.ch
same-tab: true
- title: Paperless
url: https://papers.remilia.ch
same-tab: true
- title: Privatebin
url: https://privatebin.remilia.ch
same-tab: true
- title: Proxmox
url: https://yuyuko.remilia.ch:8006
same-tab: true
- title: Photos
url: https://photos.remilia.ch
same-tab: true
- title: Portainer
url: https://portainer.remilia.ch
same-tab: true
- title: Plex
url: https://plex.remilia.ch
same-tab: true
- title: Koumbit
color: 91 70 40
links:
- title: IRC
url: https://irc.prettysunflower.moe
same-tab: true
- title: Redmine
url: https://redmine.koumbit.net/
same-tab: true
- title: kProject
url: https://travail.koumbit.net/node/29390/punches
same-tab: true
- title: Etherpad
url: https://pad.koumbit.net/
same-tab: true
- title: Wiki
url: https://wiki.koumbit.net/
same-tab: true
- title: Figurines
color: 10 70 50
links:
- title: AmiAmi
url: https://www.amiami.com/
same-tab: true
- title: HPOI
url: https://www.hpoi.net/
same-tab: true
- title: OurFigureCollection (Suruga-ya)
url: https://ourfigurecollection.moe/surugaya/
same-tab: true
- title: The Spreadsheet of Insanity
url: https://data.remilia.ch/base/bsemaa6OqPGDk6A5Uch/tblZGRYDwnFCDqnFAld/viwJgLAdhRRzvGpULZR
same-tab: true
- size: small
widgets:
- type: weather
location: Montréal, Canada
- type: clock
hour-format: 24h
timezones:
- timezone: Europe/Zurich
label: Genève
- timezone: Asia/Shanghai
label: Shanghai
- timezone: Asia/Tokyo
label: Tokyo
- type: rss
limit: 10
collapse-after: 3
cache: 15m
title: Dynasty Reader updates
feeds:
- url: https://dynasty-scans.com/feed
theme:
light: true
background-color: 0 0 95
primary-color: 0 0 10
positive-color: 175 59 40
negative-color: 0 90 50

View File

@@ -0,0 +1,7 @@
resources:
- deployment.yaml
- services.yaml
configMapGenerator:
- name: glance-config
files:
- glance.yml

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: glance
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: glance
ports:
- protocol: TCP
port: 80
targetPort: 8080
name: http

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: gotosocial-config
data:
GTS_HOST: fedi.prettysunflower.moe
GTS_ACCOUNT_DOMAIN: prettysunflower.moe
GTS_TRUSTED_PROXIES: "10.217.0.0/32"
GTS_INSTANCE_LANGUAGES: en,fr
GTS_ACCOUNTS_ALLOW_CUSTOM_CSS: "true"

View File

@@ -0,0 +1,76 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gotosocial
labels:
app.kubernetes.io/name: gotosocial
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: gotosocial
template:
metadata:
labels:
app.kubernetes.io/name: gotosocial
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: gotosocial-pvc
dnsPolicy: "None"
dnsConfig:
nameservers:
- 100.96.226.96
containers:
- image: docker.io/superseriousbusiness/gotosocial:0.19.1
name: gotosocial
ports:
- containerPort: 8080
protocol: TCP
name: http
volumeMounts:
- name: data
mountPath: /gotosocial/storage
envFrom:
- configMapRef:
name: gotosocial-config
- secretRef:
name: gotosocial-secrets
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
livenessProbe:
httpGet:
path: /livez
port: http
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
startupProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
successThreshold: 1
readinessProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1

View File

@@ -0,0 +1,6 @@
resources:
- configmap.yaml
- deployment.yaml
- pvc.yaml
- secrets.yaml
- svc.yaml

View File

@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gotosocial-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10G
storageClassName: nfs-csi

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Secret
metadata:
name: gotosocial-secrets
type: Opaque
stringData:
GTS_DB_ADDRESS: ENC[AES256_GCM,data:PqPAl3c/2yYw/R+o,iv:01M73o6Ok/cDxxtSpHjduWKSFplXNJ93WcQYf19DTWg=,tag:KdMISrg8LEG7pj49OyeYdA==,type:str]
GTS_DB_USER: ENC[AES256_GCM,data:LFMfG09Z2OIBhA==,iv:L2Gapmk2nvOdDRiRM7sRLdIJnhhJ+N9kAzYl4P4w7r8=,tag:PghjpZRZjiN6BqvCz5g3Dg==,type:str]
GTS_DB_PASSWORD: ENC[AES256_GCM,data:CnqraWwcOkRHt+ET/0lp,iv:asmChmzapS73l3nTVK+qhBr3HDNi7UvNVwjOO2razPk=,tag:fB9JOnpqWf1ZczAjIjc9Zg==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6dkoxaUJ2bnRDNEFadjdN
MFRmUUM2M0xlRXJ1WmhPY080WVdHa2h2S1FRCnI2MmdJRUxlUlNxVnBUa3ZHUEVF
YkxKaUZXYTFrU0FYSmNIQm94SDN4bHcKLS0tIHIvdTBXdmxqM2I3WGo3dWpPK3lL
ditudGE2OVpNZVRTMXdoM2w2eHdpZkUKOQ+LS4zDEeJheoJ/pR06h/WwozoyBXMz
DbxFpJ0ykjmUuRJ3CBr/MPVRa0V8NA8qVTHxjYDYwg4H9LH4nB+yiw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:Ys4wt4Z2ocKt3WPxztXl7K/2gEFnnppxvSPGxqB6KBeNe/mRkYQ7PAqCcUKZledncIgXpxRfU/Cv7huc93MlQVGyNZ1MgYO7U9H8vBHaDJuS1bAJ6n/NnDKKCQA7yJOJpfd09FnScOpeMf1cO+PQPuHaYUbIZpS+6ctepXLpHQo=,iv:uCFSGP8qvZA6EmTzUD6q9uwrkIHraMGyyjQ+42FikTM=,tag:gCePqCDIeZ3yxkKbsWCsZw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: gotosocial
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: gotosocial
ports:
- protocol: TCP
port: 80
targetPort: http
name: http

View File

@@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: opengist
labels:
app.kubernetes.io/name: opengist
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: opengist
template:
metadata:
labels:
app.kubernetes.io/name: opengist
spec:
volumes:
- name: opengist-data
persistentVolumeClaim:
claimName: opengist-data-pvc
containers:
- name: opengist
image: ghcr.io/thomiceli/opengist:1.10
ports:
- containerPort: 6157
volumeMounts:
- name: opengist-data
mountPath: "/opengist"
envFrom:
- secretRef:
name: opengist-secret
livenessProbe:
httpGet:
path: /healthcheck
port: 6157
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3

View File

@@ -0,0 +1,5 @@
resources:
- deployment.yaml
- pvc.yaml
- services.yaml
- secrets.yaml

View File

@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: opengist-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: nfs-csi

View File

@@ -0,0 +1,28 @@
apiVersion: v1
kind: Secret
metadata:
name: opengist-secret
type: Opaque
data:
OG_SECRET_KEY: ENC[AES256_GCM,data:CvlbIc/O4FkhELpy76zfE027zavhIEfSDx1JwPfjN5716LJDEuPIoLd19RDx8i92jbPk5RrGEvgLcwyWShwQ11BXPuXIXD8KsAqFwECwk6TKneuJSDbnlQ==,iv:xruob7s++xnqvzmS+JboXlL6W0leicziZMOc0zn//HA=,tag:/OLxQC02uFbcduvhJeoAKg==,type:str]
OG_OIDC_PROVIDER_NAME: ENC[AES256_GCM,data:Asg/Wvct6UjcKQj0ZmO/zWYAlZ8=,iv:14qEsQgm923nX3L+zDrrwYWX4oqpAGRS5lkP/c+Ufl4=,tag:38WXRayva09L2/QsKqPsXw==,type:str]
OG_OIDC_DISCOVERY_URL: ENC[AES256_GCM,data:3OD/XS9JUAAI3MacofVKQXWl/jC1mBoG9CEFmIm/ol7GaN9PBdmlC7c5+rsvf37aolqKkpyQdlVVEAlP98caRAJxR75STzEQS708pw==,iv:b4d1i/xOX3TaYR3ZwDh84mvAe0MYmat5JHLJj4TXSsU=,tag:5Aqhpl39RURk+PjEPJtw2A==,type:str]
stringData:
OG_OIDC_CLIENT_KEY: ENC[AES256_GCM,data:mdWOC+W+ksd+XOJRYKBEFSHDyIYV7ID9fYkpHAjoJf9UNx+c,iv:xU9zVltACcgqsATlJgfhT7M/P3+sVIE8rWn83/1fubo=,tag:rW3zq1rY0InpFo3Mmgft2A==,type:str]
OG_OIDC_SECRET: ENC[AES256_GCM,data:97lerV+9dPvEcCEJneTnwO7Iv829PnLiGd0WYuD48H4=,iv:5oDgiZ0oOnTCVJPyHXIQ+Tjaq/dBe+xZEn6EhGaDn+s=,tag:ZWBqzTGREyEuDRu6gBfKcA==,type:str]
OG_DB_URI: ENC[AES256_GCM,data:QjdJc2PDyMTBga9P+U6c5JkTABuXIpoA5ba+rPW+DHyWDA7WZtvlt+cssPd2yBH363+XqLmH40r9Wz8pWXaRHj7dnhmI7cSfSgtnGA==,iv:ilk2GD0wL/5jefsa5fu9YXwXn0G+U4Agqzme+ilUGL4=,tag:F8C+/Hdv/gSkh0Uvxt1qAA==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYMnRpRlJxbjBReDVGS2dY
bDNyVlFWaW5oQ2VmaUdsRWNZN0dnNE9kQ1FJCjg5VW9XOUc3eEdOcnZCMTI4YXcz
Q3RpZjNIczJSV01QZmFsRkV6aU4vMEkKLS0tIE5xMHd4Tk1xYlllTWwxQ2htS1NR
M3VwVERJVHE3VVB0QzlOMGk4RDF1UEkKT2BbgMdJBz9OVX279VffXQ+LonSi5IzB
+gxybF3+/HzTaGnKo0juVDO8x8cZqjmWkOWGl7iFTDv7z87qHgLV+A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:KIeBdomBppTaAua5hF3UJUX3a2bViLNEu2kygATDCEovnhCZCr7vwuJBHnwOq9X1+tvoMJLzEf4vhXCE2PjOcNAf5QHR/a/7NZdnB/9lnWCpRVu2Av6vJPBtbqWhIhS6skFgBPnz22Lo9y1A4ZhqiMF4kx0gVKe8CfMXhFhcfT4=,iv:TfY9mxLBDllQE56GklfCgMD9OrSW1tHMHvhWKVjQulI=,tag:O//p0etj0WTf+/5qnmkmEw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: opengist
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: opengist
ports:
- protocol: TCP
port: 80
targetPort: 6157
name: http

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: planka-config
data:
BASE_URL: https://kanban.prettysunflower.moe
OIDC_ISSUER: https://auth.remilia.ch
OIDC_CLIENT_ID: eb200a8b-5b93-4b77-a070-1081481270a1
OIDC_IGNORE_ROLES: "true"
OIDC_ENFORCED: "true"

View File

@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: planka
labels:
app.kubernetes.io/name: planka
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: planka
template:
metadata:
labels:
app.kubernetes.io/name: planka
spec:
volumes:
- name: planka-data
persistentVolumeClaim:
claimName: planka-data-pvc
containers:
- name: planka
image: ghcr.io/plankanban/planka:2.0.0-rc.3
ports:
- containerPort: 1337
name: http
volumeMounts:
- name: planka-data
subPath: favicons
mountPath: "/app/public/favicons/"
- name: planka-data
subPath: user-avatars
mountPath: "/app/public/user-avatars/"
- name: planka-data
subPath: background-images
mountPath: "/app/public/background-images/"
- name: planka-data
subPath: attachments
mountPath: "/app/private/attachments/"
envFrom:
- configMapRef:
name: planka-config
- secretRef:
name: planka-secrets

View File

@@ -0,0 +1,6 @@
resources:
- configmap.yaml
- deployment.yaml
- pvc.yaml
- secrets.yaml
- svc.yaml

View File

@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: planka-data-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5G
storageClassName: nfs-csi

View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: Secret
metadata:
name: planka-secrets
type: Opaque
stringData:
DATABASE_URL: ENC[AES256_GCM,data:/P/UTQ5hn4iXostkAQfguXOEgm3i4u4GU2AtXf63Fa5Vj+xphAZIswrVs3A/UYUGsm8pQzc=,iv:Scg5AkeGhBG6k7AoYbsEihOu659Q5g4j8EOp7xYW6Zo=,tag:FBrGgdzW6divFyEAbdZnvQ==,type:str]
SECRET_KEY: ENC[AES256_GCM,data:SN8r72D2iLxpGdqEzjQ5I9PHW/P3NwwJOUYbp+Gi9Hg/a0TBZ9QJZnhveGJPh9aV3KiwuzNK8+AT5TWcFkCSwYa33ZlwJeiTxvfombDYWuqvccwl2Vwun52vUYfrdqogDYcaeP9US6GsJd8eaRUO3iyc0A+C039S68jkGt18h8Q=,iv:hlpmq4fGDjnxXmYRhCBTM9RwBWXA1OAF5AMhs7T0IqU=,tag:Soq3gnQQDaTHBBYoQ9l88A==,type:str]
OIDC_CLIENT_SECRET: ENC[AES256_GCM,data:PE6qqlsEpAcaZopGVh6y6/S2EuM3ybTpha+Gmhh7krA=,iv:AcS4H21JOOlAtLDDawqpyzdxdSUr3kFtMB6ynxG3Ewg=,tag:WLZ1JfVOOahaJgvP+YYORA==,type:str]
DEFAULT_ADMIN_EMAIL: ENC[AES256_GCM,data:0q437f+tid9X9Hj2F+nlEvyD,iv:TR6YBD84MevOic8d/btZdIAJtkiHRPftOIIJQwkc5iQ=,tag:nspH0pSxPMfevqwXz3RYMw==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnMVhvdGNYSzBhSWhpTXRY
eFU0Y3Z1YXlIUU1tZkhHVTloaEhMbk1rNFNvCnl3d3NSZit3MklkSHBPOFgrL25n
d01RbGJlZ3BzN2V4R3lVbUZBZ051VTQKLS0tIFp4c3pRTitISFJOR3JYNjU2TnRI
YzAvRHM5cHprbDJCTlNGa3h0MkZxN2sKnlvHgMwqUM3X47+OeRLxJepfEaVvHSag
XWVGGhEAtFkXbyW3e59+LygrabU1Eq0BX4sbN404VpSaosCCxREM5A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:9rFIGDm44sPYF2a8lYAw5ooMW0U2td8ajclYHoeOHxQNPouXtTLvEyqjYNeXIIpUfpjYe6qz7us3PeuFeCCGAmobQ34qRu87Jd2n9yg70OSyklzMr4lCaeenlU+3q5nhWWyrv0tHuDUgLWR9F674Xl5T4QfbfbfKwzNMskNg7QM=,iv:pIT6NI7ed8EK7FEF6OySSxrN4vurMv0rUl75Y45wUdQ=,tag:rHgn4IWBGq9UH6d3z1lVkw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: planka
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: planka
ports:
- protocol: TCP
port: 80
targetPort: http

View File

@@ -0,0 +1,321 @@
# -*- mode: conf -*-
# vim:ft=cfg
# Config file for Radicale - A simple calendar server
#
# Place it into /etc/radicale/config (global)
# or ~/.config/radicale/config (user)
#
# The current values are the default ones
[server]
# CalDAV server hostnames separated by a comma
# IPv4 syntax: address:port
# IPv6 syntax: [address]:port
# Hostname syntax (using "getaddrinfo" to resolve to IPv4/IPv6 adress(es)): hostname:port
# For example: 0.0.0.0:9999, [::]:9999, localhost:9999
#hosts = localhost:5232
hosts = 0.0.0.0:5232
# Max parallel connections
#max_connections = 8
# Max size of request body (bytes)
#max_content_length = 100000000
# Socket timeout (seconds)
#timeout = 30
# SSL flag, enable HTTPS protocol
#ssl = False
# SSL certificate path
#certificate = /etc/ssl/radicale.cert.pem
# SSL private key
#key = /etc/ssl/radicale.key.pem
# CA certificate for validating clients. This can be used to secure
# TCP traffic between Radicale and a reverse proxy
#certificate_authority =
# SSL protocol, secure configuration: ALL -SSLv3 -TLSv1 -TLSv1.1
#protocol = (default)
# SSL ciphersuite, secure configuration: DHE:ECDHE:-NULL:-SHA (see also "man openssl-ciphers")
#ciphersuite = (default)
# script name to strip from URI if called by reverse proxy
#script_name = (default taken from HTTP_X_SCRIPT_NAME or SCRIPT_NAME)
[encoding]
# Encoding for responding requests
#request = utf-8
# Encoding for storing local collections
#stock = utf-8
[auth]
# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user | dovecot | ldap | oauth2 | pam | denyall
#type = denyall
type = none
# Cache logins for until expiration time
#cache_logins = false
# Expiration time for caching successful logins in seconds
#cache_successful_logins_expiry = 15
## Expiration time of caching failed logins in seconds
#cache_failed_logins_expiry = 90
# Ignore modifyTimestamp and createTimestamp attributes. Required e.g. for Authentik LDAP server
#ldap_ignore_attribute_create_modify_timestamp = false
# URI to the LDAP server
#ldap_uri = ldap://localhost
# The base DN where the user accounts have to be searched
#ldap_base = ##BASE_DN##
# The reader DN of the LDAP server
#ldap_reader_dn = CN=ldapreader,CN=Users,##BASE_DN##
# Password of the reader DN
#ldap_secret = ldapreader-secret
# Path of the file containing password of the reader DN
#ldap_secret_file = /run/secrets/ldap_password
# the attribute to read the group memberships from in the user's LDAP entry (default: not set)
#ldap_groups_attribute = memberOf
# The filter to find the DN of the user. This filter must contain a python-style placeholder for the login
#ldap_filter = (&(objectClass=person)(uid={0}))
# the attribute holding the value to be used as username after authentication
#ldap_user_attribute = cn
# Use ssl on the ldap connection
# Soon to be deprecated, use ldap_security instead
#ldap_use_ssl = False
# the encryption mode to be used: tls, starttls, default is none
#ldap_security = none
# The certificate verification mode. Works for ssl and starttls. NONE, OPTIONAL, default is REQUIRED
#ldap_ssl_verify_mode = REQUIRED
# The path to the CA file in pem format which is used to certificate the server certificate
#ldap_ssl_ca_file =
# Connection type for dovecot authentication (AF_UNIX|AF_INET|AF_INET6)
# Note: credentials are transmitted in cleartext
#dovecot_connection_type = AF_UNIX
# The path to the Dovecot client authentication socket (eg. /run/dovecot/auth-client on Fedora). Radicale must have read / write access to the socket.
#dovecot_socket = /var/run/dovecot/auth-client
# Host of via network exposed dovecot socket
#dovecot_host = localhost
# Port of via network exposed dovecot socket
#dovecot_port = 12345
# IMAP server hostname
# Syntax: address | address:port | [address]:port | imap.server.tld
#imap_host = localhost
# Secure the IMAP connection
# Value: tls | starttls | none
#imap_security = tls
# OAuth2 token endpoint URL
#oauth2_token_endpoint = <URL>
# PAM service
#pam_serivce = radicale
# PAM group user should be member of
#pam_group_membership =
# Htpasswd filename
#htpasswd_filename = /etc/radicale/users
# Htpasswd encryption method
# Value: plain | bcrypt | md5 | sha256 | sha512 | argon2 | autodetect
# bcrypt requires the installation of 'bcrypt' module.
# argon2 requires the installation of 'argon2-cffi' module.
#htpasswd_encryption = autodetect
# Enable caching of htpasswd file based on size and mtime_ns
#htpasswd_cache = False
# Incorrect authentication delay (seconds)
#delay = 1
# Message displayed in the client when a password is needed
#realm = Radicale - Password Required
# Convert username to lowercase, must be true for case-insensitive auth providers
#lc_username = False
# Strip domain name from username
#strip_domain = False
[rights]
# Rights backend
# Value: authenticated | owner_only | owner_write | from_file
#type = owner_only
# File for rights management from_file
#file = /etc/radicale/rights
# Permit delete of a collection (global)
#permit_delete_collection = True
# Permit overwrite of a collection (global)
#permit_overwrite_collection = True
# URL Decode the given username (when URL-encoded by the client - useful for iOS devices when using email address)
# urldecode_username = False
[storage]
# Storage backend
# Value: multifilesystem | multifilesystem_nolock
#type = multifilesystem
# Folder for storing local collections, created if not present
#filesystem_folder = /var/lib/radicale/collections
filesystem_folder = /data/collections
# Folder for storing cache of local collections, created if not present
# Note: only used in case of use_cache_subfolder_* options are active
# Note: can be used on multi-instance setup to cache files on local node (see below)
filesystem_cache_folder = /cache
# Use subfolder 'collection-cache' for 'item' cache file structure instead of inside collection folder
# Note: can be used on multi-instance setup to cache 'item' on local node
use_cache_subfolder_for_item = True
# Use subfolder 'collection-cache' for 'history' cache file structure instead of inside collection folder
# Note: use only on single-instance setup, will break consistency with client in multi-instance setup
use_cache_subfolder_for_history = True
# Use subfolder 'collection-cache' for 'sync-token' cache file structure instead of inside collection folder
# Note: use only on single-instance setup, will break consistency with client in multi-instance setup
use_cache_subfolder_for_synctoken = True
# Use last modifiction time (nanoseconds) and size (bytes) for 'item' cache instead of SHA256 (improves speed)
# Note: check used filesystem mtime precision before enabling
# Note: conversion is done on access, bulk conversion can be done offline using storage verification option: radicale --verify-storage
use_mtime_and_size_for_item_cache = True
# Use configured umask for folder creation (not applicable for OS Windows)
# Useful value: 0077 | 0027 | 0007 | 0022
#folder_umask = (system default, usual 0022)
# Delete sync token that are older (seconds)
#max_sync_token_age = 2592000
# Skip broken item instead of triggering an exception
#skip_broken_item = True
# Command that is run after changes to storage, default is emtpy
# Supported placeholders:
# %(user)s: logged-in user
# %(cwd)s : current working directory
# %(path)s: full path of item
# Command will be executed with base directory defined in filesystem_folder
# For "git" check DOCUMENTATION.md for bootstrap instructions
# Example(test): echo \"user=%(user)s path=%(path)s cwd=%(cwd)s\"
# Example(git): git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
#hook =
# Create predefined user collections
#
# json format:
#
# {
# "def-addressbook": {
# "D:displayname": "Personal Address Book",
# "tag": "VADDRESSBOOK"
# },
# "def-calendar": {
# "C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
# "D:displayname": "Personal Calendar",
# "tag": "VCALENDAR"
# }
# }
#
#predefined_collections =
[web]
# Web interface backend
# Value: none | internal
#type = internal
[logging]
# Threshold for the logger
# Value: debug | info | warning | error | critical
#level = info
# Don't include passwords in logs
#mask_passwords = True
# Log bad PUT request content
#bad_put_request_content = False
# Log backtrace on level=debug
#backtrace_on_debug = False
# Log request header on level=debug
#request_header_on_debug = False
# Log request content on level=debug
#request_content_on_debug = False
# Log response content on level=debug
#response_content_on_debug = False
# Log rights rule which doesn't match on level=debug
#rights_rule_doesnt_match_on_debug = False
# Log storage cache actions on level=debug
#storage_cache_actions_on_debug = False
[headers]
# Additional HTTP headers
#Access-Control-Allow-Origin = *
[hook]
# Hook types
# Value: none | rabbitmq
#type = none
#rabbitmq_endpoint =
#rabbitmq_topic =
#rabbitmq_queue_type = classic
[reporting]
# When returning a free-busy report, limit the number of returned
# occurences per event to prevent DOS attacks.
#max_freebusy_occurrence = 10000

View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: radicale
labels:
app.kubernetes.io/name: radicale
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: radicale
template:
metadata:
labels:
app.kubernetes.io/name: radicale
spec:
volumes:
- name: radicale-data
persistentVolumeClaim:
claimName: radicale-data-pvc
# emptyDir:
# sizeLimit: 50Mi
# medium: Memory
- name: radicale-config
configMap:
name: radicale-config
- name: cache-volume
emptyDir:
sizeLimit: 50Mi
medium: Memory
containers:
- name: radicale
image: tomsquest/docker-radicale:3.5.4.0
ports:
- containerPort: 5232
name: http
volumeMounts:
- name: radicale-data
mountPath: "/data"
- name: radicale-config
mountPath: "/config"
- name: cache-volume
mountPath: "/cache"
resources:
requests:
cpu: 200m
memory: 64M
limits:
cpu: 500m
memory: 256M
livenessProbe:
httpGet:
path: /
port: 5232
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,8 @@
resources:
- deployment.yaml
- pvc.yaml
- svc.yaml
configMapGenerator:
- name: radicale-config
files:
- config

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radicale-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
storageClassName: nfs-csi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: caldav
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: radicale
ports:
- protocol: TCP
port: 80
targetPort: http

View File

@@ -0,0 +1,35 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: renovate-gitea
spec:
schedule: '*/5 * * * *'
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- 100.96.226.96
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: location
operator: In
values:
- fsn
containers:
- name: renovate
image: renovate/renovate:41.31.1
env:
- name: LOG_LEVEL
value: debug
envFrom:
- secretRef:
name: renovate-gitea-env
restartPolicy: Never

View File

@@ -0,0 +1,3 @@
resources:
- cronjob.yaml
- secrets.yaml

View File

@@ -0,0 +1,28 @@
apiVersion: v1
kind: Secret
metadata:
name: renovate-gitea-env
type: Opaque
stringData:
RENOVATE_GITHUB_COM_TOKEN: ENC[AES256_GCM,data:tEaxtH/tMQ4lpvSMwNRf75Ir5Z711/x45fgOkvFDE/SQDq752QfKhA==,iv:2j2aQFodFg47a1xRTw5KCJsE/hqCa9Fe9bDMr1IPhvY=,tag:QvOEfa38bx0DnGeimP8EFA==,type:str]
RENOVATE_AUTODISCOVER: ENC[AES256_GCM,data:qgD3GA==,iv:hIXYcwxQTOn6XVdWYqjz8UISwIJ4fGdSo0bQrxbgcLs=,tag:YLP/28760E6YyuWiWVcCFw==,type:str]
RENOVATE_ENDPOINT: ENC[AES256_GCM,data:Yx8NJsN/zfCAy4IeMgObrhvpVOCdi4k9oubQfKubJlbBF5309nE=,iv:ozkCVyOgHtE05qUfcubxqUTrfYiNKrIIDg3ZZlbNGMs=,tag:8gqxc4FienvPH1oqP81ZKA==,type:str]
RENOVATE_GIT_AUTHOR: ENC[AES256_GCM,data:WFwP86EfQYSedLLcQyL/nQmZFkIRx7IMSfOTNeCqIDRLjMueQ7zeupRivNPk9A==,iv:aOC1n0EbWx5jq+8C3kM9KLUwZIAXW6GlZXvGjMwDTZ0=,tag:yrATDQw4EdUY2XcCltUhQg==,type:str]
RENOVATE_PLATFORM: ENC[AES256_GCM,data:Uw4ihT8=,iv:2Y4Mv6YNjG0KfU+0ZBX6f1eJ47v1r2o0kiV1QgWOn5I=,tag:XBw4rJCDcBTBHdxMcwmLfA==,type:str]
RENOVATE_TOKEN: ENC[AES256_GCM,data:brPzHjCuxpPU3z0pfd1loXavpMiqAWD0Nod4+szW3EWBsWAHgHj26A==,iv:smXMkCRv5vNg1vsd+X2x6RyumRcqSSwGp8xaKppsg6w=,tag:nbUYnF8Vte8shvcIQyiI0Q==,type:str]
RENOVATE_KUBERNETES: ENC[AES256_GCM,data:kY8sEwcsuvehijA6BwHvHIUI6OSO/S2MCsY=,iv:UMRcqpTQ9vScisXugKiVnDPLR8tsSz600pl6dw3v/xc=,tag:GukTMpkIXozz6TAATZjA0w==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBbitVRE5mcnBhaUhybHlT
dFg5N0V0R0g1UFlyZzFjSk9aa09QUVVEUkhvCkFPanpEYmZ6a1lmMlFCMlZZMC9O
V0gwM2lBNFhKeWtwVzRIeEhGZ0YxL0UKLS0tIEl2NkxsTThaUTY5UUozNjk1cnBx
a0NWZFRyYkVJTXZpU0d0QlBmRDNrWm8KNGrP45Bj87LHygIZsFLsz6iL8zHyuDw0
JVxqzb2tCa90OfhzDQpIh06N5ep1AowE9IWea7PoW4jaWzd7vDge5g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:+0envuEAfwqgOI2ysbTYcPph7sIKFK26RqAy8vLQ/tvQ700nXyZRgOS2DSOIKeMq0+e3bg2gbgWaKLu8TPGYSf6DI4xGOx+vXSjcPMdiO05Wa0qu1Ha3+C3Uoyijt1YY2TZ0YO/WCNakyF7WPP4urFBNtictvoZIWTv31JPw7OQ=,iv:TmsTKP8dJxnjnDM0WFzSIRqImT0XVwYBAgG06VTWkDE=,tag:++33bVCSjOhW4JQCQ8e2Xg==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: teable-config
namespace: teable
data:
PUBLIC_ORIGIN: "https://data.sunflower.lgbt"
BACKEND_CACHE_PROVIDER: "redis"
NEXT_ENV_IMAGES_ALL_REMOTE: "true"
PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: "1"
NODE_TLS_REJECT_UNAUTHORIZED: '0'
BACKEND_STORAGE_TOKEN_EXPIRE_IN: '1d'

View File

@@ -0,0 +1,139 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: teable
namespace: teable
labels:
app.kubernetes.io/name: teable
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: teable
template:
metadata:
labels:
app.kubernetes.io/name: teable
spec:
hostAliases:
- ip: "100.113.193.5"
hostnames:
- "mail.prettysunflower.moe"
initContainers:
- name: db-migrate
image: ghcr.io/teableio/teable:83745958bbba83111145e1cd48de811cfc7db601
args:
- migrate-only
envFrom:
- configMapRef:
name: teable-config
- secretRef:
name: teable-secrets
resources:
requests:
cpu: 100m
memory: 102Mi
limits:
cpu: 1000m
memory: 1024Mi
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
containers:
- name: teable
image: ghcr.io/teableio/teable:83745958bbba83111145e1cd48de811cfc7db601
args:
- skip-migrate
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: teable-config
- secretRef:
name: teable-secrets
resources:
requests:
cpu: 200m
memory: 400Mi
limits:
cpu: 2000m
memory: 4096Mi
startupProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
successThreshold: 1
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: valkey
namespace: teable
labels:
app.kubernetes.io/name: valkey
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: valkey
template:
metadata:
labels:
app.kubernetes.io/name: valkey
spec:
volumes:
- name: valkey-data
persistentVolumeClaim:
claimName: valkey-data-pvc
containers:
- image: valkey/valkey:8.1.2-alpine
name: valkey
envFrom:
- secretRef:
name: valkey-secrets
command: ["valkey-server"]
ports:
- containerPort: 6379
protocol: TCP
volumeMounts:
- name: valkey-data
mountPath: "/data"
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,7 @@
resources:
- config.yaml
- deployment.yaml
- pvc.yaml
- namespace.yaml
- services.yaml
- secrets.yaml

View File

@@ -0,0 +1,6 @@
kind: Namespace
apiVersion: v1
metadata:
name: teable
labels:
name: teable

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: valkey-data-pvc
namespace: teable
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: nfs-csi

View File

@@ -0,0 +1,63 @@
apiVersion: v1
kind: Secret
metadata:
name: teable-secrets
namespace: teable
type: Opaque
stringData:
PRISMA_DATABASE_URL: ENC[AES256_GCM,data:S7Y4B5apBAYbZ6lQ5/O31RThkAnKV3Qx+ab2ieQSn63qsik451ciRWzTysIuADOeivo+1sSqyIIdBvBGpPR+n108kw==,iv:zSwa0dgoydq2hbaxxXDO/gBcrLMPFqAxjTUaPMfzyOg=,tag:Uy/+KAP7SE4bOrDN7eNWIg==,type:str]
SECRET_KEY: ENC[AES256_GCM,data:KXnjt6MiPts4u1vqf4pFYjAJq+6xPQ==,iv:8U61KBz8ZaNZluvLsGNmP3X7M5Upv/02ngoy2lpndUQ=,tag:0RmPivQtQgQa+XAltN6Dxg==,type:str]
BACKEND_STORAGE_PROVIDER: ENC[AES256_GCM,data:M9o=,iv:Z8twg5olXc+PtrVNxl24W6m+l/5bS81kAiXF4O8CSHQ=,tag:ImiZg6nCiGGFUPIfWRqrlQ==,type:str]
BACKEND_STORAGE_S3_REGION: ENC[AES256_GCM,data:JvGqWw==,iv:8KbVumdAXPZBLB7g7oqf1rfFnHKhPvleezY7Tryma1o=,tag:9VVoNTjvuPs7v0ep8wSc9w==,type:str]
BACKEND_STORAGE_S3_ENDPOINT: ENC[AES256_GCM,data:THKG0BPjvXU9u1qeutoBkGJ8pbq1aw==,iv:T04svNvlk+05mrwlVV9sp32eyjbKWp/Z0Fdc3PUOB1k=,tag:Ov7Wr4lJ0ixdTD3/9db0DA==,type:str]
BACKEND_STORAGE_S3_ACCESS_KEY: ENC[AES256_GCM,data:4X9UespqF1qtiLIfMQRi79VP5Xdjage7xTxZKPtJ80vs2VnaFknqzzDTMsAm9fZk7FKMCWde,iv:Rp0AlShe6e0JrQ/4fVyiGs5lAkPXl7574UF35HHntwQ=,tag:TSemTreK3c5+mZjTt+Cl0w==,type:str]
BACKEND_STORAGE_S3_SECRET_KEY: ENC[AES256_GCM,data:GtenV4qKUlZmGMV8WCO3/9tsjpdTceoCzY8v4maWIo1L9iy/u4I8TKXa6iv/9QpSTq0YW2qh5YtmSOvpeqOsmceNV3s61CNydqsE,iv:I9cn5jmP6OjQ3H3Z8TLT5ZGNihnME3cnyn7BI9iBIUg=,tag:9CXNZtg9B/4Yj2ZKTgwSRg==,type:str]
BACKEND_STORAGE_PUBLIC_BUCKET: ENC[AES256_GCM,data:GoOlFVdgcG8yx9hTFyI0zK/WvlgnMAYshLejrKs=,iv:lJTx2Wovtka+fHGK7ojWiY81besS7IrV/oPcN5546UI=,tag:M4Q0ukX3Vhc/F6WPQsmmVQ==,type:str]
BACKEND_STORAGE_PRIVATE_BUCKET: ENC[AES256_GCM,data:2pmNoVRrkkwggoj2gjxy2fOGQYTT+q5L7LqYnNOF,iv:LSe93EycfC304/ji1BU/dovsCP2L+s6II3Uz7drl7lY=,tag:NlCE0GMQOEWABcjDKG6rIQ==,type:str]
BACKEND_CACHE_REDIS_URI: ENC[AES256_GCM,data:2WSh32ZQb26dPyI9LVqxQaykMdXhFuA6YKMzpT9X3HXcKO0wGiJMl0tDZvIK/qnGU4ShgCXqD5/TQZSzTe6XI1YKJoFou6pvHkXgFIoEJEZSgxWlhY9unj3Fizwm,iv:8vkHRo5cpLRNzVxmeJILY/DAO9Xgp8RoJnTiG4mqQJc=,tag:EzhcJ9ntjlWD95KDpke2Bg==,type:str]
BACKEND_MAIL_HOST: ENC[AES256_GCM,data:dRZR7Oi9acB5ANFcO6HWUyPyHFcgESYb,iv:uyyQHB18OuZJDM0+6FcYvbyZEjOeOPQj8HTE7zWLl28=,tag:6x5clI3OquJI4ryoJ/mIhQ==,type:str]
BACKEND_MAIL_PORT: ENC[AES256_GCM,data:UzK1,iv:KYdakhFPfe7wLyNbxpQlAmYDYhmHfKVAiDtFMTwxhPU=,tag:KfrNLO7Z5y24gWcFo3O9Sw==,type:str]
BACKEND_MAIL_SECURE: ENC[AES256_GCM,data:yqGAQG0=,iv:oVaScBsc2v7AqudqJxyM/AGmd9479igZzNsY+G+wNWE=,tag:JM7JfT8Ljv6IbytBGmAplg==,type:str]
BACKEND_MAIL_SENDER: ENC[AES256_GCM,data:PNmUSwER7gjYv4bVxBPDxy5LOwFMhoPsY6U=,iv:1lUdrocPb6nP7N/6Xk4+d67pF3iu4jvvskKJ0x/UADU=,tag:reHZtXP0ZXwOFH9XibNrWA==,type:str]
BACKEND_MAIL_SENDER_NAME: ENC[AES256_GCM,data:IipWnw==,iv:Tp6k90QrG1/5M9kdvSLnXtz4xcU/mxNQ4563PSeb0Xc=,tag:oIJjlXpIuDbbTtnbZ6HRgw==,type:str]
BACKEND_MAIL_AUTH_USER: ENC[AES256_GCM,data:7pz5djxOzt19o2KgDchkO4hdXuPoZA==,iv:LHK7Cb1iFJbRWlGEEB4ziKZJKhOJ4OPfEgGNqxm244I=,tag:03A36lsN5GkKZhTqQQFMFw==,type:str]
BACKEND_MAIL_AUTH_PASS: ENC[AES256_GCM,data:7Oo6vF4MRSLuTWJGnZueug==,iv:813e2G1nGQFLv9AWZF4oKIIHq1eBLKuTm/0BR/a0tAw=,tag:iWUsbvmDFLnBVNNoXJ4hcA==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFQVVUU3AxN2tnUG1ORmpw
c29YMWErYXl0QmtKVWdjWng2azRBUDJSbnlnClVnSVBlRUJ6NElDWmZOVnJRTUVB
NWVIRm1FUWc2NW14TE9MSnNpVnNPcU0KLS0tIDdrbjhWY3hoZCtROWtPKytXenJ0
eEptQ1R2QlAyeDdnZWdkZGNBcFZxL0EKe5wXjgOEN5hULVrSdyq7ljGIDlhDdwTl
jo0aeu4ObPlgMCc6jC9Coxk62SNt7yVg+brvkX2AmufuwR0lzg7N+g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:aFo7gkxw4ZgbJEkI7UbXwTUwB8DJHZGQ3cjJxTlRuROsoz6ryxzUg6jq0cDHVMrBa+Aj6atU5KUQ/o0krThZzZiL4kAWystxFgHj0IVH5aJBN2R4P5qLzwgofXP0UuTSd5x32hrAi5XVJ4loJGTQBxu/LdBHwOGQTg5Iuclk2K0=,iv:iRWTZnjiCUVCTnB99+wGmOjh6PkGak4PHJrMIs/rptU=,tag:0OgOkXAcsVaeCcXmCTSHjw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
---
apiVersion: v1
kind: Secret
metadata:
name: valkey-secrets
namespace: teable
type: Opaque
stringData:
VALKEY_EXTRA_FLAGS: ENC[AES256_GCM,data:S+rjMu5wNv+Nni1d7/ZZTDoPhqf2TY28xJhgH/FPPmQB5qGpQmkVGoZW9rhsuc6eI7JL7KDRbfPyyoa8,iv:v3pjMJD1RvusZ9+0ppCP3RW3ojpsqQseeitJ8jagvxo=,tag:IQAIFa9vsRmFFDFXAmV8Jg==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFQVVUU3AxN2tnUG1ORmpw
c29YMWErYXl0QmtKVWdjWng2azRBUDJSbnlnClVnSVBlRUJ6NElDWmZOVnJRTUVB
NWVIRm1FUWc2NW14TE9MSnNpVnNPcU0KLS0tIDdrbjhWY3hoZCtROWtPKytXenJ0
eEptQ1R2QlAyeDdnZWdkZGNBcFZxL0EKe5wXjgOEN5hULVrSdyq7ljGIDlhDdwTl
jo0aeu4ObPlgMCc6jC9Coxk62SNt7yVg+brvkX2AmufuwR0lzg7N+g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:aFo7gkxw4ZgbJEkI7UbXwTUwB8DJHZGQ3cjJxTlRuROsoz6ryxzUg6jq0cDHVMrBa+Aj6atU5KUQ/o0krThZzZiL4kAWystxFgHj0IVH5aJBN2R4P5qLzwgofXP0UuTSd5x32hrAi5XVJ4loJGTQBxu/LdBHwOGQTg5Iuclk2K0=,iv:iRWTZnjiCUVCTnB99+wGmOjh6PkGak4PHJrMIs/rptU=,tag:0OgOkXAcsVaeCcXmCTSHjw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,28 @@
apiVersion: v1
kind: Service
metadata:
name: teable
namespace: teable
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: teable
ports:
- protocol: TCP
port: 80
targetPort: 3000
name: http
---
apiVersion: v1
kind: Service
metadata:
name: valkey
namespace: teable
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: valkey
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@@ -0,0 +1,4 @@
resources:
- pvc.yaml
- services.yaml
- statefulset.yaml

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: thelounge-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
storageClassName: nfs-csi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: thelounge
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: thelounge
ports:
- protocol: TCP
port: 80
targetPort: 9000

View File

@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: thelounge
labels:
app.kubernetes.io/name: thelounge
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: thelounge
template:
metadata:
labels:
app.kubernetes.io/name: thelounge
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- 100.96.226.96
volumes:
- name: thelounge-data
persistentVolumeClaim:
claimName: thelounge-pvc
containers:
- name: thelounge
image: ghcr.io/thelounge/thelounge:4.4.3
imagePullPolicy: Always
ports:
- containerPort: 9000
volumeMounts:
- name: thelounge-data
mountPath: "/var/opt/thelounge"

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: vaultwarden-config
data:
DOMAIN: "https://passwords.prettysunflower.moe"
SMTP_HOST: mail.prettysunflower.moe
SMTP_FROM: vaultwarden@prettysunflower.moe
SMTP_PORT: "587"
SMTP_SECURITY: starttls
SMTP_USERNAME: me@prettysunflower.moe
SIGNUPS_DOMAINS_WHITELIST: prettysunflower.moe

View File

@@ -0,0 +1,58 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultwarden
labels:
app.kubernetes.io/name: vaultwarden
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: vaultwarden
template:
metadata:
labels:
app.kubernetes.io/name: vaultwarden
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: location
operator: In
values:
- fsn
volumes:
- name: vaultwarden-data
persistentVolumeClaim:
claimName: vaultwarden-data-pvc
hostAliases:
- ip: "100.113.193.5"
hostnames:
- "mail.prettysunflower.moe"
containers:
- name: teable
image: vaultwarden/server:1.34.1
ports:
- containerPort: 80
name: http
envFrom:
- configMapRef:
name: vaultwarden-config
- secretRef:
name: vaultwarden-secrets
volumeMounts:
- name: vaultwarden-data
mountPath: "/data"
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,6 @@
resources:
- configmap.yaml
- deployment.yaml
- pvc.yaml
- secrets.yaml
- services.yaml

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultwarden-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: nfs-csi

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Secret
metadata:
name: vaultwarden-secrets
type: Opaque
stringData:
SMTP_PASSWORD: ENC[AES256_GCM,data:xyLyid9vbNnZqSZmlOzr0w==,iv:FqgmKBNXi3z6rP2OkpnBvCcrUJFNuyXSZqEveRjHgXc=,tag:uNzVVes83mEIRXX8eONyxg==,type:str]
DATABASE_URL: ENC[AES256_GCM,data:O7ziU0tNyTwlxauvYvKP9cbvmQrGiczq8PVeTiO6TM4G5MX3C44EBGh8toWIFqDH3CtTl3fZ2HWzR4Jz+v8ffhLW886ruOMZLk207PwI2Xhm8rJ5+jPLTtjn,iv:M9V+FFzmlvC3gSPq9X7YFjg8+ag7pEOFsrY2DXuq/8I=,tag:+7Lt8WcIzItetgRcEC0DyA==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCdUhTOGc0TVVyNlNOeHMx
YmxzQSsxUVoyZGlMU29RRk5ERGRjdHdvSlFRCjUrYTkwTXJPQ1J6VGlPbG80YnB2
cjJ1RXNTL1hvZFkvL0o1L1VPMC9pRlEKLS0tIDZXYlRrRGtGcjJac1NWb3lhd0U5
OTFtdU1IUjlrVnlaQ0VBTnludmJTbFEKzWnGs3tiHrmIcYftVn79QxTI5MmzyZCQ
EvnSjD/WyNNf1iXpH9jsvuoFDIiaS3aWh0Y6Lbc4EcnKQWUq/buaIw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-16T14:35:28Z"
mac: ENC[AES256_GCM,data:i/U+lQrXgCcva8ukhSyoqG+f6k5ZiYI8UtBQngud3UnuMnEuyGgY1iuovdsYj1KuGnvZ3d5vnqMIccevQhLXFJVL1LHmRSiLIf2Ugs7r5SsEb7kAFMF2BAtyht75r0oJ/d9Uui+mnxC71GuowRf0uSlIeP545cOb1BebHRk5Y5o=,iv:3FL0djcCnr2UhtO0t52625rALsA25kTUKB4b95Y4nH0=,tag:BnWDkst2Z0wSqV/MmIYqzQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: vaultwarden
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: vaultwarden
ports:
- protocol: TCP
port: 80
targetPort: http