diff --git a/README.md b/README.md index e492f0e..5a85cff 100644 --- a/README.md +++ b/README.md @@ -1 +1,37 @@ # k8s-asxpio-gitops + +GitOps repo for self-hosted Kubernetes cluster on Hetzner, managed by ArgoCD. + +## Cluster + +- **Provider:** Hetzner Cloud, `hel1` (Helsinki) +- **Infrastructure:** [../hcloud-k8s](../hcloud-k8s) (Terraform, [hcloud-k8s/kubernetes](https://registry.terraform.io/modules/hcloud-k8s/kubernetes/hcloud) module v3.27.2) +- **OS:** Talos Linux +- **Nodes:** 1x control plane (`cx23`) + 2x worker (`cx23`) — each 2 vCPU, 4 GB RAM +- **Ingress:** Traefik v35.0.1 (Helm), Let's Encrypt TLS via ACME TLS challenge (`certs@asxp.io`) +- **Storage:** `hcloud-volumes` StorageClass +- **Cert Manager:** enabled +- **Terraform state:** S3-compatible object storage (`hel1.your-objectstorage.com`, bucket `k8s-asxpio-main`) + +## DNS + +`*.k8s.asxp.io` — wildcard pointing to cluster ingress IP. + +## Apps + +| App | Namespace | URL | +|-----|-----------|-----| +| ArgoCD | `argocd` | — | +| CNPG Operator | `cnpg-system` | — | +| PostgreSQL (HA) | `postgres` | 3 instances (CloudNativePG) | +| Forgejo | `forgejo` | `git.czsk.it` / `git.asxp.io` | +| WatchParty | `watchparty` | `watch.k8s.asxp.io` | + +## Structure + +``` +apps/ + app-of-apps.yaml # bootstrap — points ArgoCD at this directory + .yaml # ArgoCD Application per app + / # raw manifests per app +``` diff --git a/apps/cnpg-operator.yaml b/apps/cnpg-operator.yaml new file mode 100644 index 0000000..2311bf5 --- /dev/null +++ b/apps/cnpg-operator.yaml @@ -0,0 +1,20 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: cnpg-operator + namespace: argocd +spec: + project: default + source: + repoURL: https://cloudnative-pg.github.io/charts + chart: cloudnative-pg + targetRevision: 0.28.0 + destination: + server: https://kubernetes.default.svc + namespace: cnpg-system + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/apps/postgres.yaml b/apps/postgres.yaml new file mode 100644 index 0000000..c68094e --- /dev/null +++ b/apps/postgres.yaml @@ -0,0 +1,20 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: postgres + namespace: argocd +spec: + project: default + source: + repoURL: ssh://git@git.czsk.it/asxpi/k8s-asxpio-gitops.git + targetRevision: main + path: apps/postgres + destination: + server: https://kubernetes.default.svc + namespace: postgres + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/apps/postgres/cluster.yaml b/apps/postgres/cluster.yaml new file mode 100644 index 0000000..db00521 --- /dev/null +++ b/apps/postgres/cluster.yaml @@ -0,0 +1,23 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: postgres-cluster + namespace: postgres +spec: + instances: 2 + primaryUpdateStrategy: unsupervised + + enableSuperuserAccess: true + + postgresql: + parameters: + shared_buffers: "256MB" + max_connections: "200" + + storage: + size: 10Gi + storageClass: hcloud-volumes + + affinity: + enablePodAntiAffinity: true + topologyKey: kubernetes.io/hostname diff --git a/apps/postgres/db-watchparty.yaml b/apps/postgres/db-watchparty.yaml new file mode 100644 index 0000000..920970f --- /dev/null +++ b/apps/postgres/db-watchparty.yaml @@ -0,0 +1,10 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Database +metadata: + name: watchparty-db + namespace: postgres +spec: + name: watchparty + owner: app + cluster: + name: postgres-cluster diff --git a/apps/watchparty/deployment.yaml b/apps/watchparty/deployment.yaml index 6dfc73a..2b01708 100644 --- a/apps/watchparty/deployment.yaml +++ b/apps/watchparty/deployment.yaml @@ -24,6 +24,13 @@ spec: value: "8080" - name: HOST value: "0.0.0.0" + - name: PG_PASSWORD + valueFrom: + secretKeyRef: + name: postgres-cluster-app + key: password + - name: DATABASE_URL + value: postgresql://app:$(PG_PASSWORD)@postgres-cluster-rw.postgres.svc.cluster.local:5432/watchparty resources: requests: memory: 256Mi