diff --git a/AGENTS.md b/AGENTS.md index 48f285b..3a5994f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -217,6 +217,37 @@ k3s kubectl exec -n gitea deploy/gitea -- gitea admin user generate-access-token - HOSTNAME=0.0.0.0 - NODE_ENV=production +### TimescaleDB + +| Property | Value | +|---|---| +| Namespace | system | +| Image | timescale/timescaledb:2.29.1-pg16 | +| Workload | StatefulSet (1 replica) | +| Pod | timescaledb-0 | +| Service | timescaledb.system.svc.cluster.local:5432 | +| Storage | 10 Gi Longhorn PVC `timescaledb-data` | +| Auth | None (POSTGRES_HOST_AUTH_METHOD=trust) | +| PGDATA | /var/lib/postgresql/data/pgdata (subdir to avoid lost+found) | +| Extension | timescaledb v2.29.1 (auto-enabled on all databases) | + +**Connect from inside the cluster:** +```bash +# From any pod: +psql -h timescaledb.system.svc.cluster.local -U postgres + +# Via kubectl: +k3s kubectl exec -n system timescaledb-0 -- psql -U postgres +``` + +**Create a database with TimescaleDB:** +```bash +k3s kubectl exec -n system timescaledb-0 -- psql -U postgres -c "CREATE DATABASE mydb;" +k3s kubectl exec -n system timescaledb-0 -- psql -U postgres -d mydb -c "CREATE EXTENSION IF NOT EXISTS timescaledb;" +``` + +**No auth warning:** This instance has no password — it's designed for internal cluster use only (no ingress, no NodePort, ClusterIP only). Don't expose it externally. + ## Image Pull Secrets All namespaces pulling from Gitea registry use secret `gitea-registry`: @@ -324,3 +355,16 @@ docker push gitea.imcu.ro/homeschool/: # Update deployment k3s kubectl set image deploy/ =gitea.imcu.ro/homeschool/: -n ``` + +### Back up TimescaleDB + +```bash +# Dump a database +k3s kubectl exec -n system timescaledb-0 -- pg_dump -U postgres mydb > mydb-backup.sql + +# Dump all databases +k3s kubectl exec -n system timescaledb-0 -- pg_dumpall -U postgres > all-backup.sql + +# Restore +cat mydb-backup.sql | k3s kubectl exec -i -n system timescaledb-0 -- psql -U postgres -d mydb +``` diff --git a/README.md b/README.md index 8324e9b..5a091f0 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ All three are installed as k3s-native `HelmChart` resources in `kube-system` nam |---|---|---|---| | gitea-data | gitea | 10 Gi | Gitea SQLite DB, git repos, packages | | wolsey-content | default | 10 Gi | Wolsey static content (6.5 GB) | +| timescaledb-data | system | 10 Gi | TimescaleDB data | ## Workloads @@ -73,6 +74,7 @@ All three are installed as k3s-native `HelmChart` resources in `kube-system` nam | School Games (dev) | https://develop.imcu.ro | default | homeschool/games:7d3a57d | — | | School Games (default) | — | default | homeschool/games:2a4f03df | — | | Randomly | https://randomly.imcu.ro | randomly | homeschool/randomly:latest | — | +| TimescaleDB | timescaledb.system.svc:5432 | system | timescale/timescaledb:2.29.1-pg16 | 10 GB Longhorn | ## DNS (Cloudflare) @@ -215,7 +217,7 @@ k3s-cluster/ │ ├── cert-manager.yaml # TLS certificate manager (Let's Encrypt) │ └── longhorn.yaml # Distributed storage (2 replicas, /var/lib/longhorn/) ├── cluster-config/ # Cluster-wide configuration -│ ├── namespaces.yaml # Application namespaces (gitea, games, randomly) +│ ├── namespaces.yaml # Application namespaces (gitea, games, randomly, system) │ ├── clusterissuer.yaml # Let's Encrypt ClusterIssuer │ └── image-pull-secret-template.txt # How to create gitea-registry secrets └── workloads/ # Application manifests (deploy + svc + ingress + pvc) @@ -224,7 +226,8 @@ k3s-cluster/ ├── school-games-prod/school-games-prod.yaml ├── school-games-dev/school-games-dev.yaml ├── school-games-default/school-games-default.yaml - └── randomly/randomly.yaml + ├── randomly/randomly.yaml + └── timescaledb/timescaledb.yaml ``` ### How to update a service