A production-ready, secure homelab deployment using Kubernetes with proper secret management, health checks, and multi-environment support. Features Helm charts, Kustomize overlays, and comprehensive automation.
- No hardcoded passwords - All secrets properly managed
- External Secrets Operator for centralized secret management
- Separated databases - No more sidecar anti-patterns
- Health checks & resource limits on all services
- Multi-environment support (dev/staging/production)
- External Secrets Operator - Centralized secret management
- Kubernetes Secrets - No hardcoded passwords in Kubernetes manifests
- Automated secret generation - 32+ character random passwords
- Secret rotation capability - Update without service downtime
- SOPS + age (GitOps optional) - Encrypted secrets at rest in git (ArgoCD via KSOPS)
- K3s Kubernetes - Lightweight, production-ready Kubernetes
- Traefik Ingress - Ingress controller (routing + TLS termination via cert-manager)
- MinIO - S3-compatible object storage
- Local Path Provisioner - Dynamic persistent volume provisioning
- Separated Databases - StatefulSets instead of sidecars
- Prometheus + Grafana - Comprehensive metrics and visualization
- Uptime Kuma - Service uptime monitoring
- AlertManager - Alert management and notifications
- Loki (optional) - Log aggregation (Promtail is opt-in)
- Nextcloud - File synchronization and collaboration
- Vaultwarden - Password manager (Bitwarden-compatible)
- Jellyfin - Media server for streaming content
- Homepage - Application dashboard
- Authelia - Authentication and authorization
- Ollama (optional) - Local LLM runtime
- Open WebUI (optional) - Chat UI for Ollama
- Helm Charts - Templated, configurable deployments
- Kustomize Overlays - Environment-specific configurations
- ArgoCD - GitOps continuous delivery
- SOPS secrets (optional) - Store
Secretmanifests encrypted in git (seedocs/runbooks/gitops-secrets.md) - Ansible - System configuration management
- Automated backups - Scheduled data protection
- Health Checks - Liveness and readiness probes
- Kubernetes cluster (K3s recommended) and
kubectlconfigured - 4GB+ RAM, 50GB+ storage (more if you enable more services)
- Root or sudo access (for installing tools)
- Internet connection (image pulls and Helm charts)
git clone https://github.com/<you>/homelab.git
cd homelab
# Deploy (installs core controllers and creates any missing secrets)
./setup-v2.sh
# Validate deployment
./scripts/validate-setup.shIf you want ArgoCD-managed encrypted Secrets:
./scripts/sops-bootstrap.sh
./scripts/configure-argocd-ksops.shIf you use just, this repo includes a justfile:
just setup
just validate
just ci
just trivyThis repo includes a .pre-commit-config.yaml with fast local checks.
Install pre-commit (pick one):
pipx install pre-commitpython3 -m pip install --user pre-commit- Or: run
./scripts/install-dev-tools.shand use.tools/venv/bin/pre-commit
Enable the git hook:
pre-commit installOptional (recommended): also run the full repo gate before pushing (runs ./scripts/ci.sh and fails if required tools are missing):
pre-commit install --hook-type pre-pushRun on all files:
pre-commit run -aInstall pinned versions of the tools used by ./scripts/ci.sh into .tools/:
./scripts/install-dev-tools.sh
# or
just dev-toolsTool versions are pinned in tools/versions.env. Most repo scripts (including ./scripts/ci.sh and ./setup-v2.sh) will automatically use .tools/ if present.
# Examples
ENABLE_AI_SERVICES=true ./setup-v2.sh
ENABLE_DEV_SERVICES=true ./setup-v2.sh
ENABLE_GITOPS=true ./setup-v2.sh
INSTALL_VELERO=false INSTALL_METALLB=false ./setup-v2.sh
INSTALL_LOGGING=true INSTALL_PROMTAIL=true ./setup-v2.sh# First, setup your Synology NAS
./scripts/synology-setup.sh 192.168.1.100 admin ~/.ssh/id_rsa
# Then run the main setup
./setup.shhomelab/
βββ setup-v2.sh # π Enhanced secure setup script
βββ setup.sh # π« Legacy (insecure)
βββ config/
β βββ homelab-secure.yaml # π Secure configuration
β βββ homelab.yaml # Symlink to secure config
βββ helm/ # π Helm charts
β βββ nextcloud/ # Example Helm chart
βββ kustomize/ # π Environment overlays
β βββ base/ # Base configurations
β βββ overlays/ # Environment-specific
β βββ development/
β βββ staging/
β βββ production/
βββ extras/ # Optional (higher-risk) manifests not installed by default
βββ legacy/ # Archived legacy manifests (not used by setup-v2.sh)
βββ kubernetes/
β βββ secrets/ # π Secret management
β βββ storage/ # Storage configurations
β βββ ingress/ # Traefik and cert-manager
β βββ monitoring/ # Prometheus, Grafana, Uptime Kuma
β βββ services/ # All self-hosted services (updated)
β βββ gitops/ # ArgoCD configurations
βββ scripts/
β βββ generate-secrets.sh # π Secure secret generation
β βββ backup-secrets.sh # Encrypted secret backup (age)
β βββ restore-secrets.sh # Encrypted secret restore (age)
β βββ configure-wildcard-dns.sh # Pi-hole wildcard DNS for *.<domain>
β βββ validate-setup.sh # π Comprehensive validation
β βββ synology-setup.sh # Synology NAS configuration
βββ ansible/ # System configuration
βββ docs/ # Documentation
βββ SECURITY_NOTICE.md # π Security upgrade guide
- Secrets: generated into the
secretsnamespace; seedocs/credentials.md. - Helm values:
kubernetes/**/values.yamlandhelm/**/values.yaml. - Feature toggles: see
ENABLE_*andINSTALL_*at the top ofsetup-v2.sh. - Kustomize overlays:
./scripts/kustomize-apply.sh kustomize/overlays/production setup-v2.shreadsconfig/homelab.yamlfor defaults likehomelab.domain,homelab.timezone,homelab.email,ingress.cert_manager.cluster_issuer, andgitops.repo_url(env vars override).
After setup, access your services at:
| Service | URL | Description |
|---|---|---|
| Homepage | https://home. | Dashboard |
| Grafana | https://grafana. | Monitoring dashboard |
| Nextcloud | https://nextcloud. | File sync & sharing |
| Vaultwarden | https://vault. | Password manager |
| Jellyfin | https://jellyfin. | Media server |
| Uptime Kuma | https://uptime. | Uptime monitoring |
| Ollama (optional) | https://ai. | Local LLM API |
| Open WebUI (optional) | https://chat. | Chat UI for Ollama |
| ArgoCD (optional) | https://argocd. | GitOps dashboard |
If you enable Pi-hole, you can configure wildcard DNS so you do not need per-machine /etc/hosts entries:
./scripts/configure-wildcard-dns.sh
# Then point your clients (or router DHCP) at the Pi-hole DNS service IP:
kubectl -n pihole get svc pihole-dnsDisable the automatic DNS step during setup-v2.sh with:
CONFIGURE_WILDCARD_DNS=false ./setup-v2.sh- TLS certificates via cert-manager (local CA by default; optional Letβs Encrypt for public domains)
- Pod Security Admission (PSA) namespace labeling (
POD_SECURITY_MODE=audit|enforce; seedocs/runbooks/hardening.md) - Policy-as-code (optional) with Kyverno (
INSTALL_KYVERNO=true; seedocs/runbooks/hardening.md) - Firewall configuration with UFW
- Fail2ban for intrusion prevention
- SSH hardening with key-only authentication
- Regular security updates via unattended-upgrades
- Backup encryption and rotation
Automated backups run daily at 2 AM:
- Configuration files - Full cluster state
- Application data - Persistent volumes
- Database dumps - Complete data export
- Retention policy - 30 days default
Restore with:
/usr/local/bin/restore-homelab.sh /path/to/backupEncrypted secret backups (recommended before rebuilds):
./scripts/backup-secrets.sh
./scripts/restore-secrets.sh backups/secrets-secrets-<timestamp>.yaml.ageThe homelab supports easy addition of more services:
- Radarr, Sonarr, Lidarr (media automation)
- Overseerr (request management)
- Tautulli (Plex/Jellyfin analytics)
- GitLab CE (Git repository hosting)
- Jenkins (CI/CD)
- Code-server (VS Code in browser)
- Pi-hole (DNS filtering)
- WireGuard VPN
- Nginx Proxy Manager
Add services by placing Kubernetes manifests in kubernetes/services/<service-name>/
Services not accessible:
kubectl get pods --all-namespaces
kubectl get ingress --all-namespacesStorage issues:
kubectl get pv
kubectl get pvc --all-namespacesSSL certificate problems:
kubectl get certificates --all-namespaces
kubectl describe certificate <cert-name>Day-2 operations (backup/restore/upgrades): docs/runbooks/README.md
All setup logs are saved to setup.log
Service logs:
kubectl logs -f deployment/<service-name> -n <namespace>- Fork the repository
- Create a feature branch
- Add your service/improvement
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE for details
- K3s - Lightweight Kubernetes
- Traefik - Cloud Native Networking Stack
- Helm - Package Manager for Kubernetes
- All the amazing open-source projects that make this possible
β Star this repo if you found it helpful! β