CertGrid CertGrid
Configuration·Docker

Docker Engine Upgrade, Pinning and Removal

How to see which versions exist, upgrade safely, pin a version so an unrelated apt upgrade cannot move it, roll back, and remove Docker without destroying the volumes that hold your data.

Getting Started Guide 4 of 46 Beginner

Tested on the versions above. Version numbers change constantly. The uninstall step is deliberately NOT executed here - the commands are shown with their consequences described, because running them would destroy the host this guide was written on.

One Docker host is all this guide needs. Nothing here depends on a second machine, and the hardware above is modest on purpose - a 2 core, 4 GB VM runs everything in this path.
Server NameIP AddressOSRolesCPURAMHDD
DOCKER01192.168.0.21Ubuntu 26.04 LTSDocker Host2 Core4 GB50 GB

Before you start

  1. Know what you are running

    Two numbers matter and they can differ. The client is the docker CLI; the server is the daemon. A client newer than the server is normal and usually fine, and Compose is a separate plugin with its own version entirely.

    bash
    docker version --format "Client {{.Client.Version}} / Server {{.Server.Version}}"Client 29.7.2 / Server 29.7.2docker compose version --short5.4.0

    Expected resultClient and server versions, and the Compose plugin version separately.

    Success conditionYou can state all three. Compose is versioned independently, so it does not follow the Engine number.

  2. See which versions the repository actually offers

    apt-cache madison lists every version available from the configured repositories, newest first. This is the list you can upgrade or roll back to - anything not shown here is not installable without adding another source. Note the full version string: it is what you pass to apt when pinning.

    bash
    apt-cache madison docker-ce | head -3 docker-ce | 5:29.7.2-1~ubuntu.26.04~resolute | https://download.docker.com/linux/ubuntu resolute/stable amd64 Packages docker-ce | 5:29.7.1-1~ubuntu.26.04~resolute | https://download.docker.com/linux/ubuntu resolute/stable amd64 Packages docker-ce | 5:29.7.0-1~ubuntu.26.04~resolute | https://download.docker.com/linux/ubuntu resolute/stable amd64 Packages

    Expected resultSeveral versions, newest first, with the exact strings apt understands.

    Success conditionYou have the version list. apt-cache policy docker-ce shows which one is installed and which is the candidate for upgrade.

  3. Upgrade

    Upgrading is an ordinary package operation, but it restarts the daemon - which stops every running container unless live-restore is enabled. Plan it like any other service restart rather than running it casually mid-afternoon.

    bash
    # this restarts dockerd and will stop running containerssudo apt-get updatesudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin# upgrade all five packages together - mismatched CLI and daemon versions cause odd failures

    Expected resultThe five Docker packages upgraded together.

    Success conditiondocker version reports the new server version. Upgrade the whole set: a new CLI against an old daemon is a common source of confusing errors.

  4. Pin a version so nothing moves it

    apt-mark hold stops a package being upgraded by anything, including an unattended apt upgrade that was aiming at something else entirely. This is how you keep a validated Docker version stable on a production host between planned maintenance windows.

    bash
    sudo apt-mark hold docker-ce docker-ce-cli containerd.iodocker-ce set on hold.docker-ce-cli set on hold.containerd.io set on hold.apt-mark showholdcontainerd.iodocker-cedocker-ce-cli

    Expected resultThree packages held, and listed by showhold.

    Verify it worked

    bash Example session
    sudo apt-mark unhold docker-ce docker-ce-cli containerd.ioCanceled hold on docker-ce.apt-mark showhold# empty - nothing is pinned

    Success conditionThe holds are visible. Anyone wondering why Docker will not upgrade should check apt-mark showhold first - a forgotten hold is a common cause.

  5. Roll back to a previous version

    Rolling back is installing an older version explicitly, using the exact string from madison. Two cautions: apt will normally want to upgrade it again on the next run, so pin it immediately afterwards, and a downgrade across a major version can leave state the older daemon does not understand.

    bash
    # downgrading restarts the daemon, and across major versions may not be supportedsudo apt-get install -y --allow-downgrades docker-ce=5:29.7.1-1~ubuntu.26.04~resolute docker-ce-cli=5:29.7.1-1~ubuntu.26.04~resolutesudo apt-mark hold docker-ce docker-ce-cli# pin straight away or the next apt upgrade undoes the rollback

    Expected resultThe named version installed, then held.

    Success conditionRoll back and pin as one operation. Rolling back without pinning is a change that reverses itself.

  6. Uninstall without destroying your data

    This is the part that catches people. Removing the packages leaves /var/lib/docker alone, so images, containers and - critically - named volumes survive. Deleting that directory is a separate, deliberate act. If you are rebuilding a host and intend to keep the data, remove the packages and stop.

    bash
    # 1. remove the packages. /var/lib/docker is NOT touched - images,#    containers and named volumes all survive this.sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin# 2. ONLY if you also want the data gone. This deletes every image,#    container and VOLUME on the host, and nothing undoes it.sudo rm -rf /var/lib/docker /var/lib/containerd# back up any named volume you care about first - see the backup guide.

    Expected resultNo output is shown for either command, because neither was run. This guide was captured on a working Docker host and uninstalling it would have destroyed the environment every other guide in the path was verified on.

    Success conditionYou can separate the two acts. Purging packages is recoverable by reinstalling; removing /var/lib/docker is not recoverable at all. Back up first - see guide 13.

  7. Check what would be lost before removing anything

    Before an uninstall, list the volumes. Anything here is data that the second step would delete permanently, and a volume with no obvious owner is exactly the one somebody will miss.

    bash
    docker volume lsdocker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"# back up anything listed - see the volume backup guide in this path

    Expected resultA complete inventory of what removal would destroy.

    Success conditionYou have checked before acting. On a host with no volumes this is a formality; on one with a database volume it is the difference between a rebuild and an incident.

Troubleshooting

Official sources