Change CouchDB ingress hostname from communicore.mk-labs.cloud to communicore.local.mk-labs.cloud to align with External-DNS configuration. CouchDB is an internal service and should use the .local.mk-labs.cloud zone managed by Technitium DNS, not the public .mk-labs.cloud zone managed by Cloudflare. This ensures External-DNS will properly create the A record in the internal DNS server.
CouchDB Deployment
Application Name: couchdb
Thematic Name: communicore (DNS only)
Purpose: Obsidian sync backend for mk-labs
Deployment Method: Helm chart via ArgoCD
Overview
This deployment provides a CouchDB instance for Obsidian sync across multiple devices in the mk-labs homelab. It replaces the previous NFS-based shared vault with a proper sync solution.
Architecture
- Helm Chart: Apache CouchDB official chart (v4.6.3, CouchDB 3.5.1)
- Cluster: Single-node deployment (suitable for homelab)
- Storage: 20Gi persistent volume using nfs-emporium StorageClass
- Secrets: ExternalSecrets Operator pulling from 1Password
- TLS: cert-manager with letsencrypt-staging (switch to prod after validation)
- Ingress: nginx-ingress with external-dns
DNS Configuration
- Primary: communicore.mk-labs.cloud (thematic name)
- Managed automatically by external-dns via ingress annotations
Prerequisites
1Password Vault Setup
Create a new item in 1Password (mk-labs vault):
Item Name: couchdb
Type: Login
Fields:
admin-password: (generate strong password, 32 characters)
cookie-auth-secret: (generate random string, 32 characters)
Generate the secrets:
# Admin password
openssl rand -base64 32
# Cookie auth secret
openssl rand -base64 32
Store both values in the 1Password item before deploying.
Deployment
Initial Deployment
The deployment is managed entirely through GitOps:
- Commit and push the manifests to the homelab repository
- ArgoCD will automatically detect and sync the application
- Monitor the deployment:
# Watch ArgoCD sync status
kubectl get application -n argocd couchdb -w
# Watch pod creation
kubectl get pods -n couchdb -w
# Check deployment status
kubectl get all -n couchdb
Verification Steps
- Check ExternalSecret sync:
kubectl get externalsecret -n couchdb
kubectl get secret -n couchdb couchdb-admin
- Verify pod health:
kubectl get pods -n couchdb
kubectl logs -n couchdb -l app=couchdb
- Test internal access:
kubectl port-forward -n couchdb svc/couchdb-svc-couchdb 5984:5984
curl -u admin:PASSWORD http://localhost:5984/
# Should return: {"couchdb":"Welcome","version":"3.5.1"}
- Check certificate:
kubectl get certificate -n couchdb
kubectl describe certificate -n couchdb couchdb-tls
- Test external access:
# Once DNS propagates (may take 2-5 minutes)
curl -k https://communicore.mk-labs.cloud/
# Should show CouchDB welcome message
Switch to Production Certificates
After successful validation (24-48 hours stable), switch to production certificates:
cd ~/git/homelab/cluster/applications/couchdb
# Update values.yaml
sed -i 's/letsencrypt-staging/letsencrypt-prod/g' values.yaml
# Commit and push
git add values.yaml
git commit -m "feat(couchdb): switch to production TLS certificates"
git push
# Delete old staging certificate and secret to trigger reissuance
kubectl delete certificate -n couchdb couchdb-tls
kubectl delete secret -n couchdb couchdb-tls
# Verify new certificate
kubectl get certificate -n couchdb
Obsidian Configuration
Plugin Installation
On each device (workstation, desktop, carousel-of-progress):
- Install "Self-hosted LiveSync" plugin in Obsidian
- Enable the plugin
- Configure as follows:
Connection Settings
Remote Database URL: https://communicore.mk-labs.cloud
Remote Database: obsidian-sync
Username: admin
Password: (from 1Password couchdb item)
End-to-end Encryption: ✓ Enabled
Passphrase: (create a strong passphrase, store in 1Password)
Initial Sync (IMPORTANT)
ONLY ONE DEVICE should perform the initial upload:
-
On Workstation (primary device):
- Open Obsidian settings → Self-hosted LiveSync
- Click "Rebuild Everything"
- Wait for upload to complete (may take several minutes)
-
On Other Devices (desktop, carousel):
- Open Obsidian settings → Self-hosted LiveSync
- Click "Fetch from Remote"
- Wait for download to complete
Vault Locations
As documented in communicore-decisions.md:
- Workstation: ~/friday
- Desktop: ~/friday
- Carousel-of-progress: (to be determined by JARVIS)
Troubleshooting
Pod Not Starting
# Check events
kubectl describe pod -n couchdb <pod-name>
# Check logs
kubectl logs -n couchdb <pod-name>
# Common issues:
# - Secret not synced: check ExternalSecret status
# - PVC pending: verify storage class and NFS CSI driver
Certificate Issues
# Check certificate status
kubectl get certificate -n couchdb
kubectl describe certificate -n couchdb couchdb-tls
# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager
DNS Not Resolving
# Check external-dns logs
kubectl logs -n external-dns -l app.kubernetes.io/name=external-dns
# Verify ingress annotation
kubectl get ingress -n couchdb -o yaml | grep external-dns
Connection Refused in Obsidian
- Verify external access works from command line first
- Check that the database exists:
curl -u admin:PASSWORD https://communicore.mk-labs.cloud/_all_dbs
- If obsidian-sync database doesn't exist, create it:
curl -u admin:PASSWORD -X PUT https://communicore.mk-labs.cloud/obsidian-sync
Backup Strategy
CouchDB data is stored on nfs-emporium persistent volume. The NFS backend (Synology at 10.1.71.9) should handle snapshots.
Additional backup options:
- CouchDB replication to backup instance
- Scheduled exports to S3/Minio
- Git backup of vault using Obsidian Git plugin
Rollback
If deployment fails or causes issues:
# Delete the ArgoCD application
kubectl delete application -n argocd couchdb
# Delete the namespace (will cascade delete all resources)
kubectl delete namespace couchdb
# Remove from git
cd ~/git/homelab
git rm -rf cluster/applications/couchdb
git commit -m "rollback: remove couchdb deployment"
git push
Maintenance
Upgrade CouchDB Version
- Update chart version in application.yaml
- Update image tag in values.yaml
- Test in staging first
- Commit and push to trigger ArgoCD sync
Rotate Admin Password
- Update password in 1Password
- ExternalSecret will automatically sync within 1h (or trigger manually)
- Update Obsidian plugin configuration on all devices
References
Status
- Created: 2026-06-05
- Status: Ready for deployment
- Next Steps:
- Create 1Password item with credentials
- Commit and push to homelab repo
- Monitor ArgoCD sync
- Validate external access
- Configure Obsidian on all devices