Date: 2026-01-22 Reviewed: Official Cozystack docs, GitOps examples, API references
Reference: https://cozystack.io/docs/applications/external/
Cozystack supports custom applications via FluxCD GitRepository + HelmRelease pattern:
Process:
- Create package repository with structure:
./packages/core- Platform configuration./packages/system- System Helm charts./packages/apps- User-installable apps
- Register GitRepository pointing to your fork
- Deploy HelmRelease referencing the package path
- Applications appear in Cozystack catalog
Your arr-stack fits this model perfectly.
Reference: https://github.com/aenix-io/cozystack-gitops-example
Pattern:
- FluxCD polls repository every 1-5 minutes
- Kustomization resources target cluster-specific paths
- Multi-tenant namespaces (tenant-root, tenant-example)
- HelmReleases reference GitRepository sources
- Secrets support for private repositories
Application:
- Your arr-stack should live in
packages/apps/arr-stack/ - Deploy to
tenant-medianamespace - FluxCD handles reconciliation automatically
Reference: https://cozystack.io/docs/applications/
Storage Options:
- Linstor (linstor-r1): Replicated block storage for databases/config
- NFS: Shared filesystem for media libraries
- SeaweedFS: S3-compatible object storage (planned for your setup)
Ingress:
- Automated via
ingress.main.enabled: true - TLS certificates via cert-manager (Let's Encrypt)
- Supports multiple ingress classes (nginx, traefik)
Your Configuration:
- Linstor for Sonarr/Radarr/Prowlarr config (1Gi each)
- Shared PVC (media-pvc) for media library
- Ingress with auto-TLS on *.cozy.homi.zone
Reference: https://cozystack.io/docs/getting-started/deploy-app/
Two Approaches:
A. Dashboard (Quickest):
- Navigate to Catalog
- Search for application
- Click Deploy
- Configure parameters
- Monitor in Applications tab
B. kubectl (GitOps-friendly):
- Define HelmRelease YAML
- Apply with
kubectl apply -f - FluxCD reconciles automatically
- Check status:
kubectl get helmrelease -A
Recommendation: Use kubectl approach for arr-stack (infrastructure as code).
Pattern:
- Namespaces prefixed with
tenant-* - Resources isolated by RBAC
- Shared resources (ingress, storage) in system namespaces
Your Setup:
- Create
tenant-medianamespace - Deploy arr-stack here
- PVC lives in same namespace for isolation
Advantages:
- Infrastructure as code
- Version-controlled configuration
- Automatic reconciliation
- Rollback via git revert
- Team collaboration friendly
Steps:
- Follow
gitops_plan.mdstep-by-step - Commit arr-stack package
- Push to fork
- Apply FluxCD manifests
- Verify deployment
Timeline: 30 minutes
Advantages:
- Fastest to test
- No git workflow needed
- Good for experimentation
Steps:
- Package arr-stack as tarball
- Upload via dashboard
- Configure values in UI
- Deploy
Timeline: 15 minutes
Limitation: Not suitable for production, no version control
Platform patch (Universal Login removal) cannot be pushed to GHCR due to missing write:packages scope.
After reviewing documentation:
- Custom platform patches not required for arr-stack deployment
- Cozystack supports external applications without forking platform
- Dashboard customization nice-to-have, not critical path
Rationale:
- Arr stack works with standard Cozystack
- Focus on application delivery first
- Revisit platform customization later if needed
- Reduces complexity and unblocks deployment
If Platform Patch Required Later:
# Generate new GitHub token with write:packages
# https://github.com/settings/tokens/new
# Authenticate Docker
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# Build and push
cd ~/code/cozy-stack
make imageConfiguration:
- Config volumes: Linstor (replicated, durable)
- Media library: Shared PVC (ReadWriteMany)
Pros:
- Simple to implement
- Works with existing cluster
- No additional services needed
Cons:
- Media PVC not distributed (single-node bottleneck)
- No S3 API for future integrations
Reference: Your PROJECT.md mentions SeaweedFS
Benefits:
- Distributed object storage
- S3-compatible API
- FUSE mount for POSIX access
- Scales across nodes
Implementation Path:
- Deploy arr-stack with Linstor first (validate workflow)
- Deploy SeaweedFS as Cozystack managed app later
- Migrate media PVC to SeaweedFS volume
- Update arr-stack values to use new mount
Timeline: Phase 2 (after arr-stack working)
Current Setup: *.cozy.homi.zone
Requirements for Arr Stack:
- sonarr.cozy.homi.zone
- radarr.cozy.homi.zone
- prowlarr.cozy.homi.zone
Verification:
# Check ingress got IP
kubectl get ingress -n tenant-media
# Test DNS resolution
dig sonarr.cozy.homi.zoneTLS Automation:
- cert-manager handles Let's Encrypt
- Ingress annotation:
cert-manager.io/cluster-issuer: letsencrypt-prod - Certificates auto-renewed
Database External Access:
"External database access introduces security risks and should be avoided"
Application: Your arr-stack uses cluster-internal networking only (good).
Ingress Security:
- Enable authentication via Keycloak integration
- Or use Tailscale ingress for private access
Recommendation: Start with public ingress (HTTPS + Let's Encrypt), add auth later if needed.
Arr Stack Secrets:
- API keys (for Sonarr/Radarr integration)
- Indexer credentials (Prowlarr)
Storage:
- Create Kubernetes Secrets
- Mount into pods
- Bitwarden for backup/rotation
Example:
kubectl create secret generic arr-secrets \
-n tenant-media \
--from-literal=sonarr-api-key=xxx \
--from-literal=radarr-api-key=yyy- ✅ Review Cozystack documentation (DONE)
- ✅ Create GitOps plan (DONE)
- ✅ Create Terraform strategy (DONE)
- Next: Commit arr-stack package
- Next: Apply FluxCD manifests
- Deploy arr-stack via GitOps
- Configure Sonarr/Radarr/Prowlarr
- Test download workflow
- Document access procedures
- Deploy SeaweedFS
- Migrate media storage
- Add qBittorrent to arr-stack
- Implement backups
- Implement Terraform IaC
- Add Immich (photo management)
- Deploy Jellyfin with GPU
- Platform customization (if still needed)
| Topic | URL |
|---|---|
| Main Docs | https://cozystack.io/docs/ |
| Getting Started | https://cozystack.io/docs/getting-started/ |
| External Apps | https://cozystack.io/docs/applications/external/ |
| GitOps Example | https://github.com/aenix-io/cozystack-gitops-example |
| Application Guide | https://cozystack.io/docs/applications/ |
| Deploy App Tutorial | https://cozystack.io/docs/getting-started/deploy-app/ |
| Platform Stack | https://cozystack.io/docs/guides/platform-stack/ |
Q: How to add custom applications to Cozystack? A: Use FluxCD GitRepository + HelmRelease pattern (documented above).
Q: Do I need to modify Cozystack platform source? A: No, external applications supported natively since v0.37.0.
Q: What storage should I use for media? A: Start with shared PVC, migrate to SeaweedFS later for scale.
Q: How to handle secrets? A: Kubernetes Secrets, optionally integrated with Vault/Bitwarden.
Q: Should I use dashboard or GitOps? A: GitOps for production (version control, rollback support).
Your cluster is production-ready. The arr-stack package is correctly structured. The platform patch is non-blocking. Follow gitops_plan.md to deploy, starting with committing the arr-stack package.
Estimated time to working Arr stack: 1 hour Blocker status: None (Docker push issue bypassed via GitOps approach)