summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-14 15:32:21 +0300
committerPaul Buetow <paul@buetow.org>2026-04-14 15:32:21 +0300
commit112cf5742d65ac41ffd94680d4dce349626010a4 (patch)
tree92ef0d2d832c629f34ff521bd39a42da898e5350
parente592c41ae27881cc645bb66d4c7fac9e976fad0f (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.md7
-rw-r--r--f3s/argocd-apps/services/goprecords.yaml28
-rw-r--r--f3s/goprecords/Justfile46
-rw-r--r--f3s/goprecords/README.md42
-rw-r--r--f3s/goprecords/docker-image/Justfile13
-rw-r--r--f3s/goprecords/helm-chart/Chart.yaml5
-rw-r--r--f3s/goprecords/helm-chart/templates/deployment.yaml57
-rw-r--r--f3s/goprecords/helm-chart/templates/ingress.yaml45
-rw-r--r--f3s/goprecords/helm-chart/templates/persistent-volumes.yaml27
-rw-r--r--f3s/goprecords/helm-chart/templates/service.yaml15
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