Image build doesn't use caches
When I repeatedly attempt to build an image, it always assembles it without using any cached layer. I tried various options (nocache=False, layers=True etc.) but was unsuccessful.
My Dockerfile/Containerfile looks for example like this:
FROM docker.io/library/fedora:latest
RUN dnf update -y
RUN echo 'Hey'
Building the image using this library always re-executes all the steps:
import podman
client = podman.PodmanClient(base_url="unix:///tmp/podman.sock")
print(client.version())
image, logs = client.images.build(
dockerfile="Dockerfile",
tag="localhost/test-podman",
path="src/",
rm=False,
)
for log in logs:
print(log)
However if I use the docker library instead, it uses caches:
import docker
client = docker.DockerClient(base_url='unix:///tmp/podman.sock')
print(client.version())
image, logs = client.images.build(
dockerfile="Dockerfile",
tag="localhost/test-docker",
path="src/",
rm=False,
)
for log in logs:
print(log)
I'm experiencing this issue with podman version 5.2.2 (on Alma Linux 9), version 4.9.3 (Ubuntu 24.04 in WSL), version 5.4.1 (on mac OS).
$ time python run-podman.py
real 0m11.543s
user 0m0.118s
sys 0m0.027s
$ time python run-podman.py
real 0m12.186s
user 0m0.109s
sys 0m0.033s
$ time python run-docker.py
real 0m12.512s
user 0m0.147s
sys 0m0.011s
$ time python run-docker.py
real 0m0.323s
user 0m0.132s
sys 0m0.000s
definitely a bug. can reproduce on Fedora 42, thanks for the report.
If it helps, I've just encountered the same on fedora 42, it looks like docker-py is using the compat API (/build) and podman-py uses /libpod/build.
I compared how podman-remote works to this library, by defaults it sends many more things. Using this command:
podman-remote --build-arg base=quay.io/fedora-ostree-desktops/base-atomic:42 -v $(pwd)/dnf-cache:/var/cache/libdnf5:z -t sidecar .
I see all these parameters sent in the http request
{'buildargs': '{"base":"quay.io/fedora-ostree-desktops/base-atomic:42"}',
'compatvolumes': '0',
'dockerfile': '["Containerfile"]',
'forcerm': '1',
'httpproxy': '1',
'identitylabel': '1',
'idmappingoptions': '{"HostUIDMapping":true,"HostGIDMapping":true,"UIDMap":[],"GIDMap":[],"AutoUserNs":false,"AutoUserNsOpts":{"Size":0,"InitialSize":0,"PasswdFile":"","GroupFile":"","AdditionalUIDMappings":null,"AdditionalGIDMappings":null}}',
'inheritlabels': '1',
'isolation': '0',
'jobs': '1',
'layers': '1',
'networkmode': '0',
'nsoptions': '[{"Name":"user","Host":true,"Path":""}]',
'omithistory': '0',
'output': 'sidecar',
'outputformat': 'application/vnd.oci.image.manifest.v1+json',
't': 'sidecar',
'volume': '[omitted]dnf-cache:/var/cache/libdnf5:z'}
By trial and error I found that setting layers and outputformat as above allows podman to use cached layers. Of these two, the outputformat parameter is not documented in the podman API and I believe it corresponds to the --format flat in podman build docs (see https://docs.podman.io/en/latest/markdown/podman-build.1.html#format). I do not know go, but if I have understood how the code works, these are all the parameters supported and quite a few are not documented: identitylabel, idmappingoptions, isolation, jobs, networkmode (only wrong type), nsoptions, omithistory, output (there is outputs "TBD"), outputformat.
As a possible fix, maybe podman-py could default both layers and outputformat to those values, mirroring how the podman cli works.
Thanks for the detailed report
As a possible fix, maybe podman-py could default both layers and outputformat to those values, mirroring how the podman cli works.
I fully agree.
Are you interested in opening a PR to fix it? otherwise I'll put this in my stack of things to work on :)
Sure, I'll make a PR.
thanks @fulminemizzega , don't hesitate to ping me for help or to review your PR