I now use the default overlay driver on Btrfs and ZFS filesystems as I’ve found it to just work. Unless you have specific reasons for using the underlying filesystem driver, you might want to consider sticking with the default overlay driver.

Podman has storage backends for both Btrfs and ZFS. Using these backends allows Podman to take full advantage of the underlying CoW filesystem. This is a quick guide on enabling these storage drivers.

Enable the Btrfs and ZFS Storage Drivers for Podman

Below are the necessary steps to enable the Btrfs and ZFS storage drivers. It is assumed that you are familiar with Linux, Podman, and the command-line and that you’re running on a Linux system with Podman installed. Instructions are provided for both rootless and root configurations.

  1. Reset Podman’s storage with podman-system-reset(1) before changing the storage driver.

    The storage driver may only be set before initializing Podman. It can’t be changed on-the-fly. This requires removing all storage before switching the storage driver. This must be done separately for a user’s rootless configuration and the root configuration.

    This will delete all existing containers and images.

    rootless
    podman system reset
    root
    sudo podman system reset
  2. Set the storage backend in containers-storage.conf(5). The system configuration file is /etc/containers/storage.conf. The driver set here applies to containers run as root. New rootless configurations will default to it if it is supported. Only certain drivers are supported for rootless containers. If the system configuration is set to use a driver not supported in rootless configurations, then the driver will default to the "overlay" driver if available, otherwise it will use the "vfs" driver. A user’s rootless configuration in ~/.config/containers/storage.conf supersedes the driver in the system configuration.[1] While the Btrfs driver is supported in rootless configurations, the ZFS driver is not, at this moment.

    rootless

    When dealing with user configuration, you’ll need to create the ~/.config/containers/ directory first.

    mkdir -p ~/.config/containers
    root
    Btrfs
    /etc/containers/storage.conf
    [storage]
    
    driver = "btrfs"

    Setting the Btrfs driver here sets it as the default for new rootless configurations.

    ZFS
    /etc/containers/storage.conf
    [storage]
    
    driver = "zfs"

    Setting the ZFS driver here sets it for root only.

    Btrfs
    ~/.config/containers/storage.conf
    [storage]
    
    driver = "btrfs"
    ZFS

    This might work, but I haven’t tested the ZFS driver for rootless containers. Mileage may vary.

    ~/.config/containers/storage.conf
    [storage]
    
    driver = "zfs"

From here, you can configure various driver-specific options for either Btrfs or ZFS as defined in containers-storage.conf(5). The Btrfs driver doesn’t have a mountopt key for controlling mount options. This owes to the fact that Podman creates Btrfs subvolumes in a nested layout leading to subvolumes inheriting the mount options of their parent subvolumes. Since my user’s home directory is its own top-level subvolume mounted in fstab(5), the mount options used for it are inherited by my rootless containers. These options include autodefrag, compress=zstd, and noatime, all of which I would recommend for your running containers. You can even go so far as to create dedicated, top-level subvolumes for your root and rootless containers to fine-tune the mount options. To learn more about Btrfs mount options and layouts, see Btrfs Mount Options and Btrfs Layout.

To really capitalize on using Btrfs and ZFS for your containers, you’ll want to take advantage of their snapshot and incremental backup capabilities. Containers, images, and named volumes are all stored in ~/.local/share/containers/storage for rootless runtimes and /var/lib/containers/storage/ for root. For Btrfs, these directories contain the subdirectory btrfs/subvolumes which contains individual subvolumes for each container. I assume that the ZFS driver uses a similar procedure for creating individual datasets for each container. Snapshots can be taken of these containers and they can be backed up incrementally.

You probably use named volumes for persisting any important data in your containers such as databases and configuration. These named volumes are located in the volumes subdirectory. You might make this directory - or any of its subdirectories for that matter - a subvolume or dataset and snapshot it and back it up. For Btrfs users, the blog posts Btrfs Snapshot Management With Snapper and Backup Snapper Snapshots With snap-sync can be applied to create automated snapshots and backups of these directories.

Conclusion

You have combined the ultimate powers of Podman and Btrfs or ZFS. World domination is that much closer. Enjoy!


1. To be accurate, the user’s config file is located at $XDG_CONFIG_HOME/containers/storage.conf when XDG_CONFIG_HOME is set but otherwise resides at the aforementioned location.