Storage¶
Charmarr Storage¶
The Charmarr Storage charm (charmarr-storage-k8s) manages the shared storage in your Charmarr stack. All media apps mount the same storage volume, which enables hardlinks between download clients and media managers.
Why Shared Storage Matters¶
When qBittorrent finishes downloading a file, Radarr or Sonarr moves it to your media library. Without shared storage, this is a copy operation (slow, uses double disk space). With shared storage, it's a hardlink (instant, no extra space).
Hardlinks are also atomic, which lets Charmarr follow TRaSH Guides recommendations for instant media imports.
The storage charm creates the necessary Kubernetes storage resources (PV and PVC for hostpath/native-nfs, or just PVC for storage-class) that all apps mount at /data. This is what makes hardlinks possible.
Relations¶
| Connects To | Interface | What It Provides |
|---|---|---|
| Radarr/Sonarr | media-storage |
PVC name, mount path, UID/GID for file permissions |
| qBittorrent/SABnzbd | media-storage |
PVC name, mount path, UID/GID for file permissions |
| Plex | media-storage |
PVC name, mount path, UID/GID for file permissions |
The charm publishes PUID/PGID (user/group IDs) to all connected apps. This ensures every app writes files with the same ownership, which is required for hardlinks to work.
Backend Types¶
The charm supports three storage backends:
| Backend | Use Case |
|---|---|
| hostpath | Mount a directory from the host node. The charm creates a PV and PVC. Recommended for single-node clusters. |
| native-nfs | Connect directly to an NFS server. The charm creates a PV and PVC. Do not run on the same node as the NFS server (loopback causes deadlock). |
| storage-class | Use an existing Kubernetes StorageClass. Experimental. |
Lifecycle¶
sequenceDiagram
participant SC as Storage Charm
participant K8s as Kubernetes
participant Apps as Media Apps
SC->>SC: Read storage config
SC->>K8s: Create PV (hostpath/native-nfs only)
K8s-->>SC: PV ready
Note over SC: Waits if not ready
SC->>K8s: Create PVC
K8s-->>SC: PVC ready
Note over SC: Waits if not ready
SC->>K8s: Run permission check
K8s-->>SC: Permissions OK
Note over SC: Waits if check fails
Apps-->>SC: I need storage
SC-->>Apps: Here's PVC name, mount path, UID/GID
Note over Apps: Apps mount the shared PVC
Configuration¶
The charm requires:
- Backend type (storage-class, native-nfs, or hostpath)
- Backend-specific config (storage class name, NFS server/path, or host path)
- PUID/PGID for file ownership (defaults to 1000:1000)
Size configuration
For hostpath and native-nfs, the size config is purely informational. Actual capacity depends on the space available in the path itself. For storage-class, this depends entirely on the CSI driver and needs to be configured carefully at your discretion to prevent data loss.
Cleanup on remove
The cleanup-on-remove config deletes the PVC when the charm is removed. For hostpath and native-nfs, true is safely recommended. For storage-class, configure carefully at your discretion as behavior depends on the CSI driver's reclaim policy.
See charmarr-storage-k8s on Charmhub for all options.