Yes. You can upgrade a Docker CE host from Ubuntu 24.04 to 26.04.1 in place. Fully update 24.04, snapshot the disk, run sudo do-release-upgrade without -d, then point Docker’s apt source at resolute, re-enable it and install the resolute builds. On our 5 Oct 2026 test VM the upgrade took 3 min 32 s.
do-release-upgrade from Ubuntu 24.04 to 26.04.1 left Docker’s apt source at Enabled: no, so apt policy docker-ce showed only the installed package. The published port on 8080 returned HTTP 200 after a 15 second sampled gap during the reboot.
By ProDevs. Published 2026-10-10. AI disclosure: drafted with AI assistance.
Who this is for: DevOps engineers and developers · Intermediate · You’ll need: a 24.04 server running Docker CE from Docker’s apt repo, root, console or out-of-band access, and a snapshot or backup.
Test VM, 5 Oct 2026, times in IST: aarch64, 2 vCPU, 3.8 GiB RAM, root filesystem 38G on a 40 GiB disk, Ubuntu 24.04.5 and kernel 6.8.0-146-generic before the release upgrade. Disposable, not a production server. The client was a second VM: Ubuntu 24.04.4, aarch64, 1 vCPU, 956 MiB RAM.
Shareable fact
| Reading | Result | Caveat |
|---|---|---|
| Upgrade on 5 Oct 2026 | 3 min 32 s | 2 vCPU, 3.8 GiB RAM, two containers |
| Port sampled gap | 15 s | Probed every 5 s, not a packet capture |
| Snapshot rollback to SSH | 22 s | Disk snapshot, not an in-place downgrade |
Still deciding whether this box should run Docker at all? Start with Docker or a plain VPS.
What changes for a Docker host on Ubuntu 26.04?
From Ubuntu’s LTS summary. We measured only the kernel and cgroup lines on this VM. (Summary for LTS users)
- GA kernel 6.8 to 7.0. This host went from
6.8.0-146-genericto7.0.0-38-generic. - cgroup v1 is removed.
stat -fc %T /sys/fs/cgroupprintedcgroup2fsbefore and after. sudo-rsis the defaultsudo.rust-coreutilsis the default, with GNU tools asgnuplus the name (gnuls). OpenSSH goes from1:9.6p1to1:10.2p1. Chrony replacessystemd-timesyncdon new installs only./tmpis a tmpfs (a 24.10 change). New AppArmor profiles can deny unexpected uses. We measured none of these.
Ubuntu’s own docker.io 29 and containerd 2.2.2 packages are not Docker CE’s containerd.io. (Changes since the previous interim)
Prerequisites
- A disk snapshot taken after 24.04 is fully updated and the stack is healthy.
- Console or out-of-band access. We used SSH inside tmux. The transcript shows no extra SSH port and no port 1022.
Prompt=ltsin/etc/update-manager/release-upgrades.- A copy of every third-party apt source. The upgrader disables them but does not remove software installed from them. (How to upgrade your Ubuntu release)
- Compose project and volume names written down.
- Free space on
/. Ours was 38G on a 40 GiB disk. The upgrader’s free-space figure was not recorded.
Not for
This covers Docker CE from Docker’s apt repo (docker-ce and containerd.io). It is not for Ubuntu’s docker.io package (not tested), a first Docker install, a firewall built from scratch, or an in-place downgrade.
Alternatives
- Stay on 24.04. Ubuntu’s server doc says an LTS release gets 5 years of standard support and security updates, and interim releases nine months. (How to upgrade your Ubuntu release)
- Install 26.04 fresh and restore the Step 2 volume tarball. Not timed.
do-release-upgrade --allow-third-party, whichdo-release-upgrade --helplists on the 24.04 upgrader. Not tested, so we do not know if the Docker source would stay enabled. The nftables firewall backend was not tested either.
Step 1: What do you record before do-release-upgrade?
Save this output off the box.
grep -r download.docker.com /etc/apt/sources.list.d/ # tested with Docker Engine v29.8.2, Ubuntu 24.04.5 to 26.04.1
docker version
docker info
docker compose ls
docker volume ls
sudo ufw status verbose
iptables -V
sudo aa-status | grep -i docker
stat -fc %T /sys/fs/cgroup
Not sure what iptables -V is telling you? Talk2Term explains a shell command in plain English and asks before it runs anything.
Held noble builds before the release upgrade, and the resolute builds after the Step 4 fix on 5 Oct 2026:
| Package | Still installed after the 26.04 reboot | After the resolute reinstall |
|---|---|---|
| docker-ce | 5:29.8.2-1~ubuntu.24.04~noble | 5:29.8.2-1~ubuntu.26.04~resolute |
| docker-ce-cli | 5:29.8.2-1~ubuntu.24.04~noble | 5:29.8.2-1~ubuntu.26.04~resolute |
| containerd.io | 2.3.6-1~ubuntu.24.04~noble | 2.3.6-1~ubuntu.26.04~resolute |
| docker-compose-plugin | 5.6.0-1~ubuntu.24.04~noble | 5.6.0-1~ubuntu.26.04~resolute |
| docker-buildx-plugin | Installed. Version not recorded. | Not in the resolute install. Left on the noble build. |
| docker-model-plugin | Installed. Version not recorded. | Not in the resolute install. Left on the noble build. |
The plugins have no pin because the logs do not record one. The stack was Compose project upgrade-lab: postgres:16-alpine on named volume pgdata (local driver, on the root disk) and nginx:1.27-alpine publishing 8080:80, both restart: unless-stopped, with 1,000 rows. Checksum, md5 of COPY items TO STDOUT WITH CSV: de1cc8f70bf4486b289992dfa06cbd61. For this image’s idle RAM, see Postgres RAM when Docker looks idle.
docker info: Server 29.8.2, overlayfs, containerd snapshotter, cgroup driver cgroupfs, cgroup version 2, firewall backend iptables, apparmor, seccomp, cgroupns.
Step 2: How do you update 24.04 and save the volume?
sudo apt-get update
sudo apt-get full-upgrade
On our VM this ran 09:56:05 to 09:56:44 IST (39 s): 114 upgraded, 11 newly installed, 0 not upgraded. The point release became 24.04.5, the kernel went from 6.8.0-100-generic to 6.8.0-146-generic, and the four held Docker packages stayed held. Reboot, confirm the row count and checksum, and copy the Compose file off the box.
We did not test a restore from this tarball. Take one anyway and keep it off the host:
docker run --rm \
-v pgdata:/from:ro \
-v "$PWD":/to \
alpine:3.20 \
tar -C /from -cf /to/pgdata-backup.tar .
Snapshot the disk after that reboot, while the checksum still matches.
Step 3: Which prompts does do-release-upgrade show?
On 5 Oct 2026, sudo do-release-upgrade -c printed New release '26.04.1 LTS' available. Ubuntu enabled that path on 29 Sep 2026 and tells server users to run do-release-upgrade. (Upgrade announcement) Skip -d. The server doc reserves it for the period before the upgrade is offered. (How to upgrade your Ubuntu release)
Probe the published port every 5 seconds from a second machine, and run the upgrade in tmux or on the console.
sudo do-release-upgrade
Answers on our run:
Continue [yN]after the 26.04 welcome:yat 10:05:35 IST.- No
Y/I/N/O/D/Zconfig-file prompt. Package scripts removed obsolete conffiles without asking, such as/etc/sysctl.conf,/etc/init.d/kmodand files under/etc/iproute2/. - Log at 10:05:43 IST: Docker’s deb822 entry
Suites: noblewas disabled as an unknown mirror and rewritten withEnabled: no. Continue [yN] Details [d]before the install:y.Remove obsolete packages?,20 packages are going to be removed.,Continue [yN] Details [d], with no names listed. We answeredNat 10:08:56 IST. The server doc’s sample shows 30 packages, not this run.System upgrade is complete., thenRestart required:y.
The transcript fetch lines were Fetched 962 kB for the upgrade tool and Fetched 29.4 MB in 0s (0 B/s) for one archive. The debug log at 10:08:56 IST lists all six Docker packages from the table, containerd.io included, as obsolete, then skipping foreign pkg for each. marked for removal lists 20 Ubuntu packages, python3.12 through gcc-14-base, and no Docker package. So N kept those Ubuntu packages. Docker stayed because the upgrader skipped it as foreign.
The probe’s last HTTP 200 was 10:08:55 IST. Probes at 10:09:00 and 10:09:05 returned 000000, and the next HTTP 200 came at 10:09:10. who -b printed system boot 2026-10-05 10:08. Docker was active at 10:09:07 IST.
Step 4: How do you point Docker’s apt source at resolute?
At 10:09:43 IST, before the fix, /etc/apt/sources.list.d/docker.sources was exactly this, with no .distUpgrade or .save file beside it (only docker.sources and ubuntu.sources):
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: arm64
Signed-By: /etc/apt/keyrings/docker.asc
Enabled: no
arm64 is this aarch64 VM. On amd64, keep amd64. (Install Docker Engine on Ubuntu)
Set Suites to resolute and delete Enabled: no, or regenerate the file with the install doc’s UBUNTU_CODENAME line. After that edit and apt-get update, and before the install, apt-cache policy listed candidate 5:29.8.2-1~ubuntu.26.04~resolute.
The four packages held before the upgrade were containerd.io, docker-ce, docker-ce-cli and docker-compose-plugin. A plain apt-get install pkg=ver on a held package stops for a confirmation, so unhold first or pass --allow-change-held-packages with -y. The install log does not show the shell line, but it ends with a set on hold. line for each of the four, which matches this sequence:
sudo apt-mark unhold \
containerd.io \
docker-ce \
docker-ce-cli \
docker-compose-plugin
sudo apt-get update
sudo apt-get install \
docker-ce=5:29.8.2-1~ubuntu.26.04~resolute \
docker-ce-cli=5:29.8.2-1~ubuntu.26.04~resolute \
containerd.io=2.3.6-1~ubuntu.26.04~resolute \
docker-compose-plugin=5.6.0-1~ubuntu.26.04~resolute
sudo apt-mark hold \
containerd.io \
docker-ce \
docker-ce-cli \
docker-compose-plugin
apt-get update started at 10:10:07 IST. The install ran 10:10:21 to 10:10:27 IST (6 s): 4 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Engine stayed 29.8.2, and the suffix on those four changed from noble to resolute.
The two plugins were not in that command. Once the source points at resolute, read the candidate and install it:
apt-cache policy docker-buildx-plugin docker-model-plugin
sudo apt-get install \
docker-buildx-plugin \
docker-model-plugin
At 10:10:27 IST, docker compose ps showed both containers Up Less than a second, so the reinstall restarted Docker. curl.csv ends at 10:10:05, so that restart’s port gap was not measured. The row count was still 1000 and the checksum still de1cc8f70bf4486b289992dfa06cbd61.
Step 5: How do you check containers, the port, UFW and AppArmor?
systemctl status docker containerd --no-pager
docker compose ps
sudo ufw status verbose
iptables -V
sudo aa-status | grep -i docker
At 10:09:07 IST, docker was active, containerd running, and upgrade-lab-db-1 and upgrade-lab-web-1 Up without a docker compose up. A loopback request to port 8080 returned HTTP 200.
UFW stayed at default deny incoming, allow outgoing, deny routed, with only 22/tcp allowed, before and after.
- Loopback on the Docker host: HTTP 200 before and after.
- The two guests could not open TCP to each other. Ports 22 and 8080 on the Docker host address timed out.
- The client got HTTP 200 on port 8080 through the hypervisor forward under that UFW policy, and so did a curl from the hypervisor to the Docker host address.
So our run does not prove the bypass. Docker’s install page says published container ports bypass ufw and firewalld, and the packet-filtering page says that traffic is diverted in the nat table before ufw’s INPUT and OUTPUT chains. (Install Docker Engine on Ubuntu, Packet filtering and firewalls) Put your own rules in the DOCKER-USER chain, which runs before DOCKER-FORWARD and DOCKER (Docker and iptables), or publish with the localhost address so only the Docker host can open the port (Port publishing).
On the Docker host:
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
From the second machine, with the documentation address 203.0.113.10 standing in for your host:
HOST=203.0.113.10; curl -sS -o /dev/null -w '%{http_code}\n' "http://$HOST:8080/"
aa-status showed docker-default on Postgres and nginx. Kernel denials this boot were profile who opening /etc/nsswitch.conf and /etc/passwd, not a docker profile. docker info still said firewall backend iptables, with total memory 3.806 GiB. iptables -V moved from iptables v1.8.10 (nf_tables) to iptables v1.8.11 (nf_tables), alternative still iptables-nft, and nft list tables showed ip filter, ip6 filter, ip nat, ip6 nat and ip raw. One dockerd line at 10:09:07 IST (Deleting nftables IPv6 rules, delete table ip6 docker-bridges, No such file or directory) did not stop startup.
Re-check memory caps on cgroup v2. Memory limits, and how to prove an OOM shows the docker inspect fields.
Verify
Split by clock. These are not one reading.
Recorded at 10:09:43 IST, after the reboot and before the resolute install:
Ubuntu 26.04.1 LTS
kernel 7.0.0-38-generic
loopback port 8080 HTTP 200
docker-ce still 5:29.8.2-1~ubuntu.24.04~noble
containers Up
Recorded at 10:10:27 IST, at the end of the resolute install:
client=29.8.2 server=29.8.2
four packages on the ubuntu.26.04~resolute builds
upgrade-lab-db-1 Up Less than a second
upgrade-lab-web-1 Up Less than a second
row count 1000
checksum de1cc8f70bf4486b289992dfa06cbd61
The checksum must match the value you saved before the snapshot. The port gap during this second restart was not in curl.csv.
Troubleshooting
| Symptom | What it means | What to do |
|---|---|---|
apt policy docker-ce lists only the installed package |
Source disabled, or Suites still noble. That was our file at 10:09:43 IST. |
Step 4. |
| Obsolete-packages prompt | Our screen said 20 packages and hid the names. Those 20 were Ubuntu packages. Docker was skipped as a foreign package, including containerd.io. Answering N did not keep Docker. |
Step 4. N only keeps the Ubuntu packages in that list. |
| Published port answers while UFW denies incoming | Docker documents a bypass. Our run did not prove it. | Add rules in DOCKER-USER. (Docker and iptables) Or publish on 127.0.0.1 so only the host can connect. (Port publishing) |
You want nft rules only |
Docker supports iptables-nft and iptables-legacy, not rules created with nft. The nftables backend is experimental since 29.0.0, and Docker will not enable IP forwarding itself on that backend. |
Not tested here. We stayed on iptables, alternative iptables-nft. (Install Docker Engine on Ubuntu, Docker with nftables) |
| A script changes behavior | rust-coreutils is the default. GNU tools use a gnu prefix. |
Not seen on this run. (Summary for LTS users) |
Rollback
Restore the snapshot taken after the 24.04.5 update. Ours was a disk clone taken 10:03:44 to 10:03:48 IST (stop 4.25 s, clone under 1 s), because the VM driver had no snapshot command. The restore started at 10:10:40 IST and SSH was back at 10:11:02 IST: Ubuntu 24.04.5 LTS, kernel 6.8.0-146-generic, both containers up, count 1000, the same checksum, HTTP 200 on the loopback port.
We did not run an in-place downgrade. Ubuntu’s desktop upgrade doc says you return to an earlier LTS by reinstalling, and that downgrading the existing system is not supported. (Upgrade Ubuntu desktop) With no snapshot, install 24.04 fresh and restore the Step 2 tarball. We did not time that path.
FAQ
Can I upgrade Ubuntu 24.04 to 26.04 now?
Yes. Ubuntu enabled upgrades from 24.04 LTS to 26.04.1 LTS on 29 Sep 2026. On a server, run sudo do-release-upgrade. On 5 Oct 2026, sudo do-release-upgrade -c printed New release 26.04.1 LTS available. Do not pass -d once that check shows the new release.
Does do-release-upgrade break Docker?
It disables third-party apt sources, including Docker’s. Packages already installed from those sources are not removed. On our test VM the Docker source stayed on suite noble with Enabled set to no. The containers came back. After we set Suites to resolute, removed Enabled: no and ran apt-get update, apt-cache policy listed the resolute candidate before the install.
Does Docker support Ubuntu 26.04?
Docker’s install page lists Ubuntu Resolute 26.04 (LTS). On 5 Oct 2026 we installed docker-ce 5:29.8.2-1~ubuntu.26.04~resolute, the matching cli and compose plugin, and containerd.io 2.3.6-1~ubuntu.26.04~resolute. docker-buildx-plugin and docker-model-plugin were left on the noble builds. We did not record their version strings.
Do published Docker ports bypass UFW on 26.04?
Docker’s install page says ports you publish with Docker bypass ufw and firewalld. Docker’s packet-filtering page says that traffic is diverted in the nat table before ufw’s INPUT and OUTPUT chains. Our test did not prove that bypass. The second VM could not open TCP to the Docker host. It reached the published port only through a hypervisor forward.
If the host is not this test VM
This guide records one test VM from Ubuntu 24.04 to 26.04. If the host you would upgrade is one you cannot restore from a snapshot, write what that host runs before you start.
Use the contact form. We reply in writing, usually within one business day. The reply says we can help, we should not take this on, or we need one detail. That look is free. If we are full, we say so. Do not send passwords or keys.
If that reply says a paid written audit is the next step, the range is ₹15,000–₹25,000. That is the range on the services page. This article has no payment link.


