Goodbye Docker! Hello Podman!
A short migration guide from Docker to Podman
Monday 11th August 2025
Updated 12th August 2025

I have been considering Podman in the past but then Docker started to become more IPv6 friendly so I didn’t have to do it yet. What finally made me switch was the fact that I couldn’t create a working FreeIPA container with Docker. It was solved by Podman.
It could also have been the fact that I also switched from Debian to Fedora that made it work. I haven’t tested my compose file with Docker on the new system yet. However, Podman comes pre-installed on Fedora so why not use it.
Reasons for running Podman instead of Docker
Rootless or Rootful
The first reason everybody brings up is the ability to run containers as a regular user (Rootless mode) or as root (Rootful mode). Not only will the containers privileges be different, but also the network stack. At the moment I find it confusing to know which containers should run Rootless or Rootful. I guess you could try rootless first and see if it works as expected.
However, if the application needs a specific network driver like macvlan, or needs tight integration with systemd, Rootful is probably the answer.
Better integration with systemd
The main reason for me is that Podman works better with systemd than Docker. I believe this is the reason it why I was able to make FreeIPA finally work, after days of troubleshooting.
Podman can also define rootful containers as systemd services using Podman Quadlet.
Pretty good IPv6 support
As far as I know podman doesn’t have any limitations on IPv6 like Docker has.
I only found one caveat with Podman and that is rootful containers seemingly doesn’t do port forwarding on IPv6. However, that is almost only a cosmetic bug as IPv6 forwarding still works, apart to the localhost address. I have updated my last Podman post about it.
However it is annoying that the Podman default network doesn’t support IPv6 so you have to replace it with your own.
… Oh yeah, it’s also annoying that you can’t specify your own subnet pool for IPv6. That means every time you create a network, it will assign an IPv6 ULA address instead of a GUA address. If the containers inside the network is running dual-stack, IPv4 communication between containers will take precedence.
But other than that, IPv6 support is pretty solid.
…And Pods!
… Oh yeah, Podman supports pods as well. How that is different from connecting containers to the same network? Not much. You do get some benefits: For example that containers in a pod share other specific attributes, like cgroups, that otherwise would change the behavior for all containers on the system.
Source: https://www.net7.be/blog/article/podman_pods.html
Compatible with docker compose
This is more of a feature that makes migration from docker easier, than a unique feature to Podman. I have tested some of my docker compose projects in Podman without changing anything and they actually work.
All commands are similar to docker
Again, only something to make the migration easier. Almost every command that you run with “docker X” can be substituted with “podman X”
Migrate from Docker to Podman
Convinced yet? Here is a brief migration plan when the time comes:
Turn off Docker
Turn off docker but don’t uninstall it before migration is complete
Prune any unused networks and volumes
Turn off all containers
Turn off and disable docker.service and docker.socket
remove the docker0 bridge:
sudo ip link delete docker0
Install Podman
Depending on your system but let’s assume you have a debian-based system:
sudo apt install podman podman-composeThat’s it. No custom repositories or anything.
Configure Podman
You may want to change some defaults. First of all:
Copy the default configuration file from the /usr directory to /etc:
sudo cp /usr/share/containers/containers.conf /etc/containers/containers.confChanges in /etc supersedes changes in /usr. Therefore it’s better to make changes in the /etc directory so you can keep the one in /usr as backup.
Change the default network
After copying the default configuration:
Step 1: Create a new default network
Podmans default network called “podman” doesn’t support IPv6 and therefore you have to create a new one:
sudo podman network create --ipv6 podman1Note: The --ipv6 flag creates a dual-stack network and does not disable IPv4. You have to specify an IPv6 subnet and gateway if you want to create a IPv6-only network:
sudo podman network create --subnet fd00::/64 --gateway fd00::1 test1You can modify the network settings by editing the file:
sudo nano /etc/containers/networks/podman1.json
{
"name": "podman1",
"id": "44408b013cc62aeea7d5554979de9beec018739f40bd1b685398adb9ddd8a70f",
"driver": "bridge",
"network_interface": "podman1",
"created": "2025-03-01T21:02:43.264776095Z",
"subnets": [
{
"subnet": "100.101.0.0/24",
"gateway": "100.101.0.1"
},
{
"subnet": "2001:db8:1234:1008::/64",
"gateway": "2001:db8:1234:1008::1"
}
],
"ipv6_enabled": true,
"internal": false,
"dns_enabled": true,
"ipam_options": {
"driver": "host-local"
}
}Step 2: Change the settings in containers.conf
Change the default network and the default subnet pool:
sudo nano /etc/containers/containers.conf
...
default_network = "podman1"
...
default_subnet_pools = [
{"base" = "100.111.0.0/18", "size" = 24},
]
...Explanation:
You don’t have to change the default IPv4 network as it’s already defined in the new network file.
Unfortunately there is no way to create a default subnet pool for IPv6.
Add docker.io registry
Container registries are used for repository sources to download container images.
On RHEL-based systems, Podman comes shipped with docker.io as one of the default registries. For some reason, Debian-based systems does not include any base registries at all and have to manually be added:
sudo nano /etc/containers/registries.conf
...
# Add this to the bottom of the file:
unqualified-search-registries = ["docker.io"]Update: or create a .conf file in /etc/containers/registries.d/. The latest version of podman on Debian doesn’t have a registries.conf file anymore.
Create policy.json
When you start a container on a Debian-based distro for the first time you will get this error message:
Error: open /etc/containers/policy.json: no such file or directoryYou need to create a default policy for all containers:
$ sudo nano /etc/containers/policy.json
{
"default": [
{
"type": "reject"
}
}Best practice is the reject everything and then create granular trust control for the repositories. This command trusts all packages from the Docker.io repository:
sudo podman image trust set --type accept docker.ioVerification:
$ podman image trust show
TRANSPORT NAME TYPE ID STORE
all default reject
repository docker.io accept For more information on how to setup more granular trust control:
https://docs.podman.io/en/v4.4/markdown/podman-image-trust.1.html
Change the default directory for volumes
You might have a mounted directory with more storage available than your home directory. Podman stores container volumes in two locations, depending on if you run Rootless or Rootful containers:
Rootful volumes:
/var/lib/containers/storage/volumesRootless volumes:
$HOME/.local/containers/storage/volumes
To change the default location for Rootful volumes, edit volume_path inside /etc/containers/containers.conf
volume_path = "/var/lib/containers/storage/volumes"To change the default location for Rootless volumes:
Step 1: Create a directory under $HOME/.config/
mkdir $HOME/.config/containersStep 2: create a containers.conf file under $HOME/.config/containers/ and set the path there:
nano $HOME/.config/containers/containers.conf
-----------------------------------------------
volume_path = "/var/local/bastuklubben.online/storage/volumes"Note: The path must exist and be writable by the current user.
Change the default directory for images
Images take a lot of space to. Same deal here, 2 locations:
Rootful images:
/var/lib/containers/storageRootless images:
$HOME/.local/share/containers/storage
To change the default image path for Rootful, create a file (if it doesn’t exist) called storage.conf inside /etc/containers/
nano
----------------------------------------------
[storage]
driver = "overlay"
graphroot = "/var/lib/containers/storage"Note: Graphroot indicates the path for the image location
For system running SELinux, it’s also necessary to update some related values:
sudo semanage fcontext -a -e /var/lib/containers/storage /path/to/new/storage sudo restorecon -Rv /path/to/new/storageFor Rootless images:
Step 1: find out what the UID of your user is:
id $USERStep 2: Create a file called
storage.confinside$HOME/.config/containers/
nano $HOME/.config/containers/storage.conf
-----------------------------------------
[storage]
driver = "overlay"
runroot = "/run/user/1000"
graphroot = "/var/local/bastuklubben.online/storage/images"Step 3: Update SELinux if applicable:
sudo semanage fcontext -a -e ~/.local/share/containers/storage /path/to/new/storage
sudo restorecon -Rv /path/to/new/storageSource: https://earihos.medium.com/how-to-use-custom-storage-location-in-podman-cc825648da90
Let Rootless Containers run after user have logged out:
Let users run their containers even when they are logged out:
sudo loginctl enable-linger $USERLet Rootless Containers forward well-known ports
I wouldn’t necessarily recommend this (unless you have to) but if you want to allow ports like 80 and 443 to be forwarded on Rootless Containers you have to add this sysctl setting:
sudo nano /etc/sysctl.d/podman-privileged-ports.conf
# Lowering privileged ports to 80 to allow us to run rootless Podman containers on lower ports
# default: 1024
net.ipv4.ip_unprivileged_port_start=80Note: Despite the name, the setting applies to IPv6 ports as well.
Then load the new setting:
sudo sysctl -p /etc/sysctl.d/podman-privileged-ports.confThat should be enough tweaking to get you started.
Uninstall Docker
After you made some tests and made sure your containers and compose projects works smoothly, you can uninstall docker. Read the Docker official instructions on how to completely remove Docker for your distribution.
Install podman-docker
Not necessary but if you keep typing “docker container ps” instead of “podman container ps” you can install the podman-docker package:
sudo apt install podman-dockerThen the system will accept all docker commands but execute them with Podman instead.
Special Mention
Thank you Kristopher for you guide on how to migrate from docker to Podman. Your post was a good foundation for this post.



