feat(gitops): migrate domain to riotpiao.com, add CNPG + Forgejo HA on Redis/Postgres, wire ArgoCD apps — enables cluster rebuild after etcd wipe and unblocks the git-source chicken-egg via standalone Helm-source Applications
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cloudflared
|
||||
namespace: cloudflared
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cloudflared
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cloudflared
|
||||
spec:
|
||||
containers:
|
||||
- name: cloudflared
|
||||
image: cloudflare/cloudflared:latest
|
||||
args:
|
||||
- tunnel
|
||||
- --no-autoupdate
|
||||
- run
|
||||
- --token
|
||||
- $(TUNNEL_TOKEN)
|
||||
env:
|
||||
- name: TUNNEL_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: cloudflared-token
|
||||
key: token
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: cloudflared
|
||||
resources:
|
||||
- deployment.yaml
|
||||
@@ -9,17 +9,17 @@ Build for `linux/amd64`:
|
||||
```bash
|
||||
cd homelab
|
||||
docker buildx build --platform linux/amd64 \
|
||||
-t forgejo.riotpiao.homelab.com/rock/claude-terminal:latest \
|
||||
-t forgejo.riotpiao.com/rock/claude-terminal:latest \
|
||||
-f k8s/dev-tools/Dockerfile \
|
||||
k8s/dev-tools
|
||||
|
||||
# Log in to Forgejo registry
|
||||
docker login forgejo.riotpiao.homelab.com \
|
||||
docker login forgejo.riotpiao.com \
|
||||
--username ci-bot \
|
||||
--password "$(talos get cluster/iam/agents/ci-bot --key token)"
|
||||
|
||||
# Push
|
||||
docker push forgejo.riotpiao.homelab.com/rock/claude-terminal:latest
|
||||
docker push forgejo.riotpiao.com/rock/claude-terminal:latest
|
||||
```
|
||||
|
||||
Or use the provided build script:
|
||||
@@ -36,7 +36,7 @@ Update `values.yaml` if needed, then deploy via helmfile:
|
||||
helmfile apply -l name=claude-terminal
|
||||
```
|
||||
|
||||
Access the terminal at: **https://claude.riotpiao.homelab.com**
|
||||
Access the terminal at: **https://claude.riotpiao.com**
|
||||
|
||||
## Persistent Storage
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
REGISTRY="forgejo.riotpiao.homelab.com"
|
||||
REGISTRY="forgejo.riotpiao.com"
|
||||
IMAGE_NAME="rock/claude-terminal"
|
||||
TAG="latest"
|
||||
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
||||
|
||||
@@ -15,14 +15,14 @@ ingress:
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: homelab-ca
|
||||
hosts:
|
||||
- host: claude.riotpiao.homelab.com
|
||||
- host: claude.riotpiao.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: claude-terminal-tls
|
||||
hosts:
|
||||
- claude.riotpiao.homelab.com
|
||||
- claude.riotpiao.com
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: duckdns
|
||||
resources: []
|
||||
# DuckDNS deployed via Helm chart or CronJob
|
||||
resources:
|
||||
- duckdns-corn.yaml
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# The homelab-ca secret above only reaches the runner/register/dind containers.
|
||||
# It does NOT reach the per-job containers DinD spawns (e.g. golangci-lint,
|
||||
# node:22-bookworm) — those are fresh sibling containers with their own trust
|
||||
# store. Without this, any git/curl/apk call to forgejo.riotpiao.homelab.com
|
||||
# store. Without this, any git/curl/apk call to forgejo.riotpiao.com
|
||||
# from inside a job fails with "SSL certificate problem: unable to get local
|
||||
# issuer certificate". Build a merged bundle (public roots + homelab CA) and
|
||||
# bind-mount it over /etc/ssl/certs/ca-certificates.crt in every job
|
||||
@@ -30,7 +30,7 @@
|
||||
# IMPORTANT: source the CA from the live cluster secret, NOT from
|
||||
# k8s/forge/pki/ca.crt — that repo file is a stale CA from before the
|
||||
# "unified certificate" migration (different key, fails verification
|
||||
# against the cert actually served by forgejo.riotpiao.homelab.com). The
|
||||
# against the cert actually served by forgejo.riotpiao.com). The
|
||||
# org-wide CA that signs the live ingress cert lives in
|
||||
# cert-manager/homelab-ca-secret, and cicd/homelab-ca above is already
|
||||
# synced from it.
|
||||
@@ -220,7 +220,7 @@ spec:
|
||||
- |
|
||||
test -f /data/.runner && echo "already registered, skipping" && exit 0
|
||||
forgejo-runner register --no-interactive \
|
||||
--instance https://forgejo.riotpiao.homelab.com \
|
||||
--instance https://forgejo.riotpiao.com \
|
||||
--token "$RUNNER_TOKEN" \
|
||||
--name talos-runner \
|
||||
--labels "docker:docker://node:22-bookworm"
|
||||
@@ -407,7 +407,7 @@ spec:
|
||||
- to:
|
||||
- podSelector: {}
|
||||
# ingress-nginx (the runner talks to Forgejo via its public hostname,
|
||||
# https://forgejo.riotpiao.homelab.com, which resolves to the ingress
|
||||
# https://forgejo.riotpiao.com, which resolves to the ingress
|
||||
# controller's ClusterIP — a different namespace on the pod network)
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
|
||||
@@ -16,3 +16,4 @@ resources:
|
||||
- shadowsocks/
|
||||
- dev-tools/
|
||||
- duckdns/
|
||||
- cloudflared/
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: kmsvc
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
||||
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||
targetRevision: main
|
||||
path: k8s/charts/kafka-cluster
|
||||
helm:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: kmsvc
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
||||
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||
targetRevision: main
|
||||
path: k8s/charts/queue-crd
|
||||
helm:
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||
image:
|
||||
repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service-queue-operator
|
||||
repository: forgejo.riotpiao.com/rock/kafka-management-service-queue-operator
|
||||
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
||||
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
||||
tag: latest
|
||||
|
||||
@@ -8,25 +8,25 @@ metadata:
|
||||
spec:
|
||||
project: kmsvc
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
||||
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||
targetRevision: main
|
||||
path: k8s/charts/management-service
|
||||
helm:
|
||||
values: |
|
||||
namespace: sqs
|
||||
image:
|
||||
repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service
|
||||
repository: forgejo.riotpiao.com/rock/kafka-management-service
|
||||
# CI (.forgejo/workflows/release.yaml) writes the released git tag
|
||||
# here and pushes the commit -- ArgoCD picks it up on its next sync.
|
||||
tag: latest
|
||||
env:
|
||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
||||
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||
ingress:
|
||||
enabled: true
|
||||
host: kmsvc.riotpiao.homelab.com
|
||||
host: kmsvc.riotpiao.com
|
||||
clusterIssuer: homelab-ca
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
|
||||
@@ -6,7 +6,7 @@ metadata:
|
||||
spec:
|
||||
description: Kafka Management Service (design.md) -- Strimzi/Kafka, Redis, queue-operator, message-plane server
|
||||
sourceRepos:
|
||||
- https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
||||
- https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||
- https://strimzi.io/charts/
|
||||
- https://charts.bitnami.com/bitnami
|
||||
destinations:
|
||||
|
||||
@@ -6,7 +6,7 @@ metadata:
|
||||
spec:
|
||||
project: kmsvc
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git
|
||||
repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git
|
||||
targetRevision: main
|
||||
path: k8s/argocd/apps
|
||||
directory:
|
||||
|
||||
@@ -40,10 +40,10 @@ ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
clusterIssuer: homelab-ca
|
||||
host: kmsvc.riotpiao.homelab.com
|
||||
host: kmsvc.riotpiao.com
|
||||
tlsSecretName: kmsvc-tls
|
||||
# kmsvc-cli connects via gRPC directly to --server/KMSVC_SERVER (default
|
||||
# kmsvc.riotpiao.homelab.com:443, see kmsvc-cli's README), so raw gRPC needs an
|
||||
# kmsvc.riotpiao.com:443, see kmsvc-cli's README), so raw gRPC needs an
|
||||
# external path too — scoped to the gRPC service's own path prefix on the
|
||||
# same host/port, rather than opening the whole host to gRPC passthrough.
|
||||
grpcEnabled: true
|
||||
|
||||
@@ -23,7 +23,7 @@ redis:
|
||||
|
||||
managementService:
|
||||
ingress:
|
||||
host: kmsvc.riotpiao.homelab.com
|
||||
host: kmsvc.riotpiao.com
|
||||
clusterIssuer: homelab-ca
|
||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
||||
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||
|
||||
@@ -119,7 +119,7 @@ worker-production-5f8b4c... 1/1 Running 0 10s
|
||||
### Step 5: Verify Worker Connected to Temporal Namespace
|
||||
Check Temporal UI for namespace "production":
|
||||
```bash
|
||||
open https://temporal.riotpiao.homelab.com/namespaces/production/task-queues
|
||||
open https://temporal.riotpiao.com/namespaces/production/task-queues
|
||||
```
|
||||
|
||||
Look for all task queues with worker count > 0:
|
||||
|
||||
@@ -19,7 +19,7 @@ Browser → Ingress (TLS) → oauth2-proxy (OIDC check) → temporal-web (intern
|
||||
✅ Authentik OIDC provider `temporal` already exists with:
|
||||
- Client ID: `temporal`
|
||||
- Client Secret: stored in Kubernetes secret `temporal-oidc` (key: `clientSecret`)
|
||||
- Redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback`
|
||||
- Redirect URI: `https://temporal.riotpiao.com/oauth2/callback`
|
||||
|
||||
## Secrets
|
||||
|
||||
@@ -85,14 +85,14 @@ kubectl get ingress -n temporal
|
||||
Expected:
|
||||
```
|
||||
NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||
temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s
|
||||
temporal nginx temporal.riotpiao.com ... 80, 443 10s
|
||||
```
|
||||
|
||||
### Step 3: Test Access
|
||||
|
||||
1. **Open Temporal UI (unauthenticated):**
|
||||
```bash
|
||||
open https://temporal.riotpiao.homelab.com
|
||||
open https://temporal.riotpiao.com
|
||||
```
|
||||
|
||||
Expected: Redirects to Authentik login page
|
||||
@@ -100,12 +100,12 @@ temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s
|
||||
2. **Login with Authentik credentials**
|
||||
- Username/email
|
||||
- Password
|
||||
- Should redirect back to `temporal.riotpiao.homelab.com` and display UI
|
||||
- Should redirect back to `temporal.riotpiao.com` and display UI
|
||||
|
||||
3. **Verify auth:**
|
||||
```bash
|
||||
# Check for oauth2_proxy cookie
|
||||
curl -v https://temporal.riotpiao.homelab.com 2>&1 | grep -i cookie
|
||||
curl -v https://temporal.riotpiao.com 2>&1 | grep -i cookie
|
||||
```
|
||||
|
||||
4. **Check oauth2-proxy logs:**
|
||||
@@ -127,7 +127,7 @@ redirect_uri_mismatch: The redirect_uri does not match the one registered in Aut
|
||||
```
|
||||
|
||||
Fix:
|
||||
- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback`
|
||||
- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.com/oauth2/callback`
|
||||
- Ensure HTTPS (not HTTP)
|
||||
|
||||
### Missing secret
|
||||
|
||||
@@ -10,7 +10,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs
|
||||
directory:
|
||||
@@ -35,7 +35,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs
|
||||
directory:
|
||||
@@ -60,7 +60,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/monitoring
|
||||
directory:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/argocd/root
|
||||
destination:
|
||||
|
||||
@@ -10,7 +10,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/talos-iam
|
||||
directory:
|
||||
@@ -33,7 +33,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/logging
|
||||
directory:
|
||||
@@ -45,29 +45,30 @@ spec:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: cloudnative-pg
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/ddb
|
||||
directory:
|
||||
recurse: false
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: ddb
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
# cloudnative-pg: managed separately via k8s/argocd/apps/cnpg-operator.yaml
|
||||
# (Helm-source Application, avoids the git chicken-egg for the operator itself)
|
||||
# apiVersion: argoproj.io/v1alpha1
|
||||
# kind: Application
|
||||
# metadata:
|
||||
# name: cloudnative-pg
|
||||
# namespace: argocd
|
||||
# annotations:
|
||||
# argocd.argoproj.io/sync-wave: "1"
|
||||
# spec:
|
||||
# project: homelab
|
||||
# source:
|
||||
# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
# targetRevision: main
|
||||
# path: k8s/ddb
|
||||
# directory:
|
||||
# recurse: false
|
||||
# destination:
|
||||
# server: https://kubernetes.default.svc
|
||||
# namespace: ddb
|
||||
# syncPolicy:
|
||||
# automated:
|
||||
# prune: true
|
||||
# selfHeal: true
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
@@ -79,7 +80,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/talos-iam
|
||||
directory:
|
||||
@@ -101,7 +102,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/temporal
|
||||
directory:
|
||||
@@ -124,7 +125,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs
|
||||
directory:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs
|
||||
directory:
|
||||
@@ -31,7 +31,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs
|
||||
directory:
|
||||
@@ -54,7 +54,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/logging
|
||||
directory:
|
||||
@@ -77,7 +77,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/logging
|
||||
directory:
|
||||
@@ -89,26 +89,27 @@ spec:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "2"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/talos-ci-cd
|
||||
directory:
|
||||
recurse: false
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: cicd
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
# forgejo: managed separately via k8s/argocd/apps/forgejo.yaml
|
||||
# (Helm-source Application with inlined values, avoids the git chicken-egg)
|
||||
# apiVersion: argoproj.io/v1alpha1
|
||||
# kind: Application
|
||||
# metadata:
|
||||
# name: forgejo
|
||||
# namespace: argocd
|
||||
# annotations:
|
||||
# argocd.argoproj.io/sync-wave: "2"
|
||||
# spec:
|
||||
# project: homelab
|
||||
# source:
|
||||
# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
# targetRevision: main
|
||||
# path: k8s/talos-ci-cd
|
||||
# directory:
|
||||
# recurse: false
|
||||
# destination:
|
||||
# server: https://kubernetes.default.svc
|
||||
# namespace: cicd
|
||||
# syncPolicy:
|
||||
# automated:
|
||||
# prune: true
|
||||
# selfHeal: true
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/talos-ci-cd
|
||||
directory:
|
||||
@@ -31,7 +31,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/portainer
|
||||
directory:
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: cnpg-operator
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://cloudnative-pg.github.io/charts
|
||||
chart: cloudnative-pg
|
||||
targetRevision: "*"
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: ddb
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
@@ -0,0 +1,146 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "7"
|
||||
# Must sync after cnpg-operator (wave 0) and the ddb-cluster/forgejo-database
|
||||
# (wave 6, k8s/data) — Forgejo's DB connection depends on both existing first.
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://dl.gitea.com/charts/
|
||||
chart: gitea
|
||||
targetRevision: "~10"
|
||||
helm:
|
||||
# Mirrors k8s/security/ci-cd/forgejo-values.yaml inline — avoids the
|
||||
# git-repo chicken-egg (Forgejo can't source its own values from a repo
|
||||
# it hosts). Keep both files in sync when editing either one.
|
||||
valuesObject:
|
||||
image:
|
||||
repository: codeberg.org/forgejo/forgejo
|
||||
tag: "13"
|
||||
pullPolicy: IfNotPresent
|
||||
gitea:
|
||||
admin:
|
||||
username: rock
|
||||
email: [email protected]
|
||||
config:
|
||||
server:
|
||||
PROTOCOL: http
|
||||
DOMAIN: forgejo.riotpiao.com
|
||||
ROOT_URL: https://forgejo.riotpiao.com/
|
||||
HTTP_PORT: 3000
|
||||
START_SSH_SERVER: true
|
||||
SSH_DOMAIN: forgejo.riotpiao.com
|
||||
SSH_PORT: 2222
|
||||
SSH_LISTEN_PORT: 2222
|
||||
database:
|
||||
DB_TYPE: postgres
|
||||
HOST: ddb-cluster-rw.ddb.svc:5432
|
||||
NAME: forgejo
|
||||
USER: app
|
||||
repository:
|
||||
ROOT: /data/git
|
||||
actions:
|
||||
ENABLED: true
|
||||
packages:
|
||||
ENABLED: true
|
||||
metrics:
|
||||
ENABLED: true
|
||||
service:
|
||||
DISABLE_REGISTRATION: true
|
||||
oauth2:
|
||||
ENABLED: true
|
||||
PROVIDER: openidconnect
|
||||
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||
CLIENT_ID: forgejo
|
||||
AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||
cache:
|
||||
ADAPTER: redis
|
||||
HOST: "redis://forgejo-redis.cicd.svc:6379/0"
|
||||
session:
|
||||
PROVIDER: redis
|
||||
PROVIDER_CONFIG: "redis://forgejo-redis.cicd.svc:6379/1"
|
||||
queue:
|
||||
TYPE: redis
|
||||
CONN_STR: "redis://forgejo-redis.cicd.svc:6379/2"
|
||||
metrics:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: longhorn
|
||||
size: 20Gi
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
replicaCount: 2
|
||||
deployment:
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
env:
|
||||
- name: SSL_CERT_DIR
|
||||
value: /homelab-ca
|
||||
- name: GITEA__database__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: ddb-cluster-app
|
||||
key: password
|
||||
podAnnotations:
|
||||
configmap.reloader.stakater.com/reload: "homelab-ca"
|
||||
service:
|
||||
http:
|
||||
type: LoadBalancer
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
annotations:
|
||||
io.cilium/lb-ipam-ips: "192.168.1.165"
|
||||
io.cilium/lb-ipam-sharing-key: "forgejo"
|
||||
ssh:
|
||||
type: LoadBalancer
|
||||
port: 2222
|
||||
targetPort: 2222
|
||||
annotations:
|
||||
io.cilium/lb-ipam-ips: "192.168.1.165"
|
||||
io.cilium/lb-ipam-sharing-key: "forgejo"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
extraVolumes:
|
||||
- name: homelab-ca
|
||||
configMap:
|
||||
name: homelab-ca
|
||||
extraVolumeMounts:
|
||||
- name: homelab-ca
|
||||
mountPath: /homelab-ca
|
||||
readOnly: true
|
||||
ingress:
|
||||
enabled: false
|
||||
postgresql:
|
||||
enabled: false
|
||||
postgresql-ha:
|
||||
enabled: false
|
||||
mysql:
|
||||
enabled: false
|
||||
redis-cluster:
|
||||
enabled: false
|
||||
act_runner:
|
||||
enabled: false
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: cicd
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
# NO automated sync — Forgejo is what CI uses to push commits; auto-sync
|
||||
# would let a bad CI commit break the system CI depends on. Manual only.
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/infrastructure
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/bootstrap
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/platform
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/security
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/applications
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/data
|
||||
destination:
|
||||
|
||||
@@ -67,12 +67,12 @@ spec:
|
||||
purge: false
|
||||
|
||||
environment:
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration
|
||||
MINIO_IDENTITY_OPENID_CLIENT_ID: minio
|
||||
MINIO_IDENTITY_OPENID_CLIENT_SECRET: 9d2867fe08c3bf7fedd7e32bbaf4456fce3b0aaf788966d7559e1955947b0219
|
||||
MINIO_IDENTITY_OPENID_CLAIM_NAME: policy
|
||||
MINIO_IDENTITY_OPENID_SCOPES: openid,profile,email,minio
|
||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.homelab.com/oauth_callback
|
||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.com/oauth_callback
|
||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME: Authentik
|
||||
|
||||
destination:
|
||||
|
||||
@@ -82,7 +82,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs/charts/kafka-cluster
|
||||
helm:
|
||||
@@ -117,7 +117,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs/charts/queue-crd
|
||||
helm:
|
||||
@@ -146,7 +146,7 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/sqs/charts/management-service
|
||||
helm:
|
||||
@@ -155,11 +155,11 @@ spec:
|
||||
env:
|
||||
kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092"
|
||||
redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379"
|
||||
authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/"
|
||||
authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/"
|
||||
authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc"
|
||||
ingress:
|
||||
enabled: true
|
||||
host: kmsvc.riotpiao.homelab.com
|
||||
host: kmsvc.riotpiao.com
|
||||
clusterIssuer: homelab-ca
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
helm:
|
||||
valueFiles:
|
||||
- k8s/monitoring/prometheus-values.yaml
|
||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/hooks/phase2
|
||||
destination:
|
||||
@@ -47,7 +47,7 @@ spec:
|
||||
helm:
|
||||
valueFiles:
|
||||
- k8s/ddb/cnpg-values.yaml
|
||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/hooks/phase2
|
||||
destination:
|
||||
|
||||
@@ -95,13 +95,13 @@ metadata:
|
||||
spec:
|
||||
project: homelab
|
||||
sources:
|
||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/talos-ci-cd/charts/forgejo-runner
|
||||
helm:
|
||||
valueFiles:
|
||||
- values.yaml
|
||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/hooks/phase2
|
||||
destination:
|
||||
|
||||
@@ -18,7 +18,7 @@ spec:
|
||||
valueFiles:
|
||||
- k8s/talos-iam/authentik-values.yaml
|
||||
- k8s/talos-iam/authentik-secrets.enc.yaml
|
||||
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
- repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/hooks/phase3
|
||||
destination:
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# k8s/argocd/projects/homelab-project.yaml
|
||||
# AppProject referenced by every Application manifest under k8s/argocd/apps/
|
||||
# (project: homelab) — was never committed, so 00-homelab-root.yaml and all
|
||||
# layer/wave/phase apps fail admission with "application references project
|
||||
# 'homelab' which does not exist" until this exists.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
metadata:
|
||||
name: homelab
|
||||
namespace: argocd
|
||||
spec:
|
||||
description: Homelab GitOps — single-repo, in-cluster destinations only
|
||||
sourceRepos:
|
||||
- https://forgejo.riotpiao.com/riotpiao.com/homelab.git
|
||||
- https://cloudnative-pg.github.io/charts
|
||||
- https://dl.gitea.com/charts/
|
||||
destinations:
|
||||
- server: https://kubernetes.default.svc
|
||||
namespace: "*"
|
||||
clusterResourceWhitelist:
|
||||
- group: "*"
|
||||
kind: "*"
|
||||
namespaceResourceWhitelist:
|
||||
- group: "*"
|
||||
kind: "*"
|
||||
@@ -0,0 +1,45 @@
|
||||
# k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml
|
||||
# Let's Encrypt ClusterIssuers for *.riotpiao.com, DNS-01 via Cloudflare
|
||||
# (wildcard certs require DNS-01 — HTTP-01 can't prove ownership of a wildcard name).
|
||||
#
|
||||
# Prereq (apply manually, not in git — token is a secret):
|
||||
# kubectl create secret generic cloudflare-api-token-secret \
|
||||
# --namespace cert-manager \
|
||||
# --from-literal=api-token=<CLOUDFLARE_API_TOKEN>
|
||||
# Token scope: Zone:DNS:Edit for the riotpiao.com zone.
|
||||
#
|
||||
# Start with letsencrypt-staging to validate the solver, then point
|
||||
# Certificate.issuerRef at letsencrypt-prod once staging issues cleanly.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-staging
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
email: [email protected]
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-staging-account-key
|
||||
solvers:
|
||||
- dns01:
|
||||
cloudflare:
|
||||
apiTokenSecretRef:
|
||||
name: cloudflare-api-token-secret
|
||||
key: api-token
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: [email protected]
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod-account-key
|
||||
solvers:
|
||||
- dns01:
|
||||
cloudflare:
|
||||
apiTokenSecretRef:
|
||||
name: cloudflare-api-token-secret
|
||||
key: api-token
|
||||
@@ -4,7 +4,7 @@
|
||||
# Why this is needed:
|
||||
# Grafana v10+ does OIDC auto-discovery by fetching
|
||||
# /.well-known/openid-configuration from Authentik. When Grafana reaches
|
||||
# Authentik via the external hostname (authentik.riotpiao.homelab.com), the
|
||||
# Authentik via the external hostname (authentik.riotpiao.com), the
|
||||
# HTTP Host header is preserved and Authentik returns external URLs in the
|
||||
# discovery response. Without this rewrite, the hostname doesn't resolve
|
||||
# inside the cluster and Grafana falls back to the internal service DNS,
|
||||
@@ -30,29 +30,33 @@ data:
|
||||
}
|
||||
prometheus :9153
|
||||
|
||||
# VPN Access: Map api-server.cluster.local to cluster API IP
|
||||
# Allows secure cluster access via WireGuard tunnel (Shadowrocket/Talos)
|
||||
rewrite name api-server.cluster.local kubernetes.default.svc.cluster.local
|
||||
|
||||
# Forgejo: route through nginx ingress like every other host below. nginx
|
||||
# terminates TLS (wildcard-tls) on :443 and routes both /v2/ (container
|
||||
# registry) and web/git to forgejo-gitea-http:3000.
|
||||
# Do NOT point this at forgejo-gitea-http directly: that service only serves
|
||||
# port 3000, so containerd image pulls (which use https/:443) get
|
||||
# `dial tcp <clusterIP>:443: i/o timeout`. SSH stays on its own LB service.
|
||||
rewrite name forgejo.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name forgejo.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
|
||||
# Rewrite homelab hostnames to the nginx ingress controller so in-cluster pods
|
||||
# hit nginx TLS termination (cert-manager cert) and preserve the Host header.
|
||||
# Routing through nginx — not directly to the backend service — is critical:
|
||||
# direct rewrites to the backend bypass nginx TLS and expose each app's own
|
||||
# self-signed cert, which nothing in the cluster trusts.
|
||||
rewrite name authentik.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name grafana.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name minio.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name minio-api.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name argocd.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name vault.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name loki.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name prometheus.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name portainer.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name longhorn.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name authentik.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name grafana.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name minio.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name minio-api.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name argocd.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name vault.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name loki.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name prometheus.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name portainer.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
rewrite name longhorn.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
|
||||
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# k8s/ingress/ingress.yaml
|
||||
# Ingress rules for all homelab services.
|
||||
# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.homelab.com)
|
||||
# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.com)
|
||||
# as its default-ssl-certificate. No per-rule tls: blocks or cert-manager annotations
|
||||
# are needed — cert-manager manages one cert, nginx uses it for all hosts.
|
||||
#
|
||||
# DNS: *.riotpiao.homelab.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN).
|
||||
# DNS: *.riotpiao.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN).
|
||||
|
||||
# ── Grafana ───────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
@@ -17,7 +17,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: grafana.riotpiao.homelab.com
|
||||
- host: grafana.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -38,7 +38,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: loki.riotpiao.homelab.com
|
||||
- host: loki.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -62,7 +62,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: authentik.riotpiao.homelab.com
|
||||
- host: authentik.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -85,7 +85,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: vault.riotpiao.homelab.com
|
||||
- host: vault.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -113,7 +113,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: minio.riotpiao.homelab.com
|
||||
- host: minio.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -138,7 +138,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: minio-api.riotpiao.homelab.com
|
||||
- host: minio-api.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -159,7 +159,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: prometheus.riotpiao.homelab.com
|
||||
- host: prometheus.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -183,7 +183,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: portainer.riotpiao.homelab.com
|
||||
- host: portainer.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -210,7 +210,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: forgejo.riotpiao.homelab.com
|
||||
- host: forgejo.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -238,7 +238,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: argocd.riotpiao.homelab.com
|
||||
- host: argocd.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -259,7 +259,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: longhorn.riotpiao.homelab.com
|
||||
- host: longhorn.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -285,7 +285,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: temporal.riotpiao.homelab.com
|
||||
- host: temporal.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
@@ -307,7 +307,7 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: kmsvc.riotpiao.homelab.com
|
||||
- host: kmsvc.riotpiao.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# k8s/ingress/nginx-values.yaml
|
||||
# Nginx Ingress Controller — bare-metal homelab config.
|
||||
# LoadBalancer service with Cilium LB-IPAM assigns fixed IP (192.168.1.160).
|
||||
# Access services at https://grafana.riotpiao.homelab.com (80/443 via LoadBalancer).
|
||||
# Access services at https://grafana.riotpiao.com (80/443 via LoadBalancer).
|
||||
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
|
||||
# Single wildcard cert served for every *.riotpiao.homelab.com host.
|
||||
# Applied by the ingress-nginx presync hook (wildcard-cert.yaml) before nginx starts.
|
||||
# nginx hot-reloads when cert-manager renews homelab-tls — no restart needed.
|
||||
# Single wildcard cert served for every *.riotpiao.com host (Let's Encrypt,
|
||||
# see ../ingress/riotpiao-com-cert.yaml + ../cert-manager/letsencrypt-issuer.yaml).
|
||||
# nginx hot-reloads when cert-manager renews riotpiao-com-tls — no restart needed.
|
||||
extraArgs:
|
||||
default-ssl-certificate: "ingress-nginx/homelab-tls"
|
||||
default-ssl-certificate: "ingress-nginx/riotpiao-com-tls"
|
||||
|
||||
hostPort:
|
||||
enabled: true
|
||||
@@ -19,7 +19,7 @@ controller:
|
||||
https: 443
|
||||
|
||||
# TCP proxy: forward port 2222 on every node → Forgejo SSH service.
|
||||
# This lets `git clone [email protected].homelab.com:repo` work via the
|
||||
# This lets `git clone [email protected]:repo` work via the
|
||||
# same hostname as HTTPS without a separate LoadBalancer IP for SSH.
|
||||
tcp:
|
||||
2222: "cicd/forgejo-gitea-ssh:2222"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# k8s/bootstrap/ingress/riotpiao-com-cert.yaml
|
||||
# Public wildcard cert for *.riotpiao.com, signed by Let's Encrypt (DNS-01 via
|
||||
# Cloudflare, see ../cert-manager/letsencrypt-issuer.yaml). Distinct from
|
||||
# homelab-tls (self-signed homelab-ca, internal *.riotpiao.com) —
|
||||
# reference riotpiao-com-tls explicitly on ingresses that expose riotpiao.com
|
||||
# hosts to the internet; it is not nginx's default-ssl-certificate.
|
||||
#
|
||||
# issuerRef starts on letsencrypt-staging. Switch to letsencrypt-prod once the
|
||||
# staging cert issues cleanly, then delete this Certificate's Secret to force
|
||||
# a re-issue against prod (staging certs aren't browser-trusted).
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: riotpiao-com-tls
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
secretName: riotpiao-com-tls
|
||||
dnsNames:
|
||||
- "*.riotpiao.com"
|
||||
- "riotpiao.com"
|
||||
issuerRef:
|
||||
name: letsencrypt-staging
|
||||
kind: ClusterIssuer
|
||||
duration: 2160h # 90 days (LE max)
|
||||
renewBefore: 720h # renew 30 days before expiry
|
||||
@@ -1,22 +0,0 @@
|
||||
# k8s/ingress/wildcard-cert.yaml
|
||||
# Single wildcard TLS certificate for all *.riotpiao.homelab.com services.
|
||||
# Lives in the ingress-nginx namespace and is set as nginx's default-ssl-certificate,
|
||||
# so every ingress host gets it automatically — no per-service TLS blocks needed.
|
||||
#
|
||||
# Renewal: cert-manager auto-renews 30 days before expiry (renewBefore: 720h).
|
||||
# nginx detects the secret update via its K8s watch and hot-reloads — no pod restart.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: homelab-tls
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
secretName: homelab-tls
|
||||
dnsNames:
|
||||
- "*.riotpiao.homelab.com"
|
||||
- "riotpiao.homelab.com"
|
||||
issuerRef:
|
||||
name: homelab-ca
|
||||
kind: ClusterIssuer
|
||||
duration: 8760h # 1 year
|
||||
renewBefore: 720h # renew 30 days before expiry
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Database
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: ddb
|
||||
spec:
|
||||
name: forgejo
|
||||
owner: app
|
||||
cluster:
|
||||
name: ddb-cluster
|
||||
@@ -13,3 +13,4 @@ resources:
|
||||
- ddb-cluster.yaml
|
||||
- schemas.yaml
|
||||
- db-init-job.yaml
|
||||
- forgejo-database.yaml
|
||||
|
||||
@@ -111,7 +111,7 @@ spec:
|
||||
# Environment variables — OIDC config
|
||||
env:
|
||||
- name: MINIO_IDENTITY_OPENID_CONFIG_URL
|
||||
value: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration"
|
||||
value: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration"
|
||||
- name: MINIO_IDENTITY_OPENID_CLIENT_ID
|
||||
value: "minio"
|
||||
- name: MINIO_IDENTITY_OPENID_CLIENT_SECRET
|
||||
@@ -124,7 +124,7 @@ spec:
|
||||
- name: MINIO_IDENTITY_OPENID_SCOPES
|
||||
value: "openid,profile,email,minio"
|
||||
- name: MINIO_IDENTITY_OPENID_REDIRECT_URI
|
||||
value: "https://minio.riotpiao.homelab.com/oauth_callback"
|
||||
value: "https://minio.riotpiao.com/oauth_callback"
|
||||
- name: MINIO_IDENTITY_OPENID_DISPLAY_NAME
|
||||
value: "Authentik"
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ envFrom:
|
||||
name: minio-oidc
|
||||
|
||||
environment:
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration"
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration"
|
||||
MINIO_IDENTITY_OPENID_CLIENT_ID: "minio"
|
||||
MINIO_IDENTITY_OPENID_CLAIM_NAME: "policy"
|
||||
MINIO_IDENTITY_OPENID_SCOPES: "openid,profile,email,minio"
|
||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.homelab.com/oauth_callback"
|
||||
MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.com/oauth_callback"
|
||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME: "Authentik"
|
||||
|
||||
podAnnotations:
|
||||
|
||||
@@ -39,7 +39,7 @@ persistence:
|
||||
# ── Grafana config ────────────────────────────────────────────────────────────
|
||||
grafana.ini:
|
||||
server:
|
||||
root_url: https://grafana.riotpiao.homelab.com
|
||||
root_url: https://grafana.riotpiao.com
|
||||
|
||||
# No anonymous read access — every user must log in via Authentik SSO.
|
||||
auth.anonymous:
|
||||
@@ -70,9 +70,9 @@ grafana.ini:
|
||||
allow_sign_up: true
|
||||
client_id: grafana
|
||||
scopes: openid email profile
|
||||
auth_url: https://authentik.riotpiao.homelab.com/application/o/authorize/
|
||||
token_url: https://authentik.riotpiao.homelab.com/application/o/token/
|
||||
api_url: https://authentik.riotpiao.homelab.com/application/o/userinfo/
|
||||
auth_url: https://authentik.riotpiao.com/application/o/authorize/
|
||||
token_url: https://authentik.riotpiao.com/application/o/token/
|
||||
api_url: https://authentik.riotpiao.com/application/o/userinfo/
|
||||
role_attribute_path: "contains(groups[*], 'grafana-admins') && 'Admin' || 'Viewer'"
|
||||
use_pkce: false
|
||||
use_refresh_token: false
|
||||
@@ -154,7 +154,7 @@ tolerations:
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
|
||||
# ClusterIP only — access via ingress (grafana.riotpiao.homelab.com) or port-forward.
|
||||
# ClusterIP only — access via ingress (grafana.riotpiao.com) or port-forward.
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
@@ -40,27 +40,27 @@ serviceMonitor:
|
||||
module: http_2xx
|
||||
targets:
|
||||
- name: grafana
|
||||
url: https://grafana.riotpiao.homelab.com/
|
||||
url: https://grafana.riotpiao.com/
|
||||
- name: loki
|
||||
url: https://loki.riotpiao.homelab.com/ready
|
||||
url: https://loki.riotpiao.com/ready
|
||||
- name: authentik
|
||||
url: https://authentik.riotpiao.homelab.com/-/health/ready/
|
||||
url: https://authentik.riotpiao.com/-/health/ready/
|
||||
- name: vault
|
||||
url: https://vault.riotpiao.homelab.com/v1/sys/health
|
||||
url: https://vault.riotpiao.com/v1/sys/health
|
||||
- name: minio-console
|
||||
url: https://minio.riotpiao.homelab.com/
|
||||
url: https://minio.riotpiao.com/
|
||||
- name: minio-api
|
||||
url: https://minio-api.riotpiao.homelab.com/minio/health/live
|
||||
url: https://minio-api.riotpiao.com/minio/health/live
|
||||
- name: prometheus
|
||||
url: https://prometheus.riotpiao.homelab.com/-/healthy
|
||||
url: https://prometheus.riotpiao.com/-/healthy
|
||||
- name: portainer
|
||||
url: https://portainer.riotpiao.homelab.com/
|
||||
url: https://portainer.riotpiao.com/
|
||||
- name: forgejo
|
||||
url: https://forgejo.riotpiao.homelab.com/api/healthz
|
||||
url: https://forgejo.riotpiao.com/api/healthz
|
||||
- name: argocd
|
||||
url: https://argocd.riotpiao.homelab.com/healthz
|
||||
url: https://argocd.riotpiao.com/healthz
|
||||
- name: longhorn
|
||||
url: https://longhorn.riotpiao.homelab.com/
|
||||
url: https://longhorn.riotpiao.com/
|
||||
|
||||
prometheusRule:
|
||||
enabled: true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Deployed via helmfile (name=argocd) so it sits alongside Authentik, MinIO, etc.
|
||||
#
|
||||
# UI is exposed via the cluster Ingress (k8s/ingress/ingress.yaml,
|
||||
# argocd.riotpiao.homelab.com) over the WireGuard/LAN-only nginx ingress —
|
||||
# argocd.riotpiao.com) over the WireGuard/LAN-only nginx ingress —
|
||||
# never as a LoadBalancer, since argocd-server holds cluster-admin
|
||||
# credentials and that Ingress isn't reachable from the WAN.
|
||||
#
|
||||
@@ -12,7 +12,7 @@
|
||||
# CA trust for Forgejo repo clones injected into argocd-tls-certs-cm by postsync hook.
|
||||
|
||||
global:
|
||||
domain: argocd.riotpiao.homelab.com
|
||||
domain: argocd.riotpiao.com
|
||||
|
||||
configs:
|
||||
params:
|
||||
@@ -23,10 +23,10 @@ configs:
|
||||
# Authentik (provision_oidc.py argocd_url) exactly — ArgoCD builds its
|
||||
# OIDC redirect_uri as "{url}/auth/callback", so any mismatch here is
|
||||
# what Authentik's "Invalid redirect URL" error means.
|
||||
url: "https://argocd.riotpiao.homelab.com"
|
||||
url: "https://argocd.riotpiao.com"
|
||||
oidc.config: |
|
||||
name: Authentik
|
||||
issuer: https://authentik.riotpiao.homelab.com/application/o/argocd/
|
||||
issuer: https://authentik.riotpiao.com/application/o/argocd/
|
||||
clientID: $oidc-secret:client-id
|
||||
clientSecret: $oidc-secret:client-secret
|
||||
requestedScopes: [openid, profile, email, groups]
|
||||
|
||||
@@ -4,7 +4,7 @@ runner:
|
||||
tag: "6" # pin exact release before apply
|
||||
name: talos-runner
|
||||
labels: "docker:docker://node:22-bookworm"
|
||||
forgejoUrl: https://forgejo.riotpiao.homelab.com
|
||||
forgejoUrl: https://forgejo.riotpiao.com
|
||||
# tokenSecret: name of the K8s Secret that holds the runner registration token
|
||||
# created automatically by the helmfile presync hook (see helmfile.yaml.gotmpl)
|
||||
tokenSecret: runner-token
|
||||
|
||||
@@ -16,7 +16,7 @@ spec:
|
||||
containers:
|
||||
- name: api
|
||||
# CI bumps this tag on every push to main (ci.yml step "bump deploy repo")
|
||||
image: forgejo.riotpiao.homelab.com/rock/api:latest
|
||||
image: forgejo.riotpiao.com/rock/api:latest
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
resources:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
||||
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||
targetRevision: main
|
||||
path: api
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
||||
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||
targetRevision: main
|
||||
path: argocd
|
||||
destination:
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git
|
||||
repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git
|
||||
targetRevision: main
|
||||
path: forge
|
||||
destination:
|
||||
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
# ── 2. Build + push OCI image ───────────────────────────────────────────
|
||||
- name: build and push image
|
||||
env:
|
||||
REGISTRY: forgejo.forge.riotpiao.homelab.com
|
||||
REGISTRY: forgejo.forge.riotpiao.com
|
||||
OWNER: rock
|
||||
run: |
|
||||
REPO_NAME=${{ github.event.repository.name }}
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
# Argo CD notices the commit and rolls out the new image.
|
||||
- name: bump deploy repo
|
||||
env:
|
||||
REGISTRY: forgejo.forge.riotpiao.homelab.com
|
||||
REGISTRY: forgejo.forge.riotpiao.com
|
||||
OWNER: rock
|
||||
run: |
|
||||
git clone \
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
|
||||
git -C /tmp/deploy \
|
||||
-c user.name="ci-bot" \
|
||||
-c user.email="[email protected].homelab.com" \
|
||||
-c user.email="[email protected]" \
|
||||
commit -am "${REPO_NAME}: deploy ${TAG}"
|
||||
|
||||
git -C /tmp/deploy push
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: forgejo-redis
|
||||
namespace: cicd
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: forgejo-redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: forgejo-redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: forgejo-redis
|
||||
namespace: cicd
|
||||
spec:
|
||||
selector:
|
||||
app: forgejo-redis
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
@@ -1,7 +1,10 @@
|
||||
# k8s/talos-ci-cd/forgejo-values.yaml
|
||||
# Forgejo deployed via the gitea-charts/gitea Helm chart with image override.
|
||||
# Admin password injected via helmfile --set (FORGEJO_ADMIN_PASSWORD in .env).
|
||||
# Runner is managed by a separate helmfile release (charts/forgejo-runner/).
|
||||
# k8s/security/ci-cd/forgejo-values.yaml
|
||||
# Forgejo deployed via the gitea-charts/gitea Helm chart with image override,
|
||||
# as an ArgoCD Application with an inline Helm source (k8s/argocd/apps/forgejo.yaml).
|
||||
# Admin password set via --set at install time (FORGEJO_ADMIN_PASSWORD in .env).
|
||||
# DB: CNPG (k8s/data/ddb-cluster.yaml + forgejo-database.yaml), not SQLite.
|
||||
# Cache/session/queue: dedicated Redis (forgejo-redis.yaml), not in-memory —
|
||||
# required once replicaCount > 1, since in-memory state isn't shared across pods.
|
||||
#
|
||||
# Chart docs: https://gitea.com/gitea/helm-chart
|
||||
|
||||
@@ -21,16 +24,18 @@ gitea:
|
||||
config:
|
||||
server:
|
||||
PROTOCOL: http # nginx ingress handles TLS; pod serves plain HTTP
|
||||
DOMAIN: forgejo.riotpiao.homelab.com
|
||||
ROOT_URL: https://forgejo.riotpiao.homelab.com/
|
||||
DOMAIN: forgejo.riotpiao.com
|
||||
ROOT_URL: https://forgejo.riotpiao.com/
|
||||
HTTP_PORT: 3000
|
||||
START_SSH_SERVER: true
|
||||
SSH_DOMAIN: forgejo.riotpiao.homelab.com
|
||||
SSH_DOMAIN: forgejo.riotpiao.com
|
||||
SSH_PORT: 2222
|
||||
SSH_LISTEN_PORT: 2222
|
||||
database:
|
||||
DB_TYPE: sqlite3
|
||||
PATH: /data/forgejo.db
|
||||
DB_TYPE: postgres
|
||||
HOST: ddb-cluster-rw.ddb.svc:5432
|
||||
NAME: forgejo
|
||||
USER: app
|
||||
repository:
|
||||
ROOT: /data/git
|
||||
actions:
|
||||
@@ -44,37 +49,49 @@ gitea:
|
||||
oauth2:
|
||||
ENABLED: true
|
||||
PROVIDER: openidconnect
|
||||
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration
|
||||
OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||
CLIENT_ID: forgejo
|
||||
AUTO_DISCOVER_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration
|
||||
AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration
|
||||
cache:
|
||||
ADAPTER: memory # no Redis — single-replica SQLite setup
|
||||
ADAPTER: redis
|
||||
HOST: redis://forgejo-redis.cicd.svc:6379/0
|
||||
session:
|
||||
PROVIDER: memory
|
||||
PROVIDER: redis
|
||||
PROVIDER_CONFIG: redis://forgejo-redis.cicd.svc:6379/1
|
||||
queue:
|
||||
TYPE: channel # in-memory queue; no file lock, no LevelDB contention on rollout
|
||||
TYPE: redis
|
||||
CONN_STR: redis://forgejo-redis.cicd.svc:6379/2
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true # kube-prometheus-stack discovers ServiceMonitors cluster-wide
|
||||
|
||||
# ── Persistence (Longhorn RWO — SQLite lives here) ────────────────────────────
|
||||
# ── Persistence (Longhorn RWX — git repo data shared across replicas) ────────
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: longhorn
|
||||
size: 20Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
- ReadWriteMany
|
||||
|
||||
# ── Replicas ──────────────────────────────────────────────────────────────────
|
||||
# Postgres (CNPG) + Redis (session/cache/queue) + RWX storage means replicas
|
||||
# no longer need to serialize on a single pod like the old SQLite setup did.
|
||||
replicaCount: 2
|
||||
|
||||
# ── Deployment strategy ────────────────────────────────────────────────────────
|
||||
# RWO PVC + SQLite: old pod must terminate before new one mounts the volume.
|
||||
deployment:
|
||||
strategy:
|
||||
type: Recreate
|
||||
type: RollingUpdate
|
||||
env:
|
||||
- name: SSL_CERT_DIR
|
||||
value: /homelab-ca
|
||||
- name: GITEA__database__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: ddb-cluster-app
|
||||
key: password
|
||||
|
||||
# ── Cert / CA auto-reload ─────────────────────────────────────────────────────
|
||||
# nginx serves the wildcard-tls cert — Forgejo itself never reads a TLS secret.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: ci-cd
|
||||
resources: []
|
||||
# Helm charts (forgejo-runner) deployed via ArgoCD Helm source
|
||||
resources:
|
||||
- forgejo-redis.yaml
|
||||
# Helm charts (forgejo, forgejo-runner) deployed via standalone ArgoCD
|
||||
# Applications with Helm sources (k8s/argocd/apps/forgejo.yaml) — not through
|
||||
# this kustomization, since layer-4-security syncs from Forgejo's own repo
|
||||
# (chicken-egg: Forgejo can't be the source of truth for deploying itself).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 0. Source your env (Authentik bootstrap token + Vault addr)
|
||||
set -a && source ~/.authentik/.env && set +a
|
||||
VAULT_ADDR="http://vault.riotpiao.homelab.com"
|
||||
AUTHENTIK_URL="http://authentik.riotpiao.homelab.com"
|
||||
VAULT_ADDR="http://vault.riotpiao.com"
|
||||
AUTHENTIK_URL="http://authentik.riotpiao.com"
|
||||
|
||||
# 1. Fetch the real client_id + client_secret from Authentik
|
||||
PROVIDER_PK=$(curl -s \
|
||||
|
||||
@@ -78,7 +78,7 @@ cd /Users/rockliang/workplace/homelab
|
||||
python3 k8s/talos-iam/register_oauth_app.py \
|
||||
--service-name my-app \
|
||||
--namespace my-namespace \
|
||||
--redirect-uri "https://my-app.riotpiao.homelab.com/oauth2/callback" \
|
||||
--redirect-uri "https://my-app.riotpiao.com/oauth2/callback" \
|
||||
--service-name-in-vault "MY_SERVICE" \
|
||||
--vault-jwt-policy "shell-secrets"
|
||||
```
|
||||
@@ -127,7 +127,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 &
|
||||
- **Name:** `yourservice`
|
||||
- **Client ID:** `yourservice` (or custom)
|
||||
- **Client Secret:** (paste from `$CLIENT_SECRET` above)
|
||||
- **Redirect URIs:** `https://your-app.riotpiao.homelab.com/oauth2/callback` (or your app's callback URL)
|
||||
- **Redirect URIs:** `https://your-app.riotpiao.com/oauth2/callback` (or your app's callback URL)
|
||||
- **Sub Mode:** `Hashed User ID`
|
||||
- **Include claims in ID Token:** ✓ Enabled
|
||||
- **Grant Types:** `Authorization Code`, `Refresh Token`
|
||||
@@ -143,7 +143,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 &
|
||||
- **Name:** `Your App Display Name`
|
||||
- **Slug:** `yourservice` (must match provider slug)
|
||||
- **Provider:** (select the provider created above)
|
||||
- **Meta Launch URL:** `https://your-app.riotpiao.homelab.com` (optional, for app launcher)
|
||||
- **Meta Launch URL:** `https://your-app.riotpiao.com` (optional, for app launcher)
|
||||
|
||||
3. **Save**
|
||||
|
||||
@@ -160,7 +160,7 @@ OIDC_CLIENT_ID=yourservice
|
||||
OIDC_CLIENT_SECRET=$CLIENT_SECRET
|
||||
|
||||
# Redirect URI (must match what you configured in step 2)
|
||||
OIDC_REDIRECT_URI=https://your-app.riotpiao.homelab.com/oauth2/callback
|
||||
OIDC_REDIRECT_URI=https://your-app.riotpiao.com/oauth2/callback
|
||||
|
||||
# Optionally, token validation endpoint
|
||||
OIDC_TOKEN_URL=http://authentik-server.iam.svc.cluster.local/application/o/yourservice/token/
|
||||
@@ -179,7 +179,7 @@ talos put cluster/YOURSERVICE_OIDC_CLIENT_SECRET YOURSERVICE_OIDC_CLIENT_SECRET=
|
||||
talos put cluster/yourservice-oidc \
|
||||
client_id=yourservice \
|
||||
issuer_url="http://authentik-server.iam.svc.cluster.local/application/o/yourservice/" \
|
||||
callback_uri="https://your-app.riotpiao.homelab.com/oauth2/callback"
|
||||
callback_uri="https://your-app.riotpiao.com/oauth2/callback"
|
||||
```
|
||||
|
||||
### Step 5: Mount Credentials in Your Service
|
||||
@@ -378,7 +378,7 @@ kubectl get secret yourservice-oidc -n your-namespace -o jsonpath='{.data}' | ba
|
||||
vault read auth/jwt/role/yourservice
|
||||
|
||||
# 5. Test OAuth login (requires port-forward to your app)
|
||||
# Open http://your-app.riotpiao.homelab.com/login
|
||||
# Open http://your-app.riotpiao.com/login
|
||||
# Should redirect to Authentik, then back to your app
|
||||
|
||||
# 6. Test JWT auth to Vault (if applicable)
|
||||
|
||||
@@ -227,7 +227,7 @@ The homelab provides **automated OAuth registration** for new services via `regi
|
||||
python3 k8s/talos-iam/register_oauth_app.py \
|
||||
--service-name my-service \
|
||||
--namespace my-ns \
|
||||
--redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \
|
||||
--redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \
|
||||
--service-name-in-vault MY_SERVICE \
|
||||
--vault-jwt-policy shell-secrets \
|
||||
--add-group my-service-admins
|
||||
@@ -254,7 +254,7 @@ export DASHBOARD_OIDC_CLIENT_SECRET
|
||||
python3 k8s/talos-iam/register_oauth_app.py \
|
||||
--service-name dashboard-service \
|
||||
--namespace apps \
|
||||
--redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \
|
||||
--redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \
|
||||
--service-name-in-vault DASHBOARD \
|
||||
--vault-jwt-policy shell-secrets \
|
||||
--add-group dashboard-admins \
|
||||
@@ -282,7 +282,7 @@ kubectl get secret my-service-oidc -n my-ns -o yaml
|
||||
vault read auth/jwt/role/my-service
|
||||
|
||||
# Test OAuth login
|
||||
# Browser: https://my-service.riotpiao.homelab.com/login
|
||||
# Browser: https://my-service.riotpiao.com/login
|
||||
# Should redirect to Authentik → back to service with session
|
||||
```
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ authentik:
|
||||
# Must match what the browser sees — if it returns an internal svc URL,
|
||||
# the browser's redirect after login will fail (can't reach svc DNS externally).
|
||||
# HTTP (not HTTPS) because the Authentik ingress has no TLS cert configured.
|
||||
host: "https://authentik.riotpiao.homelab.com"
|
||||
host: "https://authentik.riotpiao.com"
|
||||
|
||||
error_reporting:
|
||||
enabled: false # do not phone home to Sentry
|
||||
@@ -103,7 +103,7 @@ _caEnv: &caEnv
|
||||
# ── Authentik server (UI + API) ───────────────────────────────────────────────
|
||||
# Handles all browser traffic: login flows, admin UI, OAuth2 authorize/token endpoints.
|
||||
# NodePort 32172 is a fallback for direct node access during troubleshooting;
|
||||
# normal access is via nginx ingress (authentik.riotpiao.homelab.com → svc:80).
|
||||
# normal access is via nginx ingress (authentik.riotpiao.com → svc:80).
|
||||
# Recreate: single replica + RWO-adjacent state — avoids split-brain on redeploy.
|
||||
server:
|
||||
replicas: 1
|
||||
@@ -221,5 +221,5 @@ redis:
|
||||
operator: Exists
|
||||
architecture: standalone
|
||||
|
||||
# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.homelab.com).
|
||||
# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.com).
|
||||
# For direct access during bootstrap: kubectl -n iam port-forward svc/authentik-server 7000:80
|
||||
|
||||
@@ -23,7 +23,7 @@ To use this example:
|
||||
python3 register_oauth_app.py \\
|
||||
--service-name dashboard-service \\
|
||||
--namespace apps \\
|
||||
--redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \\
|
||||
--redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \\
|
||||
--service-name-in-vault DASHBOARD \\
|
||||
--vault-jwt-policy shell-secrets \\
|
||||
--add-group dashboard-admins \\
|
||||
@@ -34,7 +34,7 @@ To use this example:
|
||||
http://localhost:7000/api/v3/core/applications/?slug=dashboard-service | jq .
|
||||
|
||||
# 5. Test OAuth callback (requires app running)
|
||||
# Browser: http://dashboard.riotpiao.homelab.com/login
|
||||
# Browser: http://dashboard.riotpiao.com/login
|
||||
# Should redirect to Authentik → back to dashboard with session
|
||||
"""
|
||||
|
||||
@@ -68,7 +68,7 @@ def example_dashboard_service():
|
||||
"register_oauth_app.py",
|
||||
"--service-name", "dashboard-service",
|
||||
"--namespace", "apps",
|
||||
"--redirect-uri", "https://dashboard.riotpiao.homelab.com/oauth2/callback",
|
||||
"--redirect-uri", "https://dashboard.riotpiao.com/oauth2/callback",
|
||||
"--service-name-in-vault", "DASHBOARD",
|
||||
"--vault-jwt-policy", "shell-secrets",
|
||||
"--add-group", "dashboard-admins",
|
||||
@@ -122,7 +122,7 @@ def verify_example():
|
||||
print()
|
||||
|
||||
print("✅ Test OAuth redirect (requires app running):")
|
||||
print(" curl -L https://dashboard.riotpiao.homelab.com/login")
|
||||
print(" curl -L https://dashboard.riotpiao.com/login")
|
||||
print(" # Should redirect to Authentik, then back to dashboard")
|
||||
print()
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Usage:
|
||||
python3 register_oauth_app.py \\
|
||||
--service-name my-service \\
|
||||
--namespace my-ns \\
|
||||
--redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \\
|
||||
--redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \\
|
||||
[--service-name-in-vault MY_SERVICE] \\
|
||||
[--vault-jwt-policy shell-secrets]
|
||||
|
||||
@@ -28,13 +28,13 @@ Examples:
|
||||
python3 register_oauth_app.py \\
|
||||
--service-name myapp \\
|
||||
--namespace apps \\
|
||||
--redirect-uri "https://myapp.riotpiao.homelab.com/callback"
|
||||
--redirect-uri "https://myapp.riotpiao.com/callback"
|
||||
|
||||
# Advanced: full service with Vault JWT auth
|
||||
python3 register_oauth_app.py \\
|
||||
--service-name myservice \\
|
||||
--namespace my-namespace \\
|
||||
--redirect-uri "https://myservice.riotpiao.homelab.com/oauth2/callback" \\
|
||||
--redirect-uri "https://myservice.riotpiao.com/oauth2/callback" \\
|
||||
--service-name-in-vault MYSERVICE \\
|
||||
--vault-jwt-policy shell-secrets \\
|
||||
--add-group myservice-admins \\
|
||||
@@ -328,7 +328,7 @@ def main() -> None:
|
||||
parser.add_argument(
|
||||
"--redirect-uri",
|
||||
required=True,
|
||||
help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.homelab.com/callback)"
|
||||
help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.com/callback)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--service-name-in-vault",
|
||||
@@ -420,7 +420,7 @@ def main() -> None:
|
||||
display_name=service_name.replace("-", " ").title(),
|
||||
slug=service_name,
|
||||
provider_pk=provider_pk,
|
||||
launch_url=f"https://{service_name}.riotpiao.homelab.com"
|
||||
launch_url=f"https://{service_name}.riotpiao.com"
|
||||
)
|
||||
print()
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ _vault_browser_payload=$(jq -n \
|
||||
invalidation_flow: $inval_flow,
|
||||
signing_key: $signing_key,
|
||||
redirect_uris: [
|
||||
{"matching_mode": "strict", "url": "http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback"},
|
||||
{"matching_mode": "strict", "url": "http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback"},
|
||||
{"matching_mode": "strict", "url": "http://localhost:8250/oidc/callback"}
|
||||
]
|
||||
}')
|
||||
@@ -465,7 +465,7 @@ step oidc_enable "Enabling OIDC auth method for browser login..."
|
||||
vault auth enable oidc 2>/dev/null || echo "OIDC auth already enabled."
|
||||
|
||||
vault write auth/oidc/config \
|
||||
oidc_discovery_url="http://authentik.riotpiao.homelab.com/application/o/vault-browser/" \
|
||||
oidc_discovery_url="http://authentik.riotpiao.com/application/o/vault-browser/" \
|
||||
oidc_client_id="vault-browser" \
|
||||
oidc_client_secret="${VAULT_BROWSER_CLIENT_SECRET}" \
|
||||
default_role="homelab"
|
||||
@@ -475,7 +475,7 @@ vault write auth/oidc/config \
|
||||
vault write auth/oidc/role/homelab \
|
||||
role_type=oidc \
|
||||
bound_audiences="vault-browser" \
|
||||
allowed_redirect_uris="http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \
|
||||
allowed_redirect_uris="http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \
|
||||
user_claim="sub" \
|
||||
oidc_scopes="openid,profile,email" \
|
||||
token_policies="shell-secrets,cluster-admin" \
|
||||
@@ -483,8 +483,8 @@ vault write auth/oidc/role/homelab \
|
||||
token_max_ttl=12h
|
||||
|
||||
echo "OIDC auth configured."
|
||||
echo " Browser login: http://vault.riotpiao.homelab.com → sign in with Authentik"
|
||||
echo " CLI login: VAULT_ADDR=http://vault.riotpiao.homelab.com vault login -method=oidc"
|
||||
echo " Browser login: http://vault.riotpiao.com → sign in with Authentik"
|
||||
echo " CLI login: VAULT_ADDR=http://vault.riotpiao.com vault login -method=oidc"
|
||||
|
||||
# ── 14. Seed initial secrets ──────────────────────────────────────────────────
|
||||
step seed_secrets "Seeding initial secrets from environment (accessible after OIDC login)..."
|
||||
@@ -519,8 +519,8 @@ echo "==> Vault bootstrap complete."
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Move ${UNSEAL_KEYS_FILE} OFFLINE (USB / password manager)."
|
||||
echo " 2. Browser login: open http://vault.riotpiao.homelab.com → choose OIDC → sign in with Authentik"
|
||||
echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.homelab.com"
|
||||
echo " 2. Browser login: open http://vault.riotpiao.com → choose OIDC → sign in with Authentik"
|
||||
echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.com"
|
||||
echo " vault login -method=oidc"
|
||||
echo " 4. Read MinIO credentials from Vault after login:"
|
||||
echo " vault kv get secret/cluster/minio"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# once after first install to initialize and store the keys).
|
||||
|
||||
# ── Global ────────────────────────────────────────────────────────────────────
|
||||
# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.homelab.com)
|
||||
# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.com)
|
||||
# or at port-forward. In-cluster traffic to Vault is plain HTTP; this is acceptable
|
||||
# because all clients are on the pod network (not crossing node boundaries).
|
||||
global:
|
||||
@@ -137,7 +137,7 @@ server:
|
||||
|
||||
# ── Service ─────────────────────────────────────────────────────────────────
|
||||
# NodePort 32171 — fallback for direct node access during bootstrap before
|
||||
# the ingress is up. Normal access is via nginx ingress (vault.riotpiao.homelab.com).
|
||||
# the ingress is up. Normal access is via nginx ingress (vault.riotpiao.com).
|
||||
service:
|
||||
type: NodePort
|
||||
port: 8200
|
||||
@@ -155,7 +155,7 @@ server:
|
||||
# ── UI ────────────────────────────────────────────────────────────────────────
|
||||
# Vault's web UI is used for the OIDC browser login flow (Vault as an OIDC
|
||||
# provider, if configured) and for manual operator inspection.
|
||||
# Accessible at http://vault.riotpiao.homelab.com or via port-forward.
|
||||
# Accessible at http://vault.riotpiao.com or via port-forward.
|
||||
ui:
|
||||
enabled: true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user