diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-14 15:32:21 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-14 15:32:21 +0300 |
| commit | 112cf5742d65ac41ffd94680d4dce349626010a4 (patch) | |
| tree | 92ef0d2d832c629f34ff521bd39a42da898e5350 | |
| parent | e592c41ae27881cc645bb66d4c7fac9e976fad0f (diff) | |
Add goprecords service deployment for f3s.
Introduce Docker build/push workflow, Helm manifests, and ArgoCD application wiring for goprecords so the cluster can deploy the new daemon API service from the private registry.
Made-with: Cursor
| -rw-r--r-- | f3s/argocd-apps/README.md | 7 | ||||
| -rw-r--r-- | f3s/argocd-apps/services/goprecords.yaml | 28 | ||||
| -rw-r--r-- | f3s/goprecords/Justfile | 46 | ||||
| -rw-r--r-- | f3s/goprecords/README.md | 42 | ||||
| -rw-r--r-- | f3s/goprecords/docker-image/Justfile | 13 | ||||
| -rw-r--r-- | f3s/goprecords/helm-chart/Chart.yaml | 5 | ||||
| -rw-r--r-- | f3s/goprecords/helm-chart/templates/deployment.yaml | 57 | ||||
| -rw-r--r-- | f3s/goprecords/helm-chart/templates/ingress.yaml | 45 | ||||
| -rw-r--r-- | f3s/goprecords/helm-chart/templates/persistent-volumes.yaml | 27 | ||||
| -rw-r--r-- | f3s/goprecords/helm-chart/templates/service.yaml | 15 |
10 files changed, 282 insertions, 3 deletions
diff --git a/f3s/argocd-apps/README.md b/f3s/argocd-apps/README.md index c5470b0..58f51a4 100644 --- a/f3s/argocd-apps/README.md +++ b/f3s/argocd-apps/README.md @@ -21,6 +21,7 @@ argocd-apps/ │ ├── filebrowser.yaml # Web-based file browser │ ├── freshrss.yaml # RSS feed reader │ ├── immich.yaml # Photo management +│ ├── goprecords.yaml # Uptime report daemon and API │ ├── keybr.yaml # Typing practice │ ├── kobo-sync-server.yaml # KOReader sync server │ ├── miniflux.yaml # Minimalist RSS reader @@ -40,11 +41,11 @@ argocd-apps/ ## Application Count by Namespace - **monitoring**: 6 applications -- **services**: 13 applications +- **services**: 14 applications - **infra**: 1 application - **test**: 1 application -**Total**: 21 applications +**Total**: 22 applications ## Usage @@ -168,7 +169,7 @@ kubectl create namespace test kubectl apply -f argocd-apps/ -R ``` -5. ArgoCD automatically deploys all 21 applications +5. ArgoCD automatically deploys all 22 applications Total recovery time: ~30 minutes. diff --git a/f3s/argocd-apps/services/goprecords.yaml b/f3s/argocd-apps/services/goprecords.yaml new file mode 100644 index 0000000..de2f197 --- /dev/null +++ b/f3s/argocd-apps/services/goprecords.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: goprecords + namespace: cicd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: http://git-server.cicd.svc.cluster.local/conf.git + targetRevision: master + path: f3s/goprecords/helm-chart + destination: + server: https://kubernetes.default.svc + namespace: services + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + retry: + limit: 3 + backoff: + duration: 5s + factor: 2 + maxDuration: 1m diff --git a/f3s/goprecords/Justfile b/f3s/goprecords/Justfile new file mode 100644 index 0000000..b389fc0 --- /dev/null +++ b/f3s/goprecords/Justfile @@ -0,0 +1,46 @@ +NAMESPACE := "services" +APP_NAME := "goprecords" + +build: + just -f docker-image/Justfile build + +push: + just -f docker-image/Justfile push + +build-push: build push + +status: + @echo "=== Pods ===" + @kubectl get pods -n {{NAMESPACE}} | grep goprecords + @echo "" + @echo "=== Service ===" + @kubectl get svc -n {{NAMESPACE}} goprecords-service + @echo "" + @echo "=== Ingress ===" + @kubectl get ingress -n {{NAMESPACE}} goprecords-ingress + @echo "" + @echo "=== PVC ===" + @kubectl get pvc -n {{NAMESPACE}} goprecords-stats-pvc + @echo "" + @echo "=== ArgoCD Status ===" + @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' 2>/dev/null && echo "" || echo "Not found" + +logs lines="100": + kubectl logs -n {{NAMESPACE}} -l app=goprecords --tail={{lines}} -f + +port-forward port="8080": + @echo "Forwarding goprecords to localhost:{{port}}" + kubectl port-forward -n {{NAMESPACE}} svc/goprecords-service {{port}}:80 + +sync: + @echo "Triggering ArgoCD sync..." + @kubectl annotate application {{APP_NAME}} -n cicd argocd.argoproj.io/refresh=normal --overwrite + @sleep 2 + @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' && echo "" + +argocd-status: + argocd app get {{APP_NAME}} --core + +restart: + @echo "Restarting goprecords..." + kubectl rollout restart -n {{NAMESPACE}} deployment/goprecords diff --git a/f3s/goprecords/README.md b/f3s/goprecords/README.md new file mode 100644 index 0000000..f1c95e4 --- /dev/null +++ b/f3s/goprecords/README.md @@ -0,0 +1,42 @@ +# goprecords on f3s + +This directory contains Docker image and Kubernetes deployment config for `goprecords`. + +## Image workflow + +Build and push to the private NodePort registry: + +```bash +cd /home/paul/git/conf/f3s/goprecords +just build-push +``` + +The image is pushed as: + +- `r0.lan.buetow.org:30001/goprecords:0.3.0` + +The deployment pulls from: + +- `registry.lan.buetow.org:30001/goprecords:0.3.0` + +## Runtime config + +The container runs daemon mode: + +- `-daemon` +- `-listen=:8080` +- `-stats-dir=/data/stats` + +Data persistence: + +- PVC: `goprecords-stats-pvc` +- Mount path: `/data/stats` +- Auth DB defaults to `/data/stats/goprecords-auth.db` + +## Endpoints + +- `/health` (liveness) +- `/livez` (liveness) +- `/readyz` (readiness) +- `/report` (HTTP read API) +- `/upload/{host}/{kind}` (upload API) diff --git a/f3s/goprecords/docker-image/Justfile b/f3s/goprecords/docker-image/Justfile new file mode 100644 index 0000000..046a789 --- /dev/null +++ b/f3s/goprecords/docker-image/Justfile @@ -0,0 +1,13 @@ +REGISTRY := "r0.lan.buetow.org:30001" +IMAGE := "goprecords" +TAG := "0.3.0" +SRC := "/home/paul/git/goprecords" + +build: + docker build -t {{IMAGE}}:{{TAG}} {{SRC}} + +push: + docker tag {{IMAGE}}:{{TAG}} {{REGISTRY}}/{{IMAGE}}:{{TAG}} + docker push {{REGISTRY}}/{{IMAGE}}:{{TAG}} + +all: build push diff --git a/f3s/goprecords/helm-chart/Chart.yaml b/f3s/goprecords/helm-chart/Chart.yaml new file mode 100644 index 0000000..d0c4329 --- /dev/null +++ b/f3s/goprecords/helm-chart/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: goprecords +description: A Helm chart for deploying goprecords daemon API. +version: 0.1.0 +appVersion: "0.3.0" diff --git a/f3s/goprecords/helm-chart/templates/deployment.yaml b/f3s/goprecords/helm-chart/templates/deployment.yaml new file mode 100644 index 0000000..2d460d4 --- /dev/null +++ b/f3s/goprecords/helm-chart/templates/deployment.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: goprecords + namespace: services +spec: + replicas: 1 + selector: + matchLabels: + app: goprecords + template: + metadata: + labels: + app: goprecords + spec: + containers: + - name: goprecords + image: registry.lan.buetow.org:30001/goprecords:0.3.0 + imagePullPolicy: Always + args: + - -daemon + - -listen=:8080 + - -stats-dir=/data/stats + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /livez + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "256Mi" + cpu: "500m" + securityContext: + allowPrivilegeEscalation: false + runAsUser: 0 + runAsGroup: 0 + volumeMounts: + - name: goprecords-stats + mountPath: /data/stats + volumes: + - name: goprecords-stats + persistentVolumeClaim: + claimName: goprecords-stats-pvc diff --git a/f3s/goprecords/helm-chart/templates/ingress.yaml b/f3s/goprecords/helm-chart/templates/ingress.yaml new file mode 100644 index 0000000..45aecd1 --- /dev/null +++ b/f3s/goprecords/helm-chart/templates/ingress.yaml @@ -0,0 +1,45 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: goprecords-ingress + namespace: services + annotations: + spec.ingressClassName: traefik + traefik.ingress.kubernetes.io/router.entrypoints: web +spec: + rules: + - host: goprecords.f3s.buetow.org + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: goprecords-service + port: + number: 80 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: goprecords-ingress-lan + namespace: services + annotations: + spec.ingressClassName: traefik + traefik.ingress.kubernetes.io/router.entrypoints: web,websecure +spec: + tls: + - hosts: + - goprecords.f3s.lan.buetow.org + secretName: f3s-lan-tls + rules: + - host: goprecords.f3s.lan.buetow.org + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: goprecords-service + port: + number: 80 diff --git a/f3s/goprecords/helm-chart/templates/persistent-volumes.yaml b/f3s/goprecords/helm-chart/templates/persistent-volumes.yaml new file mode 100644 index 0000000..3559be4 --- /dev/null +++ b/f3s/goprecords/helm-chart/templates/persistent-volumes.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: goprecords-stats-pv +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + hostPath: + path: /data/nfs/k3svolumes/goprecords/stats + type: DirectoryOrCreate +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: goprecords-stats-pvc + namespace: services +spec: + storageClassName: "" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/f3s/goprecords/helm-chart/templates/service.yaml b/f3s/goprecords/helm-chart/templates/service.yaml new file mode 100644 index 0000000..9266d46 --- /dev/null +++ b/f3s/goprecords/helm-chart/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: goprecords + name: goprecords-service + namespace: services +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + selector: + app: goprecords |
