121 Commits

Author SHA1 Message Date
renovate[bot]
9bc0fb78a2 chore(deps): update helm release woodpecker to v1.6.2 2025-12-21 18:52:13 +00:00
Morten Olsen
be53c17847 add woodpecker 2025-12-21 19:51:40 +01:00
renovate[bot]
2ab1db7122 chore(deps): pin dependencies (#50)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-21 12:19:19 +01:00
Morten Olsen
ace5ee7ce5 add forgejo 2025-12-20 23:28:07 +01:00
renovate[bot]
e88c307f23 chore(deps): update docker images (#49)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 22:41:35 +01:00
renovate[bot]
781ba80bfc chore(deps): update docker images (#48)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 16:18:39 +01:00
Morten Olsen
2628e9d7a9 add immich 2025-12-18 22:12:42 +01:00
Morten Olsen
db06db1fee add sealed secrets 2025-12-18 09:35:01 +01:00
renovate[bot]
c9d6b087ae chore(deps): update docker images (#47)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-16 23:04:42 +01:00
renovate[bot]
1fc3d515ed chore(deps): update docker images (#46)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-16 20:26:01 +01:00
renovate[bot]
de59468b00 chore(deps): pin dependencies (#45)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 20:29:49 +01:00
Morten Olsen
5fdd794169 update nuclei 2025-12-13 08:22:17 +01:00
Morten Olsen
6b6b2c4534 bump nuclei operator 2025-12-12 21:54:24 +01:00
Morten Olsen
5412cd1744 update nuclei version 2025-12-12 19:53:56 +01:00
Morten Olsen
b7fb381bbe feat: add nuclei operator 2025-12-12 19:25:15 +01:00
Morten Olsen
4220330245 add drip 2025-12-12 08:39:13 +01:00
Morten Olsen
2b8766c634 switch to calibre-web-automated 2025-12-11 22:56:45 +01:00
renovate[bot]
c0ba17f12b chore(deps): pin dependencies (#43)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:17:55 +01:00
Morten Olsen
c8103869d8 docs: add agent context 2025-12-11 13:16:20 +01:00
renovate[bot]
b76f47d5d1 chore(deps): update docker images to v2 (#44)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:14:07 +01:00
Morten Olsen
02b2e5644d change n8n to external runner 2025-12-09 00:04:15 +01:00
Morten Olsen
fbfe0116da expose ollama internally 2025-12-08 22:24:33 +01:00
Morten Olsen
5773f147b1 add blinko 2025-12-08 22:15:00 +01:00
renovate[bot]
659f2bd778 chore(deps): update docker images (#42)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-08 21:57:01 +01:00
Morten Olsen
7d92c8c489 add apps to zerobyte 2025-12-08 21:48:07 +01:00
Morten Olsen
4eb9647d89 disable backup task 2025-12-08 20:50:57 +01:00
Morten Olsen
1b1997eb6c feat: add falco 2025-12-05 09:10:46 +01:00
Morten Olsen
066c3ce78e add truenas route 2025-12-05 08:46:32 +01:00
renovate[bot]
79d434a79f chore(deps): pin dependencies (#41)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-04 23:36:52 +01:00
Morten Olsen
3062e83482 use strict 2025-12-04 23:33:14 +01:00
renovate[bot]
1325e57188 chore(config): migrate config renovate.json5 (#39)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-04 23:29:10 +01:00
Morten Olsen
c8cf31a151 updated renovate to update apps as well as have a 2 day release age 2025-12-04 23:26:22 +01:00
Morten Olsen
371b703fa2 fix pen pot 2025-12-04 23:09:25 +01:00
Morten Olsen
cde3debdc8 feat: add homebox 2025-12-04 22:37:01 +01:00
Morten Olsen
452e6071cf feat add memos 2025-12-04 21:03:02 +01:00
Morten Olsen
76cf7f4824 feat: add uptime kuma 2025-12-04 20:19:03 +01:00
Morten Olsen
0d1a876dde fix: remove restic frontend 2025-12-04 13:21:23 +01:00
Morten Olsen
e40cc30422 add backup to argo 2025-12-04 13:19:30 +01:00
Morten Olsen
0b0a6f4d6c move environment into argo 2025-12-04 13:11:57 +01:00
renovate[bot]
4db3cd4ed4 chore(deps): pin docker.umami.is/umami-software/umami docker tag to e3ef93b (#37)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-04 11:26:41 +01:00
Morten Olsen
1a5322172f fix: remove empty prop 2025-12-04 11:08:07 +01:00
Morten Olsen
f36a3fab35 feat: add umami 2025-12-04 10:43:26 +01:00
Morten Olsen
8f394b2585 feat: add reloader 2025-12-04 10:20:30 +01:00
Morten Olsen
cc075f3af3 migrate to virtual services 2025-12-04 09:48:53 +01:00
Morten Olsen
0368d4e147 migrate first service to virtual service 2025-12-04 09:32:00 +01:00
Morten Olsen
d9b7dcd154 update kyverne 2025-12-04 09:00:53 +01:00
Morten Olsen
401a08831c disable grafana 2025-12-04 08:48:08 +01:00
Morten Olsen
605f804188 feat: add loki 2025-12-04 08:44:58 +01:00
Morten Olsen
7ec7105aeb add kube prometheus stack 2025-12-04 08:10:11 +01:00
Morten Olsen
7fc1cef442 feat: add kyverno 2025-12-04 08:02:21 +01:00
Morten Olsen
ff000854db scope foundation apps 2025-12-04 07:53:40 +01:00
Morten Olsen
61a12bcc41 fixes 2025-12-03 23:36:50 +01:00
renovate[bot]
c5ac34e274 chore(deps): update docker images (#35)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 23:34:02 +01:00
Morten Olsen
df3ccebafc renovate security guards 2025-12-03 23:33:33 +01:00
Morten Olsen
1851a6a506 cleanup 2025-12-03 23:23:06 +01:00
Morten Olsen
a8e86c3e74 feat: add vikunja 2025-12-03 23:10:39 +01:00
Morten Olsen
448eced634 add-nats 2025-12-03 21:46:59 +01:00
Morten Olsen
37600ea101 add backup 2025-12-03 21:06:57 +01:00
Morten Olsen
e249df8693 add shared resources 2025-12-03 20:23:09 +01:00
Morten Olsen
164570237b feat: add redis operator 2025-12-03 20:08:51 +01:00
Morten Olsen
8f044b62b3 feat: add foundation 2025-12-03 18:46:59 +01:00
Morten Olsen
05bfcfed2c restructure app 2025-12-03 15:58:49 +01:00
renovate[bot]
161a1eb062 chore(deps): update docker images (#33)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 13:54:50 +01:00
Morten Olsen
5b1127912d chore: switch to main 2025-12-03 13:44:06 +01:00
Morten Olsen
1c403e013c Argo (#34)
* update

* migrate remaining applications
2025-12-03 13:31:33 +01:00
renovate[bot]
2abb883c59 chore(deps): update docker images (#32)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 10:17:18 +01:00
renovate[bot]
8a4ed5eaa2 chore(deps): update docker images (#31)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-24 21:46:38 +01:00
Morten Olsen
1484649910 add kids music 2025-11-24 21:46:17 +01:00
Morten Olsen
a2ee42495e add mollysocket 2025-11-20 23:02:59 +01:00
Morten Olsen
63e28f5b64 add ntfy 2025-11-20 21:56:05 +01:00
renovate[bot]
715c8fd368 chore(deps): update docker images (#30)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 23:09:45 +01:00
Morten Olsen
165ac88918 update 2025-11-13 21:28:47 +01:00
Morten Olsen
44bf5469f8 fixes 2025-11-13 21:25:30 +01:00
renovate[bot]
c545e00cc3 chore(deps): update docker images (#29)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-13 20:45:49 +01:00
Morten Olsen
61cf9605a1 switch pigeon pod to latest 2025-11-06 23:00:56 +01:00
renovate[bot]
987bc41a5f chore(deps): update docker images (#28)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-06 22:37:30 +01:00
Morten Olsen
a5ead880e2 add metabase and appsmith 2025-11-05 21:22:57 +01:00
renovate[bot]
cf5e82808d chore(deps): update docker images (#27)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 21:22:09 +01:00
Morten Olsen
df79f42806 update 2025-11-04 14:56:58 +01:00
Morten Olsen
2c399e26f4 update 2025-11-04 14:56:47 +01:00
Morten Olsen
155c6b6702 update reservoir 2025-11-03 21:43:27 +01:00
renovate[bot]
50fb286a7a chore(deps): update docker images (#26)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-03 19:55:20 +01:00
Morten Olsen
df78604473 update 2025-11-03 13:29:43 +01:00
Morten Olsen
f75113c58b update 2025-11-02 20:31:40 +01:00
renovate[bot]
e419c95ad0 chore(deps): update docker images (#25)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-02 20:11:15 +01:00
Morten Olsen
8b0382e402 update 2025-11-02 20:10:26 +01:00
Morten Olsen
cbe5433378 add misc 2025-11-02 19:57:43 +01:00
renovate[bot]
b66ca8a679 chore(deps): update docker images (#24)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-31 12:24:01 +01:00
renovate[bot]
2fc39a703d chore(deps): update docker images (#23)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 18:46:28 +01:00
renovate[bot]
76edc3d29b chore(deps): update docker images (#22)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-25 14:07:39 +02:00
renovate[bot]
fb4ac4b8b6 chore(deps): update valkey/valkey:9.0 docker digest to 4503e20 (#21)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-21 20:32:20 +02:00
renovate[bot]
c4cedcc7f1 chore(deps): update docker images (#20)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-21 20:30:54 +02:00
Morten Olsen
dc66b1a406 pigeon-pod 2025-10-20 23:48:00 +02:00
renovate[bot]
d8caea7ab9 chore(deps): update docker images (#19)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 23:46:18 +02:00
Morten Olsen
f492dd491b feat: add mindsdb 2025-10-20 08:49:53 +02:00
renovate[bot]
875792d13c chore(deps): update docker images (#18)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-16 22:55:03 +02:00
Morten Olsen
522da48024 disable signal 2025-10-16 21:45:47 +02:00
Morten Olsen
c2a8fdb484 penpot fixes 2025-10-16 21:37:11 +02:00
renovate[bot]
ca1f088c0b chore(deps): update docker images (#17)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-16 21:36:34 +02:00
renovate[bot]
9f8df6c155 chore(deps): pin dependencies (#16)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 23:35:33 +02:00
Morten Olsen
4b77be0ccd add tika 2025-10-13 22:23:30 +02:00
renovate[bot]
797dc5d187 chore(deps): update docker images (#15)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-12 20:38:56 +02:00
Morten Olsen
d9f4d9c560 fix: metamcp oidc 2025-10-10 12:33:05 +02:00
renovate[bot]
5fcf7ee097 chore(deps): update docker images (#14)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-09 10:41:38 +00:00
renovate[bot]
c044298666 chore(deps): pin dependencies (#13)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-08 17:43:51 +00:00
Morten Olsen
86ffd441ca update 2025-10-07 19:49:54 +02:00
renovate[bot]
a1210f51c1 chore(deps): update docker images (#12)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-07 19:26:14 +02:00
Morten Olsen
56f5d1e65f fix: incorrect zot secret name 2025-10-06 14:40:31 +02:00
renovate[bot]
f2dcc2e4c2 chore(deps): update docker images (#11)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 14:38:21 +02:00
Morten Olsen
4d5cfa2717 add gitea runner 2025-10-01 22:42:05 +02:00
renovate[bot]
0df579eba5 chore(deps): pin dependencies (#10)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-01 22:34:54 +02:00
Morten Olsen
57e06bc8e9 pin penpot version 2025-10-01 22:32:53 +02:00
renovate[bot]
091138dfd4 chore(deps): update docker images (#8)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-01 22:31:30 +02:00
renovate[bot]
4300f733cb chore(deps): update valkey/valkey docker tag to v9 (#9)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-01 22:30:45 +02:00
Morten Olsen
b22478d36f added penpot 2025-10-01 20:37:06 +02:00
Morten Olsen
172f0cb8a0 chore: move globals to root 2025-09-30 23:51:42 +02:00
renovate[bot]
64b7738f64 Migrate config renovate.json5 (#7)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-30 15:15:55 +02:00
renovate[bot]
62b212801f Pin dependencies (#6)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-30 14:47:35 +02:00
Morten Olsen
10c2606976 move version pinning 2025-09-30 14:46:36 +02:00
Morten Olsen
1387c4dcd4 part one of version migration 2025-09-30 14:39:58 +02:00
renovate[bot]
e3163b1985 Update Docker images (#5)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-30 14:27:37 +02:00
471 changed files with 4980 additions and 1033 deletions

16
.yamllint Normal file
View File

@@ -0,0 +1,16 @@
---
extends: default
rules:
line-length:
max: 120
level: warning
indentation:
spaces: 2
indent-sequences: true
comments:
min-spaces-from-content: 1
document-start: disable
truthy:
allowed-values: ['true', 'false', 'on', 'off']

453
AGENTS.md Normal file
View File

@@ -0,0 +1,453 @@
# Application Helm Charts Guide
This document provides guidelines for creating and maintaining Helm charts in this homelab project.
## Project Structure
```
apps/
├── charts/ # Individual application Helm charts
│ ├── app-name/
│ │ ├── Chart.yaml
│ │ ├── values.yaml
│ │ └── templates/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ ├── pvc.yaml
│ │ ├── client.yaml # OIDC client configuration
│ │ ├── database.yaml # Database provisioning
│ │ ├── secret.yaml # Secret generation
│ │ └── external-http-service.yaml
│ └── ...
└── root/ # ArgoCD ApplicationSet for auto-discovery
├── Chart.yaml
├── values.yaml
└── templates/
├── applicationset.yaml
└── project.yaml
foundation/
├── charts/ # Foundation service Helm charts
│ └── ...
└── root/ # ArgoCD ApplicationSet for foundation services
shared/
├── charts/ # Shared service Helm charts
│ └── ...
└── root/ # ArgoCD ApplicationSet for shared services
```
## ArgoCD ApplicationSets
This project uses three separate ArgoCD ApplicationSets to manage different categories of services:
1. **apps/** - Individual applications (web apps, tools, services)
2. **foundation/** - Core infrastructure for the cluster (monitoring, certificates, operators)
3. **shared/** - Infrastructure shared between applications (databases, message queues, caches)
Each category has its own `root/` chart containing an ApplicationSet that auto-discovers and deploys charts from its respective `charts/` directory.
## Creating a New Application Chart
### 1. Basic Chart Structure
Create a new directory under `apps/charts/` with the following structure:
```bash
mkdir -p apps/charts/my-app/templates
```
#### Chart.yaml
```yaml
apiVersion: v2
version: 1.0.0
name: my-app
```
#### values.yaml
```yaml
image:
repository: docker.io/org/my-app
tag: v1.0.0
pullPolicy: IfNotPresent
subdomain: my-app
```
### 2. Core Templates
#### Deployment Template
Create `templates/deployment.yaml`:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}"
spec:
strategy:
type: Recreate
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: "{{ .Release.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}"
spec:
containers:
- name: "{{ .Release.Name }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
tcpSocket:
port: http
readinessProbe:
tcpSocket:
port: http
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-data"
```
#### Service Template
Create `templates/service.yaml`:
```yaml
apiVersion: v1
kind: Service
metadata:
name: "{{ .Release.Name }}"
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: "{{ .Release.Name }}"
```
#### Persistent Volume Claim
Create `templates/pvc.yaml`:
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ .Release.Name }}-data"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```
## Custom Resource Definitions (CRDs)
This project uses several custom resources that are managed by operators in the cluster:
### 1. OIDC Client (OpenID Connect Authentication)
The `OidcClient` resource automatically provisions OAuth2/OIDC clients with your identity provider.
Create `templates/client.yaml`:
```yaml
apiVersion: homelab.mortenolsen.pro/v1
kind: OidcClient
metadata:
name: '{{ .Release.Name }}'
spec:
environment: '{{ .Values.globals.environment }}'
redirectUris:
- path: /oauth/oidc/callback
subdomain: '{{ .Values.subdomain }}'
matchingMode: strict
```
**What it does:**
- Creates an OIDC client in your identity provider (e.g., Authentik)
- Generates a Kubernetes secret named `{{ .Release.Name }}-client` containing:
- `clientId`: The OAuth client ID
- `clientSecret`: The OAuth client secret
- `configuration`: The OIDC provider URL
**Using in deployment:**
```yaml
env:
- name: OAUTH_CLIENT_ID
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: clientId
- name: OAUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: clientSecret
- name: OPENID_PROVIDER_URL
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: configuration
```
### 2. PostgreSQL Database
The `PostgresDatabase` resource automatically provisions PostgreSQL databases.
Create `templates/database.yaml`:
```yaml
apiVersion: homelab.mortenolsen.pro/v1
kind: PostgresDatabase
metadata:
name: '{{ .Release.Name }}'
spec:
environment: '{{ .Values.globals.environment }}'
```
**What it does:**
- Creates a PostgreSQL database with the same name as your release
- Creates a user with appropriate permissions
- Generates a Kubernetes secret named `{{ .Release.Name }}-database` containing:
- `url`: Complete PostgreSQL connection URL
- `host`: Database hostname
- `port`: Database port
- `database`: Database name
- `username`: Database username
- `password`: Database password
**Using in deployment:**
```yaml
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-database"
key: url
```
### 3. Secret Generation
The `GenerateSecret` resource creates secure random secrets.
Create `templates/secret.yaml`:
```yaml
apiVersion: homelab.mortenolsen.pro/v1
kind: GenerateSecret
metadata:
name: "{{ .Release.Name }}-secrets"
spec:
fields:
- name: encryptionkey
encoding: hex # Options: hex, base64, alphanumeric
length: 64 # Length in bytes (before encoding)
- name: apitoken
encoding: base64
length: 32
```
**What it does:**
- Generates cryptographically secure random values
- Creates a Kubernetes secret with the specified fields
- Supports different encoding formats for different use cases
**Using in deployment:**
```yaml
env:
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-secrets"
key: encryptionkey
```
### 4. External HTTP Service
The `ExternalHttpService` resource configures ingress routing for your application.
Create `templates/external-http-service.yaml`:
```yaml
apiVersion: homelab.mortenolsen.pro/v1
kind: ExternalHttpService
metadata:
name: '{{ .Release.Name }}'
spec:
environment: '{{ .Values.globals.environment }}'
subdomain: '{{ .Values.subdomain }}'
destination:
host: '{{ .Release.Name }}.{{ .Release.Namespace }}.svc.cluster.local'
port:
number: 80
```
**What it does:**
- Creates ingress routes for your application
- Configures subdomain routing (e.g., `myapp.yourdomain.com`)
- Handles TLS termination automatically
- Integrates with your service mesh (if applicable)
## Best Practices
### 1. Naming Conventions
- Use `{{ .Release.Name }}` consistently for all resource names
- Suffix resource names appropriately: `-data`, `-secrets`, `-client`, `-database`
### 2. Container Configuration
- Always specify health checks (liveness and readiness probes)
- Use named ports (e.g., `http`, `grpc`) instead of port numbers
- Set `revisionHistoryLimit: 0` to prevent accumulation of old ReplicaSets
### 3. Environment Variables
- Never hardcode secrets in values.yaml
- Use secretKeyRef to reference generated secrets
- Group related environment variables together
### 4. Persistent Storage
- Always use PVCs for stateful data
- Consider storage requirements carefully (start with reasonable defaults)
- Mount data at standard paths for the application
### 5. OIDC Integration
- Set `ENABLE_SIGNUP: "false"` if using OIDC
- Enable OIDC signup with `ENABLE_OAUTH_SIGNUP: "true"`
- Configure email merging if needed with `OAUTH_MERGE_ACCOUNTS_BY_EMAIL`
### 6. Database Usage
- Only include database.yaml if the app needs PostgreSQL
- Applications should support DATABASE_URL environment variable
- Consider connection pooling settings for production
## Disabling Applications
To temporarily disable an application, rename its directory with `.disabled` suffix:
```bash
mv apps/charts/my-app apps/charts/my-app.disabled
```
The ArgoCD ApplicationSet will automatically exclude directories matching `*.disabled`.
## Testing Your Chart
1. **Lint your chart:**
```bash
helm lint apps/charts/my-app
```
2. **Render templates locally:**
```bash
helm template my-app apps/charts/my-app
```
3. **Dry run installation:**
```bash
helm install my-app apps/charts/my-app --dry-run --debug
```
## Deployment Workflow
**IMPORTANT:** There is no test environment. When creating or modifying applications:
1. **Make changes directly to the files** - The agent will write changes to the actual chart files
2. **User deploys the changes** - After changes are made, the user must deploy them to the cluster
3. **Debug with kubectl** - If issues arise after deployment, agents can use kubectl to:
- Check pod status and logs
- Inspect generated resources
- Verify secret creation
- Troubleshoot configuration issues
**Note:** Agents cannot deploy applications themselves. They can only:
- Create and modify chart files
- Use kubectl to investigate deployment issues
- Provide debugging assistance and recommendations
## Common Patterns
### Application with OIDC + Database
For apps requiring both authentication and database:
- Include `client.yaml` for OIDC
- Include `database.yaml` for PostgreSQL
- Reference both secrets in deployment
### Stateless Applications
For simple stateless apps:
- Omit `pvc.yaml`
- Remove volume mounts from deployment
- Consider using `Deployment` scaling if appropriate
### Background Services
For services without web interface:
- Omit `external-http-service.yaml`
- Omit `client.yaml` (no OIDC needed)
- Focus on service discovery within cluster
## Troubleshooting
### Secret Not Found
If secrets are not being created:
1. Check that the CRD controller is running
2. Verify the `environment` value matches your setup
3. Check controller logs for provisioning errors
### OIDC Issues
1. Verify redirect URIs match exactly
2. Check that the identity provider is accessible
3. Ensure the client secret is being properly mounted
### Database Connection
1. Verify the database operator is running
2. Check network policies between namespaces
3. Ensure the database server has capacity
## Global Values
Applications can access global values through `{{ .Values.globals }}`:
- `environment`: The deployment environment (e.g., "production", "staging")
- Additional values can be added at the root chart level
## Maintenance
### Updating Images
1. Update the tag in `values.yaml`:
```yaml
tag: v1.0.0 # Use semantic version tags only
```
2. **Note:** Do not include SHA digests in tags. Immutable digests are automatically added later by Renovate
### Renovate Integration
The project uses Renovate for automated dependency updates. Configure in `renovate.json5` to:
- Auto-update container images
- Create pull requests for updates
- Group related updates
### Backup Considerations
For applications with persistent data:
1. Consider implementing backup CronJobs
2. Use volume snapshots if available
3. Export data regularly for critical applications
## Contributing
When adding new applications:
1. Follow the existing patterns and conventions
2. Document any special requirements in the chart's README
3. Consider security implications of all configurations
4. Update this document if introducing new patterns
## Maintaining This Document
**IMPORTANT:** When making changes to the project structure, patterns, or custom resources:
- Keep this AGENTS.md file up to date with any changes
- Document new CRDs or custom resources as they are added
- Update examples if the patterns change
- Add new sections for significant new features or patterns
- Ensure all code examples remain accurate and tested
This document serves as the primary reference for creating and maintaining applications in this project. Keeping it current ensures consistency and helps onboard new contributors.

30
apps.yaml Normal file
View File

@@ -0,0 +1,30 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: apps-data
labels:
type: local
spec:
capacity:
storage: 5Gi # Adjust this to your desired size
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # Retain the data even if the PV is deleted
storageClassName: "manual-app-data"
hostPath:
path: "/data/volumes" # The specific host path for your 'apps' volume
type: DirectoryOrCreate # Ensures the directory exists on the host
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: apps-data
namespace: prod # Specify the namespace
spec:
storageClassName: "manual-app-data"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # Must match or be less than the PV's capacity

View File

@@ -1,3 +1,3 @@
apiVersion: v2 apiVersion: v2
version: 1.0.0 version: 1.0.0
name: monitoring name: appsmith

View File

@@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}"
labels:
app: "{{ .Release.Name }}"
spec:
replicas: 1
selector:
matchLabels:
app: "{{ .Release.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}"
spec:
containers:
- name: "{{ .Release.Name }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
name: http
env:
volumeMounts:
- mountPath: /appsmith-stacks
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-data"

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,4 @@
subdomain: appsmith
image:
repository: index.docker.io/appsmith/appsmith-ce
tag: latest@sha256:0776a0a9665919800d22fc736956ec54fedd16a9a30f9d4ad3f3fc0fd8ac8694

View File

@@ -8,7 +8,7 @@ spec:
type: ClusterIP type: ClusterIP
ports: ports:
- port: 80 - port: 80
targetPort: 5678 targetPort: 80
protocol: TCP protocol: TCP
name: http name: http
selector: selector:

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: ghcr.io/advplyr/audiobookshelf
tag: 2.31.0@sha256:e23adb24848d99d19cd1e251aee4e1e12ed4f5effc8ccb21754b062b6a06cf66
pullPolicy: IfNotPresent
subdomain: audiobookshelf

View File

@@ -4,7 +4,7 @@ globals:
domain: olsen.cloud domain: olsen.cloud
image: image:
repository: garethgeorge/backrest repository: garethgeorge/backrest
tag: latest@sha256:f8306faef0a3cbedc7daa55756f1d4c105d8c104aa773656bdad4fa8553dab5a tag: latest@sha256:1308397161321b3c5aeca8acc6bf26eccb990df385f2532d3ce0eaa8b483dedf
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
subdomain: restic subdomain: restic
password: password:

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: docker.io/ckulka/baikal
tag: 0.10.1-nginx@sha256:434bdd162247cc6aa6f878c9b4dce6216e39e79526b980453b13812d5f8ebf4b
pullPolicy: IfNotPresent
subdomain: baikal

View File

@@ -1,3 +1,3 @@
apiVersion: v2 apiVersion: v2
version: 1.0.0 version: 1.0.0
name: apprise name: blinko

View File

@@ -0,0 +1,10 @@
apiVersion: homelab.mortenolsen.pro/v1
kind: OidcClient
metadata:
name: "{{ .Release.Name }}"
spec:
environment: "{{ .Values.globals.environment }}"
redirectUris:
- path: api/auth/callback/authentik
subdomain: "{{ .Values.subdomain }}"
matchingMode: strict

View File

@@ -0,0 +1,57 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}"
spec:
strategy:
type: RollingUpdate
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: "{{ .Release.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}"
spec:
containers:
- name: "{{ .Release.Name }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
ports:
- name: http
containerPort: 1111
protocol: TCP
livenessProbe:
tcpSocket:
port: http
readinessProbe:
tcpSocket:
port: http
volumeMounts:
- mountPath: /data
name: data
env:
- name: TZ
value: "{{ .Values.globals.timezone }}"
- name: NODE_ENV
value: "production"
- name: NEXTAUTH_URL
value: "https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- name: NEXT_PUBLIC_BASE_URL
value: "https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-secrets"
key: betterauth
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-pg-connection"
key: url
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-data"

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: '{{ .Release.Name }}'
labels:
app: '{{ .Release.Name }}'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 1111
protocol: TCP
name: http
selector:
app: '{{ .Release.Name }}'

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: blinkospace/blinko
tag: latest@sha256:04ad2a67f617e122db98425d39c2d0d901492729b3aee5a7e8c4d351009ee9e9
pullPolicy: IfNotPresent
subdomain: blinko

View File

@@ -16,7 +16,7 @@ spec:
spec: spec:
containers: containers:
- name: "{{ .Release.Name }}" - name: "{{ .Release.Name }}"
image: ghcr.io/jordan-dalby/bytestash:latest image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports: ports:
- containerPort: 5000 - containerPort: 5000
name: http name: http

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,4 @@
subdomain: bytestash
image:
repository: ghcr.io/jordan-dalby/bytestash
tag: 1.5.9@sha256:9c17b5510ca45c976fe23b0d4705ad416aa58d4bf756a70e03ef1f08cf7801fd

View File

@@ -24,6 +24,8 @@ spec:
env: env:
- name: TZ - name: TZ
value: "{{ .Values.globals.timezone }}" value: "{{ .Values.globals.timezone }}"
- name: NETWORK_SHARE_MODE
value: "true"
- name: PUID - name: PUID
value: "1000" value: "1000"
- name: PGID - name: PGID
@@ -31,7 +33,7 @@ spec:
volumeMounts: volumeMounts:
- mountPath: /config - mountPath: /config
name: data name: data
- mountPath: /books - mountPath: /calibre-library
name: books name: books
volumes: volumes:
- name: data - name: data

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: crocodilestick/calibre-web-automated
tag: latest@sha256:577e846f104fd21453ef306eefb4a95dd95b3b9ddd2463a150944494284da0fd
pullPolicy: IfNotPresent
subdomain: calibre-web

View File

@@ -1,24 +1,25 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: '{{ .Release.Name }}' name: "{{ .Release.Name }}"
spec: spec:
strategy: strategy:
type: Recreate type: Recreate
replicas: 1 replicas: 1
revisionHistoryLimit: 0
selector: selector:
matchLabels: matchLabels:
app: '{{ .Release.Name }}' app: "{{ .Release.Name }}"
template: template:
metadata: metadata:
labels: labels:
app: '{{ .Release.Name }}' app: "{{ .Release.Name }}"
spec: spec:
serviceAccountName: '{{ .Release.Name }}-serviceaccount' serviceAccountName: "{{ .Release.Name }}-serviceaccount"
containers: containers:
- name: '{{ .Release.Name }}' - name: "{{ .Release.Name }}"
image: '{{ .Values.image.repository }}:{{ .Values.image.tag }}' image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: '{{ .Values.image.pullPolicy }}' imagePullPolicy: "{{ .Values.image.pullPolicy }}"
ports: ports:
- name: http - name: http
containerPort: 7080 containerPort: 7080
@@ -34,7 +35,7 @@ spec:
name: data name: data
env: env:
- name: CODER_HTTP_ADDRESS - name: CODER_HTTP_ADDRESS
value: '0.0.0.0:7080' value: "0.0.0.0:7080"
- name: CODER_OIDC_ALLOWED_GROUPS - name: CODER_OIDC_ALLOWED_GROUPS
value: admin value: admin
- name: CODER_OIDC_GROUP_FIELD - name: CODER_OIDC_GROUP_FIELD
@@ -44,30 +45,30 @@ spec:
- name: CODER_OIDC_ICON_URL - name: CODER_OIDC_ICON_URL
value: https://authentik.olsen.cloud/static/dist/assets/icons/icon.png value: https://authentik.olsen.cloud/static/dist/assets/icons/icon.png
- name: CODER_DISABLE_PASSWORD_AUTH - name: CODER_DISABLE_PASSWORD_AUTH
value: 'true' value: "true"
- name: CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS - name: CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS
value: 'false' value: "false"
- name: CODER_OIDC_SIGN_IN_TEXT - name: CODER_OIDC_SIGN_IN_TEXT
value: 'Sign in with OIDC' value: "Sign in with OIDC"
- name: CODER_OIDC_SCOPES - name: CODER_OIDC_SCOPES
value: openid,profile,email,offline_access value: openid,profile,email,offline_access
- name: CODER_OIDC_ISSUER_URL - name: CODER_OIDC_ISSUER_URL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: '{{ .Release.Name }}-client' name: "{{ .Release.Name }}-client"
key: configurationIssuer key: configurationIssuer
- name: CODER_OIDC_CLIENT_ID - name: CODER_OIDC_CLIENT_ID
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: '{{ .Release.Name }}-client' name: "{{ .Release.Name }}-client"
key: clientId key: clientId
- name: CODER_OIDC_CLIENT_SECRET - name: CODER_OIDC_CLIENT_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: '{{ .Release.Name }}-client' name: "{{ .Release.Name }}-client"
key: clientSecret key: clientSecret
volumes: volumes:
- name: data - name: data
persistentVolumeClaim: persistentVolumeClaim:
claimName: '{{ .Release.Name }}-data' claimName: "{{ .Release.Name }}-data"

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: ghcr.io/coder/coder
tag: v2.29.1@sha256:19b3ecd02510b4ee91ba488c61a3f40a6c164c9aeef38999c855e55fd653097c
pullPolicy: IfNotPresent
subdomain: coder

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,3 @@
apiVersion: v2
version: 1.0.0
name: drip

View File

@@ -0,0 +1,80 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}"
spec:
strategy:
type: Recreate
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: "{{ .Release.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}"
spec:
containers:
- name: "{{ .Release.Name }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
- name: tcp-tunnel-min
containerPort: {{ .Values.service.tcpPortMin }}
protocol: TCP
- name: tcp-tunnel-max
containerPort: {{ .Values.service.tcpPortMax }}
protocol: TCP
volumeMounts:
- mountPath: /app/data
name: data
env:
- name: TZ
value: UTC
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-secrets"
key: authtoken
- name: DOMAIN
value: "{{ .Values.subdomain }}.{{ .Values.globals.environment }}"
command:
- drip-server
- --domain
- "{{ .Values.subdomain }}.{{ .Values.globals.environment }}"
- --port
- "{{ .Values.service.port }}"
- --token
- "$(AUTH_TOKEN)"
- --tcp-port-min
- "{{ .Values.service.tcpPortMin }}"
- --tcp-port-max
- "{{ .Values.service.tcpPortMax }}"
livenessProbe:
exec:
command: {{ .Values.healthcheck.test }}
initialDelaySeconds: {{ .Values.healthcheck.startPeriod | default 0 | trimSuffix "s" | int }}
periodSeconds: {{ .Values.healthcheck.interval | default 10 | trimSuffix "s" | int }}
timeoutSeconds: {{ .Values.healthcheck.timeout | default 1 | trimSuffix "s" | int }}
failureThreshold: {{ .Values.healthcheck.retries | default 3 }}
readinessProbe:
exec:
command: {{ .Values.healthcheck.test }}
initialDelaySeconds: {{ .Values.healthcheck.startPeriod | default 0 | trimSuffix "s" | int }}
periodSeconds: {{ .Values.healthcheck.interval | default 10 | trimSuffix "s" | int }}
timeoutSeconds: {{ .Values.healthcheck.timeout | default 1 | trimSuffix "s" | int }}
failureThreshold: {{ .Values.healthcheck.retries | default 3 }}
resources:
limits:
cpu: "{{ .Values.resources.limits.cpu }}"
memory: "{{ .Values.resources.limits.memory }}"
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-data"

View File

@@ -0,0 +1,11 @@
apiVersion: homelab.mortenolsen.pro/v1
kind: ExternalHttpService
metadata:
name: '{{ .Release.Name }}'
spec:
environment: '{{ .Values.globals.environment }}'
subdomain: '{{ .Values.subdomain }}'
destination:
host: '{{ .Release.Name }}.{{ .Release.Namespace }}.svc.cluster.local'
port:
number: {{ .Values.service.port }}

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ .Release.Name }}-data"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: '{{ .Values.globals.environment }}'

View File

@@ -0,0 +1,9 @@
apiVersion: homelab.mortenolsen.pro/v1
kind: GenerateSecret
metadata:
name: "{{ .Release.Name }}-secrets"
spec:
fields:
- name: authtoken
encoding: hex
length: 64

View File

@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ .Release.Name }}"
spec:
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
- port: {{ .Values.service.tcpPortMin }}
targetPort: tcp-tunnel-min
protocol: TCP
name: tcp-tunnel-min
- port: {{ .Values.service.tcpPortMax }}
targetPort: tcp-tunnel-max
protocol: TCP
name: tcp-tunnel-max
selector:
app: "{{ .Release.Name }}"

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,27 @@
image:
repository: ghcr.io/gouryella/drip
tag: latest@sha256:440bcfd7eb75bf0b337d60346e44ae9e5be803e2504697ea7aa1b4f5fce568b9
pullPolicy: IfNotPresent
subdomain: drip
service:
port: 443
tcpPortMin: 20000
tcpPortMax: 20100
resources:
limits:
cpu: 1
memory: 512Mi
healthcheck:
test:
- wget
- --no-verbose
- --tries=1
- --spider
- http://localhost:443/health
interval: 30s
timeout: 3s
retries: 3
startPeriod: 10s

View File

@@ -0,0 +1,3 @@
apiVersion: v2
version: 1.0.0
name: environment

View File

@@ -0,0 +1,9 @@
apiVersion: homelab.mortenolsen.pro/v1
kind: Environment
metadata:
name: "{{ .Values.globals.environment }}"
spec:
domain: "{{ .Values.globals.domain }}"
networkIp: 192.168.20.180
tls:
issuer: lets-encrypt-prod

View File

@@ -0,0 +1,4 @@
globals:
environment: prod
timezone: Europe/Amsterdam
domain: olsen.cloud

View File

@@ -6,6 +6,7 @@ spec:
strategy: strategy:
type: Recreate type: Recreate
replicas: 1 replicas: 1
revisionHistoryLimit: 0
selector: selector:
matchLabels: matchLabels:
app: "{{ .Release.Name }}" app: "{{ .Release.Name }}"

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,5 @@
image:
repository: ghcr.io/esphome/esphome
tag: 2025.12.1@sha256:3a81bf977aca174a74800e33baa11565a77c3f56b574206087555349c6f275bc
pullPolicy: IfNotPresent
subdomain: esphome

View File

@@ -0,0 +1,8 @@
apiVersion: v2
version: 1.0.0
name: forgejo
dependencies:
- name: woodpecker
version: 1.6.2
repository: https://woodpecker-ci.org/

View File

@@ -0,0 +1,106 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}"
spec:
strategy:
type: Recreate
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: "{{ .Release.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}"
spec:
containers:
- name: "{{ .Release.Name }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
ports:
- name: http
containerPort: 3000
protocol: TCP
- name: ssh
containerPort: 22
protocol: TCP
livenessProbe:
tcpSocket:
port: http
readinessProbe:
tcpSocket:
port: http
volumeMounts:
- mountPath: /data
name: data
env:
- name: TZ
value: "{{ .Values.globals.timezone }}"
- name: USER_UID
value: "1000"
- name: USER_GID
value: "1000"
- name: FORGEJO__server__SSH_DOMAIN
value: "ssh-{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- name: FORGEJO__server__SSH_PORT
value: "2206"
- name: FORGEJO__service__REQUIRE_EXTERNAL_REGISTRATION_PASSWORD
value: "true"
#- name: FORGEJO__service__ENABLE_BASIC_AUTHENTICATION
# value: 'true'
- name: FORGEJO__service__ENABLE_PASSWORD_SIGNIN_FORM
value: "false"
- name: FORGEJO__service__DEFAULT_KEEP_EMAIL_PRIVATE
value: "true"
- name: FORGEJO__service__DEFAULT_USER_IS_RESTRICTED
value: "true"
- name: FORGEJO__service__DEFAULT_USER_VISIBILITY
value: "private"
- name: FORGEJO__service__DEFAULT_ORG_VISIBILITY
value: "private"
- name: FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION
value: "true"
- name: FORGEJO__other__SHOW_FOOTER_POWERED_BY
value: "false"
- name: FORGEJO__other__SHOW_FOOTER_TEMPLATE_LOAD_TIME
value: "false"
- name: FORGEJO__other__SHOW_FOOTER_VERSION
value: "false"
- name: FORGEJO__repository__ENABLE_PUSH_CREATE_USER
value: "true"
- name: FORGEJO__repository__ENABLE_PUSH_CREATE_ORG
value: "true"
- name: FORGEJO__openid__ENABLE_OPENID_SIGNIN
value: "false"
- name: FORGEJO__openid__ENABLE_OPENID_SIGNUP
value: "false"
- name: FORGEJO__database__DB_TYPE
value: postgres
- name: FORGEJO__database__NAME
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-pg-connection"
key: database
- name: FORGEJO__database__HOST
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-pg-connection"
key: host
- name: FORGEJO__database__DB_PORT
value: "5432"
- name: FORGEJO__database__USER
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-pg-connection"
key: user
- name: FORGEJO__database__PASSWD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-pg-connection"
key: password
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ .Release.Name }}-data"

View File

@@ -0,0 +1,32 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ .Release.Name }}"
labels:
app: "{{ .Release.Name }}"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 3000
protocol: TCP
name: http
selector:
app: "{{ .Release.Name }}"
---
apiVersion: v1
kind: Service
metadata:
name: "{{ .Release.Name }}-ssh"
labels:
app: "{{ .Release.Name }}"
spec:
type: LoadBalancer
ports:
- port: 2206
targetPort: 22
protocol: TCP
name: ssh
selector:
app: "{{ .Release.Name }}"

View File

@@ -0,0 +1,18 @@
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: "{{ .Release.Name }}"
namespace: "{{ .Release.Namespace }}"
spec:
gateways:
- "{{ .Values.globals.istio.gateway }}"
- mesh
hosts:
- "{{ .Values.subdomain }}.{{ .Values.globals.domain }}"
- mesh
http:
- route:
- destination:
host: "{{ .Release.Name }}"
port:
number: 80

View File

@@ -0,0 +1,13 @@
apiVersion: homelab.mortenolsen.pro/v1
kind: ExternalHttpService
metadata:
name: "{{ .Release.Name }}-woodpecker"
spec:
environment: '{{ .Values.globals.environment }}'
subdomain: 'woodpecker'
destination:
host: '{{ .Release.Name }}-woodpecker-server.{{ .Release.Namespace }}.svc.cluster.local'
port:
number: 80

View File

@@ -0,0 +1,13 @@
image:
repository: codeberg.org/forgejo/forgejo
tag: 13
pullPolicy: IfNotPresent
subdomain: code
woodpecker:
server:
env:
- name: WOODPECKER_GITEA
value: "true"
agent:
enabled: true

View File

@@ -5,6 +5,6 @@ metadata:
spec: spec:
environment: '{{ .Values.globals.environment }}' environment: '{{ .Values.globals.environment }}'
redirectUris: redirectUris:
- path: /oauth/oidc/callback - path: /user/oauth2/Authentik/callback
subdomain: '{{ .Values.subdomain }}' subdomain: '{{ .Values.subdomain }}'
matchingMode: strict matchingMode: strict

Some files were not shown because too many files have changed in this diff Show More