Storage
This page describes how Canasta handles persistent storage: what state it keeps, how each orchestrator (Docker Compose, Kubernetes) provisions that state, when shared (RWM-capable) storage is required, and which storage backends Canasta supports out of the box.
What Canasta stores
A running Canasta instance has six categories of persistent state:
| State | Lives on |
|---|---|
Wiki content directories — extensions, skins, images, public_assets |
PVCs (K8s) or instance-directory bind mounts (Compose) |
| Wiki database (when bundled) | A db-data PVC managed by a StatefulSet (K8s), or the mysql-data-volume Docker volume (Compose). Skipped entirely when USE_EXTERNAL_DB=true — see Help:External database.
|
| Search index (when Elasticsearch enabled) | An es-data PVC managed by a StatefulSet (K8s), or the elasticsearch Docker volume (Compose).
|
| TLS state (Compose only) | The caddy-data Docker volume holds Caddy's Let's Encrypt account and issued certificates. K8s instances delegate TLS to cert-manager + ingress; Caddy runs with no persistent state and has no equivalent PVC.
|
| Logs (when observability stack enabled) | Shared volumes between web/db/caddy and the log-shipping containers. See Help:Observability for the topology. |
Instance config — .env, values.yaml, per-wiki settings |
The instance directory at ~/canasta/<id>/ on the operator workstation (or wherever --path points). Not on the cluster.
|
The instance config is on the operator host, not the cluster. If the operator host fails, the cluster keeps running but you lose the ability to issue further canasta commands until the directory is restored. See Help:GitOps for keeping it in version control, or back it up alongside the wiki content.
Storage on Compose
Compose instances use two storage mechanisms:
- Bind mounts from the instance directory:
./extensions,./skins,./images,./public_assets,./configare mounted into the web container at the equivalent/var/www/mediawiki/paths. Editing files in the instance directory directly modifies what the running container sees. - Named Docker volumes for the bundled services:
mysql-data-volume,caddy-data,elasticsearch, plus log-shipping volumes when the observability profile is active. These are managed by Docker Engine — typically under/var/lib/docker/volumes/on Linux hosts.
Compose has no concept of a StorageClass; whatever the host filesystem offers is what you get. Backups (see Help:Backup and restore) capture both the bind-mounted directories and the named volume contents into a single Restic snapshot.
Storage on Kubernetes
Kubernetes instances use PersistentVolumeClaims for everything stateful. The cluster's CSI drivers and StorageClasses control the actual provisioning.
Which StorageClass gets used
Canasta picks the StorageClass for a new instance in this order, first match wins:
--storage-class <name>oncanasta create.- The
defaultStorageClasssetting in the controller's registry (~/Library/Application Support/canasta/conf.jsonon macOS,~/.config/canasta/conf.jsonelsewhere). Set this once per controller and skip the flag. - The cluster's default StorageClass (whichever one is annotated
storageclass.kubernetes.io/is-default-class: "true").
The registry value is sticky across instances. If the same controller has been used against multiple clusters with different defaults (e.g., k3s's local-path and EKS's gp2), the registry locks in whichever was set last; it does not re-read the cluster's default per-instance. Pass --storage-class explicitly when switching clusters, or update the registry once with the new value.
To inspect what's available on the current cluster:
canasta storage list
ReadWriteOnce vs ReadWriteMany
The four content PVCs default to ReadWriteOnce (RWO). RWO PVCs can mount on only one node at a time, which is fine for single-replica web on a single-node cluster, or for multi-replica web where Kubernetes can schedule all replicas onto the same node.
For multi-node multi-replica web — where pods on different nodes need to read and write the same content — pass --access-mode ReadWriteMany at canasta create time. RWM declares the PVCs RWM-capable and matches them to a StorageClass whose CSI driver supports concurrent multi-node mounts. Common RWM backends:
- Network filesystems exported from a shared host or appliance (NFS, SMB, CephFS).
- Managed RWM services from cloud providers (e.g., AWS EFS, Azure Files, Google Cloud Filestore).
- Vendor CSI drivers that explicitly advertise RWM (NetApp Trident, Portworx, Longhorn-with-RWM-enabled).
The single-node defaults — k3s's local-path, EKS's gp2 — are RWO-only. Asking for RWM access mode against an RWO-only StorageClass produces PVCs stuck in Pending. See Help:Multi-node Kubernetes for the topology context and worked examples.
Turnkey storage helpers
For two common shared-storage backends, Canasta installs the CSI driver and registers the StorageClass in one command:
| Backend | Command |
|---|---|
| NFS (server on any reachable host, including a Canasta-managed node) | canasta storage setup nfs --host <node> --share /srv/nfs/canasta
|
| AWS EFS (managed NFS, pre-provisioned filesystem) | canasta storage setup efs --host <node> --filesystem-id fs-...
|
Both commands target a --host that has a working kubectl against the cluster — typically the K8s control-plane node. canasta storage setup nfs --install-server additionally installs the NFS server package on that host.
For other RWM backends (CephFS, Portworx, vendor CSI drivers), follow your CSI driver's standard install instructions and register the StorageClass via kubectl apply -f; Canasta only needs the StorageClass to exist when canasta create --storage-class <name> runs.
Object storage
Two distinct object-storage roles are worth distinguishing:
- Backups use object storage as the Restic repository — the actual destination of snapshot data. This is fully supported via the
RESTIC_REPOSITORYenvironment variable. See Help:Backup and restore for the supported backends (S3, Azure Blob, Backblaze B2, GCS, OpenStack Swift, etc.) and configuration. - Wiki uploads as object storage — having MediaWiki write user-uploaded files directly to S3 instead of the
imagesPVC — is not currently supported by the bundled chart. Uploads go to theimagesPVC and are reachable via the wiki's normal URL paths. Operators who want object-storage-backed uploads can configure MediaWiki's$wgFileBackendsmanually in their settings, but this is operator-managed configuration outside Canasta's supported envelope.
Sizing
The default per-PVC size in the chart (1 GiB for each of extensions, skins, images, public_assets) is sized for a small bootstrap. Real wikis with media uploads, third-party extensions, or large skins will need to grow these — typically images grows fastest. Edit the per-instance values.yaml on the target host (persistence.images.size, etc.) and run canasta restart to apply. Some CSI drivers (most cloud-managed ones, and NFS) support online expansion; check your provider's docs.
See also
- Help:Multi-node Kubernetes — when shared (RWM) storage becomes a hard requirement, and the topology context.
- Help:Backup and restore — Restic-based backup destinations and configuration.
- Help:External database — moving the wiki database off the bundled
dbStatefulSet to a managed RDS / Cloud SQL / Galera cluster. - Help:Observability — log-shipping volume topology.
- Help:User journeys/Canasta multi-node on AWS EC2 with k3s — worked example: NFS-backed shared storage for multi-replica web on self-managed k3s.
- Help:User journeys/Canasta on AWS EKS with RDS — worked example: EBS-backed PVCs (single-replica web), RDS for the database.