CertGrid CertGrid
Hands-on Lab·Podman

Podman Prune Commands and Data Loss

`container prune` and `image prune` reclaim space and lose nothing. `volume prune` removed two volumes here, one of them a Compose volume with data in it - and it is the only one of the three that is irreversible.

Security and Operations Guide 45 of 47 Intermediate

Written against the versions above. Podman follows the distribution here rather than a vendor repository, so the version you get is the one Ubuntu shipped. The commands are stable across 5.x.

Every command on this page ran on podman01.
Server NameIP AddressOSRolesCPURAMHDD
PODMAN01192.168.0.21Ubuntu 26.04 LTSPrimary Container Host2 Core4 GB50 GB

Before you start

  1. Ask what is actually using it

    podman system df is the honest accounting:

    TYPE           TOTAL  ACTIVE  SIZE      RECLAIMABLE
    Images         28     0       439.3MB   439.3MB (100%)
    Containers     0      0       0B        0B (0%)
    Local Volumes  2      0       1.393kB   1.393kB (100%)

    ACTIVE is the column to read. Images 28, ACTIVE 0 means twenty-eight images and not one is referenced by a container - so all 439 MB is reclaimable. That is a working host after a day of experiments, and it is how disk disappears without anything looking wrong.

    podman system df -v breaks it down per image, container and volume, which is what you want before deciding rather than after.

    bash Example session
    podman system dfTYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLEImages         30          0           439.3MB     439.3MB (100%)Containers     0           0           0B          0B (0%)Local Volumes  1           0           1.393kB     1.393kB (100%)podman system df -v | head -20Images space usage: REPOSITORY                     TAG         IMAGE ID      CREATED     SIZE        SHARED SIZE  UNIQUE SIZE  CONTAINERSdocker.io/library/nginx        alpine      7bc5ba2f958a  2 days      64.2MB      8.698MB      55.5MB       0docker.io/library/alpine       latest      d529dd0c6e55  2 months    17.41MB     8.698MB      8.71MB       0docker.io/library/redis        alpine      00c30ddf0ef8  3 days      119.4MB     8.694MB      110.8MB      0docker.io/library/hello-world  latest      e2ac70e7319a  5 months    25.46kB     0B           25.46kB      0docker.io/library/busybox      latest      c6348fa86ba0  3 months    4.691MB     0B           4.691MB      0192.168.0.23:5000/verified     1           b66e0ce64844  2 months    8.59MB      8.575MB      14.09kB      0localhost/app-a                1           b66e0ce64844  2 months    8.59MB      8.575MB      14.09kB      0docker.io/library/alpine       3.22        b66e0ce64844  2 months    8.59MB      8.575MB      14.09kB      0<none>                         <none>      6180d06f43b1  2 hours     13.79MB     13.79MB      3.25kB       0<none>                         <none>      1f4fdfd3f228  2 hours     13.8MB      13.79MB      3.809kB      0<none>                         <none>      ab7f293673bf  2 hours     13.8MB      13.8MB       4.284kB      0localhost/app                  2           c154b5c3995c  2 hours     13.8MB      13.8MB       4.425kB      0localhost/app                  1           c154b5c3995c  2 hours     13.8MB      13.8MB       4.425kB      0<none>                         <none>      9779093186b3  2 hours     13.8MB      13.79MB      3.809kB      0<none>                         <none>      1582b6a9092a  2 hours     13.8MB      13.8MB       4.284kB      0localhost/app                  3           3add4ec8193b  2 hours     13.8MB      13.8MB       4.424kB      0localhost/manual               1           7128fd2a22d9  2 hours     9.53MB      8.575MB      954.5kB      0

    Expected resultA summary with a reclaimable percentage, then a per-object breakdown.

    Success conditionYou know how much of your disk containers are holding and how much is dead.

  2. The two safe prunes

    podman container prune -f removes stopped containers and prints their IDs. Nothing running is touched, and a stopped container is only a writable layer plus configuration - if it mattered it would be in a volume.

    podman image prune -f removes dangling images: ones with no tag and no container using them, which is what a rebuild leaves behind every time it moves a tag (guide 32).

    Both are safe to run on a schedule and neither can lose anything you would miss. If you only remember two commands from this guide, these are the two.

    Note what did not go: podman volume ls still lists stack_site and orphan. Neither prune touches volumes, which is exactly right and also why volumes are what silently accumulates.

    bash Example session
    podman container prune -ff6c5fabc1e606ee8c200e64ca720accc19767728e95a562a33f4e0e35c372bae33b3caa4971ca596bd82c069cccdd1c58b687b9d9ca0d730514963de0914231fpodman image prune -fb92795baa673585ea4a75c601e4d722e8198885f41845a7b3a9519a38f0d6d80f9f558b6dce5cbe45402746393b611d0b9ef1d1c2324072a78c1b16d157d2a5dpodman system dfTYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLEImages         30          0           439.3MB     439.3MB (100%)Containers     0           0           0B          0B (0%)Local Volumes  1           0           1.393kB     1.393kB (100%)podman volume lsDRIVER      VOLUME NAMElocal       stack_sitelocal       orphan

    Expected resultRemoved container and image IDs, a smaller system df, and both volumes still listed.

    Success conditionYou reclaimed space without removing anything that held data.

  3. The one to be careful with

    $ podman volume prune -f
    stack_site
    orphan
    $ podman volume ls
    (empty)

    Two volumes gone. orphan was created empty for this guide - but stack_site was the Compose volume from guide 70, which had nginx's document root in it. podman volume prune removes every volume no *running* container references, and a Compose stack that is down references nothing.

    That is the trap. A database whose container is stopped for maintenance looks exactly like an abandoned volume, and -f means no confirmation. There is no undo - guide 62 is the only thing standing between you and a rebuild.

    A safe order for regular cleanup:

    1. podman system df - look before touching anything
    2. podman container prune -f and podman image prune -f - safe, do these freely
    3. podman volume ls - read the list
    4. podman volume rm for the ones you recognise as dead

    And two commands worth knowing but not running casually: podman system prune -a --volumes -f does everything above at once including the volumes, and podman system reset destroys the entire store - images, containers, volumes and networks. Both have their place in a lab and neither belongs in a cron job.

    bash Example session
    podman volume prune -fstack_siteorphanpodman volume lsDRIVER      VOLUME NAMElocal       stack_sitelocal       orphanpodman system dfTYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLEImages         30          0           439.3MB     439.3MB (100%)Containers     0           0           0B          0B (0%)Local Volumes  1           0           1.393kB     1.393kB (100%)

    Expected resultTwo volume names removed and an empty volume list.

    Success conditionYou can name which of the three prunes is irreversible.

Troubleshooting

Official sources