PodWarden
Guides

Storage

Persistent volumes, NFS mounts, S3 connections, and storage management

Overview

PodWarden supports persistent storage for workloads that need data to survive pod restarts — databases, media servers, ML models, object storage, and more. Storage is configured through volume mounts on stacks and optional storage connections for shared backends.

Volume Types

Each volume mount has a type that determines how storage is provisioned:

TypePersistenceUse Case
emptyDirEphemeral (lost on restart)Scratch space, temp files, caches
hostPathTied to specific hostDevelopment, single-node data
configMapRead-only configConfiguration files (see also Config Files for managed config slots)
secretRead-only secretsTLS certs, credentials
pvcPersistent (survives restarts)Databases, application data
nfsNetwork-attachedShared data across workloads
s3Object storage (env injection)Media, backups, ML datasets

emptyDir

Temporary storage that exists for the lifetime of the pod. Fast and simple, but data is lost when the pod restarts.

When to use: Temp files, build caches, inter-container shared directories.

hostPath

Mounts a directory from the host machine directly into the container. Data persists on that specific host but is not portable across servers.

When to use: Development environments, single-node deployments where simplicity matters.

Fields: host_path (directory on host), host_path_type (DirectoryOrCreate, Directory, File, etc.)

PVC (Persistent Volume Claim)

Block storage provisioned by a StorageClass. PVCs survive pod restarts and redeployments. This is the recommended approach for stateful workloads.

When to use: Databases (PostgreSQL, MySQL, Redis), application data that must persist.

Fields:

FieldDescription
sizeStorage size (e.g. 10Gi, 100Gi)
access_modeReadWriteOnce, ReadOnlyMany, or ReadWriteMany
storage_classStorageClass name (optional, uses cluster default)
retain_on_undeployKeep PVC data when workload is undeployed (default: true)

StorageClass requirement: Your cluster needs at least one StorageClass provisioner (e.g. Longhorn, OpenEBS, local-path). Check your cluster's StorageClasses in the cluster detail page — PodWarden shows available classes and warns when none exist.

PVC lifecycle:

  1. On deploy: PodWarden creates a PVC named {deployment}-{volume-name} before applying the deployment
  2. On undeploy with retain_on_undeploy: true: PVC and data are kept (default)
  3. On undeploy with retain_on_undeploy: false: PVC is deleted along with the deployment

NFS

Mounts a remote NFS share directly into the container. Useful for shared storage accessible from multiple workloads or servers.

When to use: Shared media libraries, datasets accessed by multiple workloads, existing NFS infrastructure.

Two ways to configure:

  1. Direct: Specify server (IP or hostname) and path directly on the volume mount
  2. Via storage connection: Reference a named NFS storage connection — PodWarden resolves the server and path at deploy time

Fields: server, path, read_only, or storage_connection (name of a registered NFS connection)

S3 (Credential Injection)

References an S3 storage connection and injects its credentials as environment variables into the container. The workload application uses these env vars to connect to S3 directly.

When to use: Object storage for media files, backups, ML model artifacts.

Injected environment variables:

VariableSource
S3_ENDPOINTConnection config
S3_BUCKETConnection config
S3_REGIONConnection config
S3_ACCESS_KEYApp secret {connection_name}_access_key
S3_SECRET_KEYApp secret {connection_name}_secret_key

Storage Connections

Storage connections are global named backends that you register once and reference from any workload. Navigate to Storage in the sidebar to manage them.

NFS Connection

Register an NFS server so workloads can reference it by name instead of hardcoding IP addresses.

Config fields:

  • Server — NFS server hostname or IP address
  • Base path — Export path on the server (e.g. /exports/data)

Testing: The test button runs connectivity checks:

  1. TCP port 2049 reachability
  2. RPC portmapper response
  3. NFS export listing
  4. If managed hosts are available: SSH-based mount + 100 MB read/write speed test

S3 Connection

Register an S3-compatible endpoint (AWS S3, MinIO, SeaweedFS, RustFS, etc.) with credentials stored securely in PodWarden's encrypted secrets.

Config fields:

  • Endpoint — S3 endpoint URL (e.g. https://s3.amazonaws.com)
  • Bucket — Bucket name
  • Region — AWS region or empty for non-AWS
  • Access Key — Stored as encrypted app secret
  • Secret Key — Stored as encrypted app secret

Testing: The test button verifies:

  1. Endpoint reachability
  2. Authentication (SigV4-signed request)
  3. Upload + download speed test (100 MB)

NFS StorageClass Provisioning

PodWarden can deploy an NFS provisioner to a cluster, creating a StorageClass that auto-provisions PVCs on your NFS server. This is useful when you want workloads to use NFS-backed persistent volumes without manually configuring each volume mount as type nfs.

Via MCP:

create_nfs_storage_class(
    connection_id="...",         # UUID of an NFS storage connection
    cluster_id="...",            # target cluster
    storage_class_name="nfs",    # name for the StorageClass
    reclaim_policy="Retain"      # "Retain" or "Delete"
)

What this deploys:

  1. A nfs-provisioner namespace
  2. RBAC (ServiceAccount, ClusterRole, ClusterRoleBinding, Role, RoleBinding)
  3. An nfs-subdir-external-provisioner deployment that watches for PVC requests
  4. A StorageClass named nfs (or your chosen name)

Once created, any workload can use storage_class: "nfs" in its volume mounts, and the provisioner will automatically create subdirectories on the NFS server for each PVC.

NFS StorageClasses only work on clusters where nodes can reach the NFS server. For mixed LAN/mesh clusters, this typically means only nodes on the same LAN (e.g. 10.10.x.x network) can use NFS volumes.

Adding Volume Mounts to a Workload

  1. Go to Apps & Stacks and create or edit a definition
  2. Scroll to the Volume Mounts section
  3. Click Add Volume Mount
  4. Select the volume type and fill in the fields:
    • Name — Unique name for this volume (used in PVC naming)
    • Mount Path — Path inside the container (e.g. /data, /var/lib/postgresql/data)
    • Read Only — Mount as read-only (optional)
    • Type-specific fields — Size, StorageClass, NFS server, etc.
  5. Save the stack

When you deploy the workload, PodWarden automatically:

  • Creates PVCs before applying the deployment
  • Resolves storage connection references to actual server addresses
  • Injects S3 credentials as environment variables
  • Generates the correct Kubernetes volume and volumeMount specs

StorageClass Discovery

Each cluster's detail page shows available StorageClasses — the provisioners that create persistent volumes on demand. If your cluster has no StorageClasses, PodWarden shows a warning with guidance.

Common StorageClass provisioners:

  • Longhorn — Distributed block storage, replication, snapshots
  • OpenEBS — Container-attached storage with multiple engines
  • local-path — Simple local storage (ships with K3s by default)

Examples

PostgreSQL with PVC

Volume Mount:
  Name: pgdata
  Mount Path: /var/lib/postgresql/data
  Type: PVC
  Size: 50Gi
  Access Mode: ReadWriteOnce
  Retain on Undeploy: true

Jellyfin with NFS Media Library

Volume Mount:
  Name: media
  Mount Path: /media
  Type: NFS (via storage connection)
  Storage Connection: nas-media
  Read Only: true

ML Training with S3 Dataset

Volume Mount:
  Name: s3-datasets
  Type: S3
  Storage Connection: training-bucket

Container receives:
  S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
  S3_BUCKET=ml-datasets
  S3_REGION=us-east-1
  S3_ACCESS_KEY=AKIA...
  S3_SECRET_KEY=wJal...
Storage