From 51ccb1f61ef4c749b2a5d15df72b7910cd4c91dd Mon Sep 17 00:00:00 2001 From: funman300 Date: Mon, 18 May 2026 12:38:32 -0700 Subject: [PATCH] feat(obsidian-livesync): initial CouchDB LiveSync deployment --- .gitignore | 3 + apps/obsidian-livesync/couchdb-configmap.yaml | 23 ++++++ .../obsidian-livesync/couchdb-deployment.yaml | 71 +++++++++++++++++++ apps/obsidian-livesync/couchdb-ingress.yaml | 25 +++++++ apps/obsidian-livesync/couchdb-pvc.yaml | 11 +++ .../couchdb-secret.yaml.example | 22 ++++++ apps/obsidian-livesync/couchdb-service.yaml | 12 ++++ apps/obsidian-livesync/kustomization.yaml | 10 +++ apps/obsidian-livesync/namespace.yaml | 4 ++ argocd/obsidian-livesync.yaml | 27 +++++++ 10 files changed, 208 insertions(+) create mode 100644 .gitignore create mode 100644 apps/obsidian-livesync/couchdb-configmap.yaml create mode 100644 apps/obsidian-livesync/couchdb-deployment.yaml create mode 100644 apps/obsidian-livesync/couchdb-ingress.yaml create mode 100644 apps/obsidian-livesync/couchdb-pvc.yaml create mode 100644 apps/obsidian-livesync/couchdb-secret.yaml.example create mode 100644 apps/obsidian-livesync/couchdb-service.yaml create mode 100644 apps/obsidian-livesync/kustomization.yaml create mode 100644 apps/obsidian-livesync/namespace.yaml create mode 100644 argocd/obsidian-livesync.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb670e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Kubernetes secrets — apply manually, never commit +apps/**/*-secret.yaml +apps/**/*-auth-secret.yaml diff --git a/apps/obsidian-livesync/couchdb-configmap.yaml b/apps/obsidian-livesync/couchdb-configmap.yaml new file mode 100644 index 0000000..db0a493 --- /dev/null +++ b/apps/obsidian-livesync/couchdb-configmap.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: couchdb-config + namespace: obsidian +data: + livesync.ini: | + [couchdb] + single_node = true + + [chttpd] + bind_address = any + port = 5984 + require_valid_user = true + + [httpd] + enable_cors = true + + [cors] + origins = app://obsidian.md,capacitor://localhost,http://localhost + credentials = true + headers = accept, authorization, content-type, origin, referer + methods = GET, PUT, POST, HEAD, DELETE diff --git a/apps/obsidian-livesync/couchdb-deployment.yaml b/apps/obsidian-livesync/couchdb-deployment.yaml new file mode 100644 index 0000000..91f494f --- /dev/null +++ b/apps/obsidian-livesync/couchdb-deployment.yaml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: couchdb + namespace: obsidian +spec: + replicas: 1 + selector: + matchLabels: + app: couchdb + strategy: + type: Recreate + template: + metadata: + labels: + app: couchdb + spec: + containers: + - name: couchdb + image: couchdb:3 + env: + - name: COUCHDB_USER + valueFrom: + secretKeyRef: + name: couchdb-secret + key: COUCHDB_USER + - name: COUCHDB_PASSWORD + valueFrom: + secretKeyRef: + name: couchdb-secret + key: COUCHDB_PASSWORD + - name: COUCHDB_SECRET + valueFrom: + secretKeyRef: + name: couchdb-secret + key: COUCHDB_SECRET + ports: + - containerPort: 5984 + name: http + volumeMounts: + - name: couchdb-data + mountPath: /opt/couchdb/data + - name: couchdb-config + mountPath: /opt/couchdb/etc/local.d/livesync.ini + subPath: livesync.ini + livenessProbe: + httpGet: + path: /_up + port: 5984 + initialDelaySeconds: 30 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /_up + port: 5984 + initialDelaySeconds: 10 + periodSeconds: 10 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 256Mi + volumes: + - name: couchdb-data + persistentVolumeClaim: + claimName: couchdb-data + - name: couchdb-config + configMap: + name: couchdb-config diff --git a/apps/obsidian-livesync/couchdb-ingress.yaml b/apps/obsidian-livesync/couchdb-ingress.yaml new file mode 100644 index 0000000..972a196 --- /dev/null +++ b/apps/obsidian-livesync/couchdb-ingress.yaml @@ -0,0 +1,25 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: couchdb + namespace: obsidian + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + traefik.ingress.kubernetes.io/router.entrypoints: websecure +spec: + ingressClassName: traefik + rules: + - host: obsidian.aleshym.co + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: couchdb + port: + name: http + tls: + - hosts: + - obsidian.aleshym.co + secretName: couchdb-tls diff --git a/apps/obsidian-livesync/couchdb-pvc.yaml b/apps/obsidian-livesync/couchdb-pvc.yaml new file mode 100644 index 0000000..58eddaf --- /dev/null +++ b/apps/obsidian-livesync/couchdb-pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: couchdb-data + namespace: obsidian +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi diff --git a/apps/obsidian-livesync/couchdb-secret.yaml.example b/apps/obsidian-livesync/couchdb-secret.yaml.example new file mode 100644 index 0000000..621dbc2 --- /dev/null +++ b/apps/obsidian-livesync/couchdb-secret.yaml.example @@ -0,0 +1,22 @@ +# DO NOT COMMIT THE REAL VERSION OF THIS FILE. +# apps/obsidian-livesync/couchdb-secret.yaml is gitignored — apply it manually once: +# +# cp apps/obsidian-livesync/couchdb-secret.yaml.example apps/obsidian-livesync/couchdb-secret.yaml +# # fill in real values below, then: +# kubectl apply -f apps/obsidian-livesync/couchdb-secret.yaml +# kubectl annotate secret couchdb-secret -n obsidian \ +# argocd.argoproj.io/sync-options=Prune=false --overwrite +# +# Generate strong values with: +# python3 -c "import secrets; print(secrets.token_urlsafe(18))" # password +# python3 -c "import secrets; print(secrets.token_hex(32))" # COUCHDB_SECRET +apiVersion: v1 +kind: Secret +metadata: + name: couchdb-secret + namespace: obsidian +stringData: + COUCHDB_USER: "admin" + COUCHDB_PASSWORD: "CHANGE_ME" + # Erlang/OTP cookie — must be a long random hex string + COUCHDB_SECRET: "CHANGE_ME_HEX_32_BYTES" diff --git a/apps/obsidian-livesync/couchdb-service.yaml b/apps/obsidian-livesync/couchdb-service.yaml new file mode 100644 index 0000000..3ec3e1f --- /dev/null +++ b/apps/obsidian-livesync/couchdb-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: couchdb + namespace: obsidian +spec: + selector: + app: couchdb + ports: + - name: http + port: 5984 + targetPort: 5984 diff --git a/apps/obsidian-livesync/kustomization.yaml b/apps/obsidian-livesync/kustomization.yaml new file mode 100644 index 0000000..e809388 --- /dev/null +++ b/apps/obsidian-livesync/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - namespace.yaml + - couchdb-configmap.yaml + - couchdb-pvc.yaml + - couchdb-deployment.yaml + - couchdb-service.yaml + - couchdb-ingress.yaml diff --git a/apps/obsidian-livesync/namespace.yaml b/apps/obsidian-livesync/namespace.yaml new file mode 100644 index 0000000..23f7db7 --- /dev/null +++ b/apps/obsidian-livesync/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: obsidian diff --git a/argocd/obsidian-livesync.yaml b/argocd/obsidian-livesync.yaml new file mode 100644 index 0000000..a3cff71 --- /dev/null +++ b/argocd/obsidian-livesync.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: obsidian-livesync + namespace: argocd +spec: + project: default + source: + repoURL: https://git.aleshym.co/funman300/k3s-homelab.git + targetRevision: main + path: apps/obsidian-livesync + destination: + server: https://kubernetes.default.svc + namespace: obsidian + ignoreDifferences: + - group: "" + kind: Secret + name: couchdb-secret + namespace: obsidian + jsonPointers: + - /data + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true