podman icon indicating copy to clipboard operation
podman copied to clipboard

Podman v5 no longer builds Dockerfiles with build args used as --platform in FROM instruction

Open phandox opened this issue 1 year ago • 8 comments

Issue Description

Hi,

since Podman v5, our existing Dockerfiles which uses this pattern:

ARG PLATFORM=linux/amd64
FROM --platform=${PLATFORM} busybox
ARG PLATFORM
RUN echo "platform: ${PLATFORM}"

no longer builds and errors out on --platform not having any value. Here is output from podman v5 (running via podman run -v ${PWD}:/app -it --rm --privileged quay.io/podman/stable:v5.1-immutable)

[root@94fcff13cb01 app]# cat Dockerfile.bug-report 
ARG PLATFORM=linux/amd64

FROM --platform=${PLATFORM} busybox

ARG PLATFORM

RUN echo "platform: ${PLATFORM}"
[root@94fcff13cb01 app]# podman build -f Dockerfile.bug-report --no-cache .
Error: no value specified for --platform=
[root@94fcff13cb01 app]# podman version
Client:       Podman Engine
Version:      5.1.0
API Version:  5.1.0
Go Version:   go1.22.3
Built:        Wed May 29 00:00:00 2024
OS/Arch:      linux/amd64

Same Dockerfile works in Podman 4.9.4 (running with podman run -v ${PWD}:/app -it --rm --privileged quay.io/podman/stable:v4.9.4-immutable)

[root@2214e9821ccd app]# cat Dockerfile.bug-report 
ARG PLATFORM=linux/amd64

FROM --platform=${PLATFORM} busybox

ARG PLATFORM

RUN echo "platform: ${PLATFORM}"
[root@2214e9821ccd app]# podman build -f Dockerfile.bug-report --no-cache .
STEP 1/3: FROM busybox
Resolved "busybox" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob ec562eabd705 done   | 
Copying config 65ad0d468e done   | 
Writing manifest to image destination
STEP 2/3: ARG PLATFORM
--> 7af8e0b457d4
STEP 3/3: RUN echo "platform: ${PLATFORM}"
WARN[0001] Path "/run/secrets/etc-pki-entitlement" from "/etc/containers/mounts.conf" doesn't exist, skipping 
WARN[0001] Path "/run/secrets/rhsm" from "/etc/containers/mounts.conf" doesn't exist, skipping 
platform: linux/amd64
COMMIT
--> 4838f2a308c5
4838f2a308c5a23189508d27642255b6f32524993a2f5190e68589fc91a318dc
[root@2214e9821ccd app]# podman version
Client:       Podman Engine
Version:      4.9.4
API Version:  4.9.4
Go Version:   go1.21.8
Built:        Tue Mar 26 09:39:52 2024
OS/Arch:      linux/amd64

Steps to reproduce the issue

Steps to reproduce the issue

  1. Create Dockerfile using ARG with default value. Reference the ARG in FROM instruction
ARG PLATFORM=linux/amd64

FROM --platform=${PLATFORM} busybox

ARG PLATFORM

RUN echo "platform: ${PLATFORM}"
  1. Run podman build -f Dockerfile . Podman must be version 5+
  2. Podman build fails with Error: no value specified for --platform=

Repeat the steps with Podman v4 - error doesn't happen

Describe the results you received

Podman build fails with Error: no value specified for --platform= (Podman v5)

Describe the results you expected

Podman v5 would build the image as it works with Podman v4

podman info output

host:
  arch: amd64
  buildahVersion: 1.36.0
  cgroupControllers: []
  cgroupManager: cgroupfs
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.10-1.fc40.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.10, commit: '
  cpuUtilization:
    idlePercent: 95.38
    systemPercent: 0.93
    userPercent: 3.69
  cpus: 16
  databaseBackend: sqlite
  distribution:
    distribution: fedora
    variant: container
    version: "40"
  eventLogger: file
  freeLocks: 2048
  hostname: 94fcff13cb01
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 6.5.0-1024-oem
  linkmode: dynamic
  logDriver: k8s-file
  memFree: 788545536
  memTotal: 32868839424
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.10.0-1.fc40.x86_64
      path: /usr/libexec/podman/aardvark-dns
      version: aardvark-dns 1.10.0
    package: netavark-1.10.3-3.fc40.x86_64
    path: /usr/libexec/podman/netavark
    version: netavark 1.10.3
  ociRuntime:
    name: crun
    package: crun-1.15-1.fc40.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.15
      commit: e6eacaf4034e84185fd8780ac9262bbf57082278
      rundir: /run/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedge +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt-0^20240510.g7288448-1.fc40.x86_64
    version: |
      pasta 0^20240510.g7288448-1.fc40.x86_64
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: false
    path: /run/podman/podman.sock
  rootlessNetworkCmd: pasta
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: false
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: ""
    package: ""
    version: ""
  swapFree: 2044456960
  swapTotal: 2046816256
  uptime: 3h 40m 22.00s (Approximately 0.12 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - docker.io
  - quay.io
store:
  configFile: /etc/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.imagestore: /usr/lib/containers/storage
    overlay.mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: fuse-overlayfs-1.13-1.fc40.x86_64
      Version: |-
        fusermount3 version: 3.16.2
        fuse-overlayfs: version 1.13-dev
        FUSE library version 3.16.2
        using FUSE kernel interface version 7.38
    overlay.mountopt: nodev,fsync=0
  graphRoot: /var/lib/containers/storage
  graphRootAllocated: 981132795904
  graphRootUsed: 194885316608
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Supports shifting: "true"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 0
  runRoot: /run/containers/storage
  transientStore: false
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 5.1.0
  Built: 1716940800
  BuiltTime: Wed May 29 00:00:00 2024
  GitCommit: ""
  GoVersion: go1.22.3
  Os: linux
  OsArch: linux/amd64
  Version: 5.1.0

Podman in a container

Yes

Privileged Or Rootless

Privileged

Upstream Latest Release

Yes

Additional environment details

Testing with Podman in Podman, with --privileged flag. Can be reproduced also on Google Kubernetes Engine, where we run our CI jobs from Gitlab Runners (using the quay.io/podman/stable:v5.1-immutable image).

Additional information

Happens all the time, doesn't matter if --build-arg is passed with podman build command.

phandox avatar Jun 19 '24 10:06 phandox

I don't think this worked back in 4.9.4. Near as I can tell, the ARG value from the heading wasn't being evaluated there, effectively causing it to be treated as if no value was supplied, and that most-likely-an-error was quietly ignored. Opened https://github.com/openshift/imagebuilder/pull/286 to fix it.

nalind avatar Jun 20 '24 15:06 nalind

Ah, @baude corrected me - it did pay attention to arg values supplied in the header, but ignored those supplied from elsewhere.

nalind avatar Jun 20 '24 18:06 nalind

Hi @nalind thank you for looking into issue! I see that https://github.com/containers/buildah/pull/5599 was merged - will it be incorporated in next release of Podman?

phandox avatar Jun 26 '24 07:06 phandox

Yes

rhatdan avatar Jun 26 '24 10:06 rhatdan

I think I may be hitting this issue as well. The behavior of Docker is to add platform args to the global scope. I am using TARGETARCH in a FROM statement. In order for it to work, I have to declare ARG TARGETARCH even though in my case I'm not using it any of the build stages (as demonstrated by the empty value from command in the first stage).

ARG TARGETARCH  # Without this, the build fails in podman but succeedes with docker
FROM alpine as base
RUN echo "Arch is $TARGETARCH"

FROM --platform=amd64 base AS build-amd64
ENV BUILD="Building for x86"

FROM --platform=amd64 base AS build-arm64
ENV BUILD="Building for ARM"

FROM build-${TARGETARCH} AS final
RUN echo "${BUILD}"

Successful output
> podman build --no-cache -t test -f Containerfile .
[1/4] STEP 1/2: FROM alpine AS base
[1/4] STEP 2/2: RUN echo "Arch is $TARGETARCH"
Arch is
--> 555f1360d102
[3/4] STEP 1/2: FROM 555f1360d1029564a7074722e862ab037851acc72997d736374ef97ecb96f9fd AS build-arm64
[3/4] STEP 2/2: ENV BUILD="Building for ARM"
--> f6668c205c87
[4/4] STEP 1/2: FROM f6668c205c878d4d890df9fa080691e2628300f90bc505fa1e988c44430c4818 AS final
[4/4] STEP 2/2: RUN echo "${BUILD}"
Building for ARM
[4/4] COMMIT test
--> 74a9b02f2947
Successfully tagged localhost/test:latest
74a9b02f2947b92e45dc66bb32323497aa3990b56f3a2dcc95496f3a1c521cce

If I remove ARG TARGETARCH from the global scope, the build failes with podman (but completes successfully with docker).

# ARG TARGETARCH
FROM alpine as base
RUN echo "Arch is $TARGETARCH"

FROM --platform=amd64 base AS build-amd64
ENV BUILD="Building for x86"

FROM --platform=amd64 base AS build-arm64
ENV BUILD="Building for ARM"

FROM build-${TARGETARCH} AS final
RUN echo "${BUILD}"

> podman build --no-cache -t test -f Containerfile .
[4/4] STEP 1/2: FROM build-arm64 AS final
Resolving "build-arm64" using unqualified-search registries (/etc/containers/registries.conf.d/999-podman-machine.conf)
Trying to pull docker.io/library/build-arm64:latest...
Error: creating build container: initializing source docker://build-arm64:latest: reading manifest latest in docker.io/library/build-arm64: requested access to the resource is denied

samdoran avatar Jun 28 '24 21:06 samdoran

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jul 29 '24 00:07 github-actions[bot]

I'm also having this issue with podman 5.2.2

Previously it was working with a containerfile such as:

ARG TARGETPLATFORM=linux/amd64
FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9/ubi-minimal:9.4

Now it produces an error:

$ podman build --build-arg=TARGETPLATFORM=linux/arm64 -f test.dockerfile -t test  .
Error: reading multiple stages: attempted to redefine "TARGETPLATFORM": invalid argument

Removing the default value of TARGETPLATFORM gets rid of the error, but it seems like it will always use the current platform - it cannot be passed as an argument:

ARG TARGETPLATFORM
FROM --platform=$TARGETPLATFORM registry.access.redhat.com/ubi9/ubi-minimal:9.4
 podman build --build-arg=TARGETPLATFORM=linux/arm64 -f test.dockerfile -t test  .
STEP 1/1: FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/ubi-minimal:9.4
COMMIT test
--> 9d45c5b8b439

See amd64 is used instead of the expected arm64.

If I use a custom argument name, then it works:

ARG ZZ_TARGETPLATFORM
FROM --platform=$ZZ_TARGETPLATFORM registry.access.redhat.com/ubi9/ubi-minimal:9.4
$ podman build --build-arg=ZZ_TARGETPLATFORM=linux/arm64 -f test.dockerfile -t test  .
STEP 1/1: FROM --platform=linux/arm64 registry.access.redhat.com/ubi9/ubi-minimal:9.4
Trying to pull registry.access.redhat.com/ubi9/ubi-minimal:9.4...
Getting image source signatures
Checking if image destination supports signatures
Copying blob abd9eccbef61 skipped: already exists  
Copying config 42b74258be done   | 
Writing manifest to image destination
Storing signatures
COMMIT test

jotak avatar Sep 11 '24 08:09 jotak

TARGETPLATFORM is wired to the value that was passed to the --platform flag on the command line (or derived from a --arch and/or --os, if necessary), or to one of the values if it's a list and we're doing multiple builds, and it no longer needs to be explicitly declared before the first FROM instruction to be used in FROM instructions. I've opened https://github.com/containers/buildah/pull/5731 to accept the TARGETPLATFORM build arg as a fallback method of specifying it.

nalind avatar Sep 11 '24 15:09 nalind

Running into this same issue with version 5.4.0:

$ podman version
Client:       Podman Engine
Version:      5.4.0
API Version:  5.4.0
Go Version:   go1.23.10 (Red Hat 1.23.10-1.el9_6)
Built:        Wed Jun 25 06:42:18 2025
OS/Arch:      linux/ppc64le

This is a my sample container file:

$ cat Containerfile 
FROM quay.io/rockylinux/rockylinux:9-minimal
ARG SOMEARG
RUN echo $SOMEARG

And this is the result of building it:

$ podman build --build-arg SOMEARG=somevalue -f Containerfile 
STEP 1/3: FROM quay.io/rockylinux/rockylinux:9-minimal
STEP 2/3: ARG SOMEARG
--> e8a75f122119
STEP 3/3: RUN echo $SOMEARG

COMMIT
--> 41cea32f5fc8
41cea32f5fc88a2cc6412f86a45e31b437e1b3c3755af289261198f34dbf64e6

I've tried quoting it and stuff but it just won't work.

ralberrto avatar Aug 18 '25 20:08 ralberrto

@ralberrto I think your case is different from the one in this issue, which was specifically about the BUILDTARGET arg and the --platform flag. Your example works for me when I try it with podman-5.5.2-1.fc42.x86_64 on Fedora 42, and with podman-5.4.0-7.el9.x86_64 in a CentOS Stream 9 VM, so I don't think I can reproduce what you're seeing.

nalind avatar Aug 18 '25 21:08 nalind

I'm also used to using Docker's built-in global ARGs in multi-arch Dockerfiles: ARG TARGETPLATFORM ARG BUILDPLATFORM ARG BUILDARCH ARG TARGETARCH

I hope Podman's behavior can be consistent with Docker's.

KeyOfSpectator avatar Oct 10 '25 09:10 KeyOfSpectator