Fix multi-arch builds to preserve OCI config metadata
All checks were successful
Build and Push Base Distro Images / build-and-push (apko/base.yaml, base) (push) Successful in 10m9s
Build and Push Base Distro Images / build-and-push (apko/build.yaml, build) (push) Successful in 10m20s
Build and Push Base Distro Images / build-and-push (apko/dotnet-runtime.yaml, dotnet-runtime) (push) Successful in 10m10s
Build and Push Base Distro Images / build-and-push (apko/dotnet-sdk.yaml, dotnet-sdk) (push) Successful in 10m18s
Build and Push Base Distro Images / build-and-push (apko/flutter-sdk.yaml, flutter-sdk) (push) Successful in 10m5s
Weekly Rebuild (CVE Updates) / rebuild (apko/base.yaml, base) (push) Successful in 9m56s
Weekly Rebuild (CVE Updates) / rebuild (apko/build.yaml, build) (push) Successful in 9m59s
Weekly Rebuild (CVE Updates) / rebuild (apko/dotnet-runtime.yaml, dotnet-runtime) (push) Successful in 9m59s
Weekly Rebuild (CVE Updates) / rebuild (apko/dotnet-sdk.yaml, dotnet-sdk) (push) Successful in 10m1s
Weekly Rebuild (CVE Updates) / rebuild (apko/flutter-sdk.yaml, flutter-sdk) (push) Successful in 10m0s
All checks were successful
Build and Push Base Distro Images / build-and-push (apko/base.yaml, base) (push) Successful in 10m9s
Build and Push Base Distro Images / build-and-push (apko/build.yaml, build) (push) Successful in 10m20s
Build and Push Base Distro Images / build-and-push (apko/dotnet-runtime.yaml, dotnet-runtime) (push) Successful in 10m10s
Build and Push Base Distro Images / build-and-push (apko/dotnet-sdk.yaml, dotnet-sdk) (push) Successful in 10m18s
Build and Push Base Distro Images / build-and-push (apko/flutter-sdk.yaml, flutter-sdk) (push) Successful in 10m5s
Weekly Rebuild (CVE Updates) / rebuild (apko/base.yaml, base) (push) Successful in 9m56s
Weekly Rebuild (CVE Updates) / rebuild (apko/build.yaml, build) (push) Successful in 9m59s
Weekly Rebuild (CVE Updates) / rebuild (apko/dotnet-runtime.yaml, dotnet-runtime) (push) Successful in 9m59s
Weekly Rebuild (CVE Updates) / rebuild (apko/dotnet-sdk.yaml, dotnet-sdk) (push) Successful in 10m1s
Weekly Rebuild (CVE Updates) / rebuild (apko/flutter-sdk.yaml, flutter-sdk) (push) Successful in 10m0s
Extract rootfs layer and config from apko OCI archive separately, then generate Dockerfile with ENV, ENTRYPOINT, WORKDIR and USER from the OCI config. Fixes missing environment variables in the final multi-arch image. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
81b219fedc
commit
4120f820a0
@ -122,13 +122,45 @@ jobs:
|
|||||||
apko build --arch aarch64 ${{ matrix.config }} \
|
apko build --arch aarch64 ${{ matrix.config }} \
|
||||||
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.tag.outputs.suffix }} \
|
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.tag.outputs.suffix }} \
|
||||||
/tmp/build-arm64/image.tar
|
/tmp/build-arm64/image.tar
|
||||||
cat > /tmp/Dockerfile <<'EOF'
|
|
||||||
FROM scratch
|
# Extract the rootfs layer from the OCI archive for each arch.
|
||||||
ARG TARGETARCH
|
# apko outputs an OCI image tarball; we need to extract just the
|
||||||
ADD build-${TARGETARCH}/image.tar /
|
# filesystem layer (.tar.gz) and the config metadata.
|
||||||
USER 65532
|
for arch in amd64 arm64; do
|
||||||
EOF
|
cd /tmp/build-${arch}
|
||||||
sed -i 's/^ //' /tmp/Dockerfile
|
tar xf image.tar
|
||||||
|
# The .tar.gz file is the filesystem layer
|
||||||
|
ROOTFS=$(ls *.tar.gz 2>/dev/null | head -1)
|
||||||
|
mv "$ROOTFS" rootfs.tar.gz
|
||||||
|
# Extract ENV and ENTRYPOINT from the OCI config
|
||||||
|
MANIFEST_DIGEST=$(jq -r '.manifests[0].digest' index.json | sed 's/sha256://')
|
||||||
|
CONFIG_DIGEST=$(jq -r '.config.digest' "sha256:${MANIFEST_DIGEST}" | sed 's/sha256://')
|
||||||
|
cp "sha256:${CONFIG_DIGEST}" config.json
|
||||||
|
# Clean up OCI artifacts
|
||||||
|
rm -f image.tar index.json manifest.json oci-layout sha256:*
|
||||||
|
cd /tmp
|
||||||
|
done
|
||||||
|
|
||||||
|
# Generate Dockerfile with metadata from the OCI config
|
||||||
|
# (use amd64 config as reference — env vars are the same for both arches)
|
||||||
|
ENV_LINES=$(jq -r '(.config.Env // [])[] | "ENV " + .' /tmp/build-amd64/config.json)
|
||||||
|
ENTRYPOINT=$(jq -r '(.config.Entrypoint // [])[]' /tmp/build-amd64/config.json | head -1)
|
||||||
|
USER_ID=$(jq -r '.config.User // "65532"' /tmp/build-amd64/config.json)
|
||||||
|
WORKDIR=$(jq -r '.config.WorkingDir // "/"' /tmp/build-amd64/config.json)
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "FROM scratch"
|
||||||
|
echo "ARG TARGETARCH"
|
||||||
|
echo "ADD build-\${TARGETARCH}/rootfs.tar.gz /"
|
||||||
|
if [ -n "$ENV_LINES" ]; then
|
||||||
|
echo "$ENV_LINES"
|
||||||
|
fi
|
||||||
|
if [ -n "$ENTRYPOINT" ] && [ "$ENTRYPOINT" != "null" ]; then
|
||||||
|
echo "ENTRYPOINT [\"${ENTRYPOINT}\"]"
|
||||||
|
fi
|
||||||
|
echo "WORKDIR ${WORKDIR}"
|
||||||
|
echo "USER ${USER_ID}"
|
||||||
|
} > /tmp/Dockerfile
|
||||||
|
|
||||||
- name: Build and push with buildx (SBOM + provenance)
|
- name: Build and push with buildx (SBOM + provenance)
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
|
|||||||
@ -114,13 +114,45 @@ jobs:
|
|||||||
apko build --arch aarch64 ${{ matrix.config }} \
|
apko build --arch aarch64 ${{ matrix.config }} \
|
||||||
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest \
|
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-latest \
|
||||||
/tmp/build-arm64/image.tar
|
/tmp/build-arm64/image.tar
|
||||||
cat > /tmp/Dockerfile <<'EOF'
|
|
||||||
FROM scratch
|
# Extract the rootfs layer from the OCI archive for each arch.
|
||||||
ARG TARGETARCH
|
# apko outputs an OCI image tarball; we need to extract just the
|
||||||
ADD build-${TARGETARCH}/image.tar /
|
# filesystem layer (.tar.gz) and the config metadata.
|
||||||
USER 65532
|
for arch in amd64 arm64; do
|
||||||
EOF
|
cd /tmp/build-${arch}
|
||||||
sed -i 's/^ //' /tmp/Dockerfile
|
tar xf image.tar
|
||||||
|
# The .tar.gz file is the filesystem layer
|
||||||
|
ROOTFS=$(ls *.tar.gz 2>/dev/null | head -1)
|
||||||
|
mv "$ROOTFS" rootfs.tar.gz
|
||||||
|
# Extract ENV and ENTRYPOINT from the OCI config
|
||||||
|
MANIFEST_DIGEST=$(jq -r '.manifests[0].digest' index.json | sed 's/sha256://')
|
||||||
|
CONFIG_DIGEST=$(jq -r '.config.digest' "sha256:${MANIFEST_DIGEST}" | sed 's/sha256://')
|
||||||
|
cp "sha256:${CONFIG_DIGEST}" config.json
|
||||||
|
# Clean up OCI artifacts
|
||||||
|
rm -f image.tar index.json manifest.json oci-layout sha256:*
|
||||||
|
cd /tmp
|
||||||
|
done
|
||||||
|
|
||||||
|
# Generate Dockerfile with metadata from the OCI config
|
||||||
|
# (use amd64 config as reference — env vars are the same for both arches)
|
||||||
|
ENV_LINES=$(jq -r '(.config.Env // [])[] | "ENV " + .' /tmp/build-amd64/config.json)
|
||||||
|
ENTRYPOINT=$(jq -r '(.config.Entrypoint // [])[]' /tmp/build-amd64/config.json | head -1)
|
||||||
|
USER_ID=$(jq -r '.config.User // "65532"' /tmp/build-amd64/config.json)
|
||||||
|
WORKDIR=$(jq -r '.config.WorkingDir // "/"' /tmp/build-amd64/config.json)
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "FROM scratch"
|
||||||
|
echo "ARG TARGETARCH"
|
||||||
|
echo "ADD build-\${TARGETARCH}/rootfs.tar.gz /"
|
||||||
|
if [ -n "$ENV_LINES" ]; then
|
||||||
|
echo "$ENV_LINES"
|
||||||
|
fi
|
||||||
|
if [ -n "$ENTRYPOINT" ] && [ "$ENTRYPOINT" != "null" ]; then
|
||||||
|
echo "ENTRYPOINT [\"${ENTRYPOINT}\"]"
|
||||||
|
fi
|
||||||
|
echo "WORKDIR ${WORKDIR}"
|
||||||
|
echo "USER ${USER_ID}"
|
||||||
|
} > /tmp/Dockerfile
|
||||||
|
|
||||||
- name: Build and push with buildx (SBOM + provenance)
|
- name: Build and push with buildx (SBOM + provenance)
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user