migrate miniflux

This commit is contained in:
Morten Olsen
2026-01-02 10:42:06 +01:00
parent 4f88506ba7
commit b64ce72f3c
12 changed files with 255 additions and 159 deletions

View File

@@ -1,3 +1,7 @@
apiVersion: v2 apiVersion: v2
version: 1.0.0 version: 1.0.0
name: miniflux name: miniflux
dependencies:
- name: common
version: 1.0.0
repository: file://../../common

View File

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

View File

@@ -1,6 +1 @@
apiVersion: homelab.mortenolsen.pro/v1 {{ include "common.database" . }}
kind: PostgresDatabase
metadata:
name: '{{ .Release.Name }}'
spec:
environment: '{{ .Values.globals.environment }}'

View File

@@ -1,75 +1 @@
apiVersion: apps/v1 {{ include "common.deployment" . }}
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: 8080
protocol: TCP
livenessProbe:
tcpSocket:
port: http
readinessProbe:
tcpSocket:
port: http
volumeMounts:
- mountPath: /data
name: data
env:
- name: TZ
value: "{{ .Values.globals.timezone }}"
- name: BASE_URL
value: https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}
- name: RUN_MIGRATIONS
value: "1"
- name: DISABLE_LOCAL_AUTH
value: "1"
- name: OAUTH2_CLIENT_ID
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: clientId
- name: OAUTH2_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: clientSecret
- name: OAUTH2_OIDC_DISCOVERY_ENDPOINT
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-client"
key: configurationIssuer
- name: OAUTH2_OIDC_PROVIDER_NAME
value: Authentik
- name: OAUTH2_PROVIDER
value: oidc
- name: OAUTH2_REDIRECT_URL
value: https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}/oauth2/oidc/callback
- name: OAUTH2_USER_CREATION
value: "1"
- 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 @@
{{ include "common.oidc" . }}

View File

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

View File

@@ -1,15 +1 @@
apiVersion: v1 {{ include "common.service" . }}
kind: Service
metadata:
name: "{{ .Release.Name }}"
labels:
app: "{{ .Release.Name }}"
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: "{{ .Release.Name }}"

View File

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

View File

@@ -2,4 +2,85 @@ image:
repository: ghcr.io/miniflux/miniflux repository: ghcr.io/miniflux/miniflux
tag: latest@sha256:9a1f95a7a05b77040d19bb7be96194af4c222de02fb84165fb808f65700c064f tag: latest@sha256:9a1f95a7a05b77040d19bb7be96194af4c222de02fb84165fb808f65700c064f
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
subdomain: miniflux subdomain: miniflux
# Deployment configuration
deployment:
strategy: RollingUpdate
replicas: 1
revisionHistoryLimit: 0
# Container configuration
container:
port: 8080
healthProbe:
type: tcpSocket
port: http # Use named port
# Service configuration
service:
port: 80
type: ClusterIP
# Volume configuration
volumes:
- name: data
mountPath: /data
persistentVolumeClaim: data
# Persistent volume claims
persistentVolumeClaims:
- name: data
size: 1Gi
# VirtualService configuration
virtualService:
enabled: true
gateways:
public: true
private: true
# OIDC client
oidc:
enabled: true
redirectUris:
- "/oauth2/oidc/callback"
# Database configuration
database:
enabled: true
# Environment variables
env:
TZ:
value: "{timezone}"
BASE_URL:
value: "https://{subdomain}.{domain}"
RUN_MIGRATIONS: "1"
DISABLE_LOCAL_AUTH: "1"
OAUTH2_CLIENT_ID:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials"
key: clientId
OAUTH2_CLIENT_SECRET:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials"
key: clientSecret
OAUTH2_OIDC_DISCOVERY_ENDPOINT:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials"
key: issuer
OAUTH2_OIDC_PROVIDER_NAME: Authentik
OAUTH2_PROVIDER: oidc
OAUTH2_REDIRECT_URL:
value: "https://{subdomain}.{domain}/oauth2/oidc/callback"
OAUTH2_USER_CREATION: "1"
DATABASE_URL:
valueFrom:
secretKeyRef:
name: "{release}-connection"
key: url

View File

@@ -5,6 +5,7 @@ This guide explains how to migrate existing Helm charts to use the common librar
## Overview ## Overview
Migrating a chart to use the common library involves: Migrating a chart to use the common library involves:
1. Adding the common library as a dependency 1. Adding the common library as a dependency
2. Restructuring `values.yaml` to match the standardized format 2. Restructuring `values.yaml` to match the standardized format
3. Replacing template files with simple includes 3. Replacing template files with simple includes
@@ -37,7 +38,8 @@ dependencies:
Convert your existing `values.yaml` to the standardized format: Convert your existing `values.yaml` to the standardized format:
#### Before (Old Format): #### Before (Old Format)
```yaml ```yaml
image: image:
repository: docker.io/org/app repository: docker.io/org/app
@@ -45,7 +47,8 @@ image:
subdomain: myapp subdomain: myapp
``` ```
#### After (Standardized Format): #### After (Standardized Format)
```yaml ```yaml
image: image:
repository: docker.io/org/app repository: docker.io/org/app
@@ -95,6 +98,7 @@ oidc:
enabled: true enabled: true
redirectUris: redirectUris:
- "/api/auth/callback/authentik" - "/api/auth/callback/authentik"
subjectMode: user_username # Optional, defaults to "user_username"
# Database configuration (if applicable) # Database configuration (if applicable)
database: database:
@@ -117,71 +121,89 @@ env:
Replace your template files with simple includes: Replace your template files with simple includes:
#### deployment.yaml #### deployment.yaml
**Before:** ~50-100 lines of template code **Before:** ~50-100 lines of template code
**After:** **After:**
```yaml ```yaml
{{ include "common.deployment" . }} {{ include "common.deployment" . }}
``` ```
#### service.yaml #### service.yaml
**Before:** ~15-20 lines **Before:** ~15-20 lines
**After:** **After:**
```yaml ```yaml
{{ include "common.service" . }} {{ include "common.service" . }}
``` ```
#### pvc.yaml #### pvc.yaml
**Before:** ~20-30 lines per PVC **Before:** ~20-30 lines per PVC
**After:** **After:**
```yaml ```yaml
{{ include "common.pvc" . }} {{ include "common.pvc" . }}
``` ```
#### virtual-service.yaml #### virtual-service.yaml
**Before:** ~40-50 lines **Before:** ~40-50 lines
**After:** **After:**
```yaml ```yaml
{{ include "common.virtualService" . }} {{ include "common.virtualService" . }}
``` ```
#### dns.yaml (if applicable) #### dns.yaml (if applicable)
**Before:** ~20 lines **Before:** ~20 lines
**After:** **After:**
```yaml ```yaml
{{ include "common.dns" . }} {{ include "common.dns" . }}
``` ```
#### oidc.yaml (if applicable) #### oidc.yaml (if applicable)
**Before:** ~20 lines **Before:** ~20 lines
**After:** **After:**
```yaml ```yaml
{{ include "common.oidc" . }} {{ include "common.oidc" . }}
``` ```
#### database.yaml (if applicable) #### database.yaml (if applicable)
**Before:** ~10 lines **Before:** ~10 lines
**After:** **After:**
```yaml ```yaml
{{ include "common.database" . }} {{ include "common.database" . }}
``` ```
#### secret.yaml (if using External Secrets) #### secret.yaml (if using External Secrets)
**Before:** ~10 lines (GenerateSecret) **Before:** ~10 lines (GenerateSecret)
**After (recommended - split files for correct ordering):** **After (recommended - split files for correct ordering):**
Create two files: Create two files:
`templates/secret-password-generators.yaml`: `templates/secret-password-generators.yaml`:
```yaml ```yaml
{{ include "common.externalSecrets.passwordGenerators" . }} {{ include "common.externalSecrets.passwordGenerators" . }}
``` ```
`templates/secret-external-secrets.yaml`: `templates/secret-external-secrets.yaml`:
```yaml ```yaml
{{ include "common.externalSecrets.externalSecrets" . }} {{ include "common.externalSecrets.externalSecrets" . }}
``` ```
**Alternative (single file):** **Alternative (single file):**
```yaml ```yaml
{{ include "common.externalSecrets" . }} {{ include "common.externalSecrets" . }}
``` ```
@@ -216,6 +238,7 @@ helm template your-app apps/charts/your-app \
``` ```
Verify: Verify:
- All resources render correctly - All resources render correctly
- Environment variables use placeholders correctly - Environment variables use placeholders correctly
- Ports and volumes are configured properly - Ports and volumes are configured properly
@@ -372,11 +395,13 @@ See [TEMPLATING.md](./TEMPLATING.md) for complete placeholder documentation.
### Example 1: Simple Application (audiobookshelf) ### Example 1: Simple Application (audiobookshelf)
**Before:** **Before:**
- 6 template files with ~169 total lines - 6 template files with ~169 total lines
- Custom health probe configuration - Custom health probe configuration
- Multiple PVCs - Multiple PVCs
**After:** **After:**
- 6 template files with 6 total lines (one include each) - 6 template files with 6 total lines (one include each)
- Standardized health probe using `/ping` endpoint - Standardized health probe using `/ping` endpoint
- Same functionality, 96% less code - Same functionality, 96% less code
@@ -384,11 +409,13 @@ See [TEMPLATING.md](./TEMPLATING.md) for complete placeholder documentation.
### Example 2: Multi-Port Application (forgejo) ### Example 2: Multi-Port Application (forgejo)
**Before:** **Before:**
- Multiple services (HTTP + SSH) - Multiple services (HTTP + SSH)
- Complex port configuration - Complex port configuration
- Multiple container ports - Multiple container ports
**After:** **After:**
- Uses `container.ports` array - Uses `container.ports` array
- Uses `service.ports` array - Uses `service.ports` array
- Each service can have different type (ClusterIP vs LoadBalancer) - Each service can have different type (ClusterIP vs LoadBalancer)
@@ -396,11 +423,13 @@ See [TEMPLATING.md](./TEMPLATING.md) for complete placeholder documentation.
### Example 3: Application with Database (blinko) ### Example 3: Application with Database (blinko)
**Before:** **Before:**
- Environment variables with template syntax - Environment variables with template syntax
- Secret references - Secret references
- Database connection strings - Database connection strings
**After:** **After:**
- Environment variables use placeholders - Environment variables use placeholders
- Secret references use `{release}` placeholder - Secret references use `{release}` placeholder
- Cleaner, more maintainable values.yaml - Cleaner, more maintainable values.yaml
@@ -430,6 +459,7 @@ Create `templates/database.yaml`:
### Generated Secret ### Generated Secret
The PostgresDatabase resource creates a secret named `{release}-connection` containing: The PostgresDatabase resource creates a secret named `{release}-connection` containing:
- `url` - Complete PostgreSQL connection URL - `url` - Complete PostgreSQL connection URL
- `host` - Database hostname - `host` - Database hostname
- `port` - Database port - `port` - Database port
@@ -485,10 +515,12 @@ When migrating databases from the old PostgreSQL server (`prod-postgres-cluster-
#### Database Naming Convention #### Database Naming Convention
Database names follow the pattern `{namespace}_{name}` where: Database names follow the pattern `{namespace}_{name}` where:
- `{namespace}` is the Kubernetes namespace (default: `prod`) - `{namespace}` is the Kubernetes namespace (default: `prod`)
- `{name}` is the application name (release name) - `{name}` is the application name (release name)
**Examples:** **Examples:**
- `prod_blinko` - blinko app in prod namespace - `prod_blinko` - blinko app in prod namespace
- `prod_gitea` - gitea app in prod namespace - `prod_gitea` - gitea app in prod namespace
- `shared_authentik-db` - authentik app in shared namespace - `shared_authentik-db` - authentik app in shared namespace
@@ -496,28 +528,35 @@ Database names follow the pattern `{namespace}_{name}` where:
#### Using the Migration Script #### Using the Migration Script
The migration script is located at `scripts/migrate_database.py` and handles: The migration script is located at `scripts/migrate_database.py` and handles:
- Dumping the database from the old server - Dumping the database from the old server
- Restoring to the new server - Restoring to the new server
- Fixing permissions and ownership automatically - Fixing permissions and ownership automatically
The script can not be used until the new database is deployed, so it shouldn't be used as part of the migration
**Basic Usage:** **Basic Usage:**
```bash ```bash
./scripts/migrate_database.py <source_db_name> <dest_db_name> ./scripts/migrate_database.py <source_db_name> <dest_db_name>
``` ```
**Example:** **Example:**
```bash ```bash
# Migrate prod_blinko database (same name on both servers) # Migrate prod_blinko database (same name on both servers)
./scripts/migrate_database.py prod_blinko prod_blinko ./scripts/migrate_database.py prod_blinko prod_blinko
``` ```
**With Different Database Names:** **With Different Database Names:**
```bash ```bash
# Migrate from old_name to new_name # Migrate from old_name to new_name
./scripts/migrate_database.py old_name new_name ./scripts/migrate_database.py old_name new_name
``` ```
**With Custom PostgreSQL Users:** **With Custom PostgreSQL Users:**
```bash ```bash
# If the PostgreSQL users differ from defaults # If the PostgreSQL users differ from defaults
./scripts/migrate_database.py prod_blinko prod_blinko \ ./scripts/migrate_database.py prod_blinko prod_blinko \
@@ -526,6 +565,7 @@ The migration script is located at `scripts/migrate_database.py` and handles:
``` ```
**Overwriting Existing Data:** **Overwriting Existing Data:**
```bash ```bash
# Use --clean flag to drop existing objects before restoring # Use --clean flag to drop existing objects before restoring
# WARNING: This will DELETE all existing data in the destination database! # WARNING: This will DELETE all existing data in the destination database!
@@ -535,6 +575,7 @@ The migration script is located at `scripts/migrate_database.py` and handles:
#### Behavior with Existing Databases #### Behavior with Existing Databases
**Without `--clean` flag:** **Without `--clean` flag:**
- The script will attempt to restore objects to the destination database - The script will attempt to restore objects to the destination database
- If tables/objects already exist, `pg_restore` may: - If tables/objects already exist, `pg_restore` may:
- Fail with errors (e.g., "relation already exists") - Fail with errors (e.g., "relation already exists")
@@ -543,12 +584,14 @@ The migration script is located at `scripts/migrate_database.py` and handles:
- **This will NOT automatically overwrite existing data** - **This will NOT automatically overwrite existing data**
**With `--clean` flag:** **With `--clean` flag:**
- Drops all existing objects (tables, sequences, functions, etc.) before restoring - Drops all existing objects (tables, sequences, functions, etc.) before restoring
- **WARNING: This will DELETE all existing data in the destination database** - **WARNING: This will DELETE all existing data in the destination database**
- Use this when you want to completely replace the destination database with source data - Use this when you want to completely replace the destination database with source data
- Recommended for initial migrations or when you're sure you want to overwrite - Recommended for initial migrations or when you're sure you want to overwrite
**Best Practice:** **Best Practice:**
- For initial migrations: Use `--clean` to ensure a clean restore - For initial migrations: Use `--clean` to ensure a clean restore
- For updates/re-syncs: Use `--clean` only if you're certain you want to replace all data - For updates/re-syncs: Use `--clean` only if you're certain you want to replace all data
- For incremental updates: Consider using application-specific sync mechanisms instead - For incremental updates: Consider using application-specific sync mechanisms instead
@@ -574,6 +617,7 @@ The migration script is located at `scripts/migrate_database.py` and handles:
#### Default Configuration #### Default Configuration
The script uses these defaults: The script uses these defaults:
- **Source server**: `prod-postgres-cluster-0` in `homelab` namespace - **Source server**: `prod-postgres-cluster-0` in `homelab` namespace
- **Source user**: `homelab` - **Source user**: `homelab`
- **Destination server**: `postgres-statefulset-0` in `shared` namespace - **Destination server**: `postgres-statefulset-0` in `shared` namespace
@@ -582,16 +626,20 @@ The script uses these defaults:
#### Troubleshooting #### Troubleshooting
**Error: "role does not exist"** **Error: "role does not exist"**
- Check the PostgreSQL user name with: `kubectl exec -n <namespace> <pod> -c <container> -- env | grep POSTGRES_USER` - Check the PostgreSQL user name with: `kubectl exec -n <namespace> <pod> -c <container> -- env | grep POSTGRES_USER`
- Use `--source-user` or `--dest-user` flags to specify correct users - Use `--source-user` or `--dest-user` flags to specify correct users
**Error: "database does not exist"** **Error: "database does not exist"**
- Create the destination database manually before running the script - Create the destination database manually before running the script
- Verify database names match the `{namespace}_{name}` convention - Verify database names match the `{namespace}_{name}` convention
**Error: "permission denied for schema"** **Error: "permission denied for schema"**
- The script should fix this automatically - The script should fix this automatically
- If issues persist, manually grant permissions: - If issues persist, manually grant permissions:
```sql ```sql
GRANT USAGE ON SCHEMA <schema_name> TO <db_user>; GRANT USAGE ON SCHEMA <schema_name> TO <db_user>;
GRANT CREATE ON SCHEMA <schema_name> TO <db_user>; GRANT CREATE ON SCHEMA <schema_name> TO <db_user>;
@@ -606,9 +654,81 @@ Some charts may still have legacy resources that should be kept as-is:
- **PostgresDatabase** (legacy `homelab.mortenolsen.pro/v1`) - Use `common.database` for new PostgresDatabase instead - **PostgresDatabase** (legacy `homelab.mortenolsen.pro/v1`) - Use `common.database` for new PostgresDatabase instead
- **GenerateSecret** (legacy `homelab.mortenolsen.pro/v1`) - Use `common.externalSecrets` for External Secrets instead - **GenerateSecret** (legacy `homelab.mortenolsen.pro/v1`) - Use `common.externalSecrets` for External Secrets instead
### Migrating from OidcClient to AuthentikClient
**Before (OidcClient):**
```yaml
# templates/client.yaml
apiVersion: homelab.mortenolsen.pro/v1
kind: OidcClient
metadata:
name: "{{ .Release.Name }}"
spec:
environment: "{{ .Values.globals.environment }}"
redirectUris:
- path: oauth2/oidc/callback
subdomain: "{{ .Values.subdomain }}"
matchingMode: strict
```
**After (AuthentikClient):**
```yaml
# values.yaml
oidc:
enabled: true
redirectUris:
- "/oauth2/oidc/callback" # Path only, domain is automatically prepended
subjectMode: user_username # Optional, defaults to "user_username"
# templates/client.yaml (or oidc.yaml)
{{ include "common.oidc" . }}
```
**Key Changes:**
1. **API Version**: Changed from `homelab.mortenolsen.pro/v1` to `authentik.homelab.mortenolsen.pro/v1alpha1`
2. **Resource Kind**: Changed from `OidcClient` to `AuthentikClient`
3. **Redirect URIs**: Now specified as paths only (e.g., `"/oauth2/oidc/callback"`). The full URL is automatically constructed as `https://{subdomain}.{domain}{path}`
4. **Subject Mode**: New `subjectMode` field defaults to `"user_username"` but can be customized
5. **Secret Name**: The generated secret name changed from `{release}-client` to `{release}-oidc-credentials`
6. **Secret Keys**: The secret key `configurationIssuer` changed to `issuer`
**Environment Variable Updates:**
When migrating, update your environment variables to reference the new secret:
```yaml
env:
OAUTH2_CLIENT_ID:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials" # Changed from {release}-client
key: clientId
OAUTH2_CLIENT_SECRET:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials" # Changed from {release}-client
key: clientSecret
OAUTH2_OIDC_DISCOVERY_ENDPOINT:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials" # Changed from {release}-client
key: issuer # Changed from configurationIssuer
```
**Subject Mode Options:**
The `subjectMode` field controls how the subject identifier is generated:
- `user_username` (default) - Uses the username as the subject identifier
- `user_email` - Uses the email address as the subject identifier
- `user_id` - Uses the user ID as the subject identifier
### Migrating from GenerateSecret to External Secrets ### Migrating from GenerateSecret to External Secrets
**Before (GenerateSecret):** **Before (GenerateSecret):**
```yaml ```yaml
# templates/secret.yaml # templates/secret.yaml
apiVersion: homelab.mortenolsen.pro/v1 apiVersion: homelab.mortenolsen.pro/v1
@@ -623,6 +743,7 @@ spec:
``` ```
**After (External Secrets):** **After (External Secrets):**
```yaml ```yaml
# values.yaml # values.yaml
externalSecrets: externalSecrets:
@@ -641,6 +762,7 @@ externalSecrets:
``` ```
**Note:** **Note:**
- External Secrets generates passwords directly (no encoding option) - External Secrets generates passwords directly (no encoding option)
- The `secretKeys` field is **required** to set the key name in the secret - The `secretKeys` field is **required** to set the key name in the secret
- Without `secretKeys`, the Password generator defaults to using `password` as the key name - Without `secretKeys`, the Password generator defaults to using `password` as the key name
@@ -653,6 +775,7 @@ externalSecrets:
**Error:** `found in Chart.yaml, but missing in charts/ directory: common` **Error:** `found in Chart.yaml, but missing in charts/ directory: common`
**Solution:** **Solution:**
```bash ```bash
cd apps/charts/your-app cd apps/charts/your-app
rm -rf charts Chart.lock rm -rf charts Chart.lock
@@ -666,6 +789,7 @@ helm dependency build
**Error:** Template rendering fails with syntax errors **Error:** Template rendering fails with syntax errors
**Solution:** **Solution:**
- Ensure all placeholders use curly braces: `{release}`, not `{{release}}` - Ensure all placeholders use curly braces: `{release}`, not `{{release}}`
- Check that values.yaml uses proper YAML structure - Check that values.yaml uses proper YAML structure
- Verify globals are provided when testing - Verify globals are provided when testing
@@ -675,6 +799,7 @@ helm dependency build
**Problem:** Placeholders like `{subdomain}` appear literally in output **Problem:** Placeholders like `{subdomain}` appear literally in output
**Solution:** **Solution:**
- Ensure you're using the latest common library version - Ensure you're using the latest common library version
- Rebuild dependencies: `helm dependency build` - Rebuild dependencies: `helm dependency build`
- Check that placeholders are in `env:` section, not elsewhere - Check that placeholders are in `env:` section, not elsewhere
@@ -684,6 +809,7 @@ helm dependency build
**Problem:** Health probe uses wrong port or type **Problem:** Health probe uses wrong port or type
**Solution:** **Solution:**
- For named ports, use: `port: http` (the port name) - For named ports, use: `port: http` (the port name)
- For numeric ports, use: `port: 80` (the port number) - For numeric ports, use: `port: 80` (the port number)
- Ensure `container.healthProbe.type` is set correctly - Ensure `container.healthProbe.type` is set correctly
@@ -693,6 +819,7 @@ helm dependency build
**Problem:** Only one service is created when multiple are expected **Problem:** Only one service is created when multiple are expected
**Solution:** **Solution:**
- Use `service.ports` array (not `service.port`) - Use `service.ports` array (not `service.port`)
- Each port entry creates a separate service - Each port entry creates a separate service
- Use `serviceName` in port config for custom names - Use `serviceName` in port config for custom names

View File

@@ -75,6 +75,39 @@ Helper functions for custom templates:
The library expects a standardized values structure. See migrated charts (`audiobookshelf`, `forgejo`, `baikal`, `blinko`) for examples. The library expects a standardized values structure. See migrated charts (`audiobookshelf`, `forgejo`, `baikal`, `blinko`) for examples.
### OIDC Configuration
To enable OIDC authentication, configure the `oidc` section in your `values.yaml`:
```yaml
oidc:
enabled: true
redirectUris:
- "/api/auth/callback/authentik"
subjectMode: user_username # Optional, defaults to "user_username"
```
**Subject Mode Options:**
- `user_username` (default) - Uses the username as the subject identifier
- `user_email` - Uses the email address as the subject identifier
- `user_id` - Uses the user ID as the subject identifier
The AuthentikClient resource creates a secret named `{release}-oidc-credentials` containing:
- `clientId` - OAuth client ID
- `clientSecret` - OAuth client secret
- `issuer` - OIDC provider issuer URL
Reference these in your environment variables using placeholders:
```yaml
env:
OAUTH2_CLIENT_ID:
valueFrom:
secretKeyRef:
name: "{release}-oidc-credentials"
key: clientId
```
## Placeholders ## Placeholders
Use placeholders in `values.yaml` for dynamic values: Use placeholders in `values.yaml` for dynamic values:

View File

@@ -521,6 +521,7 @@ spec:
{{- range .Values.oidc.redirectUris }} {{- range .Values.oidc.redirectUris }}
- {{ printf "https://%s%s" (include "common.domain" $) . | quote }} - {{ printf "https://%s%s" (include "common.domain" $) . | quote }}
{{- end }} {{- end }}
subjectMode: {{ .Values.oidc.subjectMode | default "user_username" }}
{{- end }} {{- end }}
{{- end }} {{- end }}