Deploy and Manage Applications
This guide explains how to deploy and manage applications on our Kubernetes cluster using GitOps with ArgoCD.
Quick Start
Applications live in /k8s/applications/
organized by function:
ai/
- AI tools like OpenWebUI, KaraKeepautomation/
- Home automation (Frigate, MQTT)media/
- Media servers and tools (Jellyfin, *arr stack)network/
- Network apps (AdGuard Home, Omada)tools/
- Utility apps (IT-Tools, Whoami, Unrar)web/
- Web applications (BabyBuddy, Pedrobot)external/
- Services outside Kubernetes but referenced internally
How Application Deployment Works
We use ArgoCD ApplicationSet to automatically deploy apps from Git. Here's the process:
- Add your app files to a category folder (e.g.,
/k8s/applications/media/myapp/
) - For most applications, ensure they are discoverable by the main ApplicationSet in
/k8s/applications/application-set.yaml
(which scans subdirectories). - For applications in the
external/
category (like HAOS, Proxmox, TrueNAS), these are managed by a separate ApplicationSet located at/k8s/applications/external/application-set.yaml
. This ApplicationSet specifically scans paths likek8s/apps/external/*
. - ArgoCD detects the change and deploys automatically.
Key Files
kustomization.yaml
- Groups apps in each categoryproject.yaml
- Sets ArgoCD permissions and controlsapplication-set.yaml
- Main deployment configuration (additional ApplicationSets may exist for specific categories likeexternal
)
Application Structure
Each app folder should contain:
myapp/
├── kustomization.yaml # App configuration
├── namespace.yaml # Kubernetes namespace
├── deployment.yaml # Container settings
├── service.yaml # Network exposure
├── pvc.yaml # Storage (if needed)
└── http-route.yaml # External access
Example: KaraKeep Configuration
Here's how KaraKeep (/k8s/applications/ai/karakeep/
) is structured:
-
Basic Setup
- Uses namespace:
karakeep
- Configures non-sensitive settings via ConfigMap
- Manages versions through Kustomize
- Uses namespace:
-
Security
- Runs as non-root
- Drops unnecessary privileges
- Uses default security profiles
-
Storage
- Uses Longhorn for app data via PersistentVolumeClaims (e.g.,
data-pvc
,meilisearch-pvc
), which use the default StorageClass (Longhorn). - While a shared NFS media store exists for other media applications, KaraKeep primarily uses its dedicated PVCs for its operational data.
- Uses Longhorn for app data via PersistentVolumeClaims (e.g.,
-
Network Access
- The primary web interface is exposed via a
LoadBalancer
service (e.g.,karakeep-web-svc
with IP10.25.150.230
). Internal components like Meilisearch or Chrome might useClusterIP
services. - External access through Gateway API
- Custom IPs via Cilium
- The primary web interface is exposed via a
-
Secrets
- Managed by ExternalSecrets
- Stored in Bitwarden
- Automatically synced to Kubernetes
Shared Resources
Media Storage
We use NFS for shared media files:
- Location:
172.20.20.103:/mnt/wd1/media_share
- Access: ReadWriteMany
- Retention: Persistent
- Used by: All media apps
Best Practices
- Use Kustomize for configuration
- Store secrets in Bitwarden
- Set resource limits
- Configure security contexts
- Use automated sync with ArgoCD
Need help? Check the application examples in /k8s/applications/
for reference implementations.