dockermultiarch

How to extract files from docker multi-arch images?


I'd like to use docker as tool to compile (ningx) modules for multiple architectures (x86-64 and ARM).

I got my Dockerfile working and it's building each multi-arch image ok but I can't figure out hot to extract (copy) the compiled libraries out of each docker image without actually running the containers and since I can't run the arm image on my local laptop I'm stuck.

Does anyone have a simple/clever way of doing it?

Thanks in advance


Solution

  • You can export content from an image directly in the build command, telling docker to output to a filesystem instead of outputting to an image:

    FROM base as build
    RUN build commands here
    
    FROM scratch as artifact
    COPY --from=build /usr/local/bin/app /app
    
    FROM runtime as release
    COPY --from=build /usr/local/bin/app /usr/local/bin/app
    ENTRYPOINT ["/usr/local/bin/app"]
    

    Then build with:

    docker build --target=artifact --output type=local,dest=out/ .
    

    Which would create an out/app.

    The other options include pulling files directly out of the image tar blobs, or doing a docker create and docker cp to copy files out of your image. To pull files directly out of the blob, you would need to know which layer contains the files, and then pull that blob, extracting through tar:

    $ regctl manifest get localhost:5000/library/alpine \
        --platform linux/amd64 --format '{{jsonPretty .}}'
    {
      "schemaVersion": 2,
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "config": {
        "mediaType": "application/vnd.docker.container.image.v1+json",
        "size": 1472,
        "digest": "sha256:e66264b98777e12192600bf9b4d663655c98a090072e1bab49e233d7531d1294"
      },
      "layers": [
        {
          "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
          "size": 2798889,
          "digest": "sha256:2408cc74d12b6cd092bb8b516ba7d5e290f485d3eb9672efc00f0583730179e8"
        }
      ]
    }
    
    $ regctl blob get localhost:5000/library/alpine sha256:2408cc74d12b6cd092bb8b516ba7d5e290f485d3eb9672efc00f0583730179e8 | tar -tvzf - | head -20
    drwxr-xr-x 0/0               0 2022-05-23 12:51 bin/
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/arch -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/ash -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/base64 -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/bbconfig -> /bin/busybox
    -rwxr-xr-x 0/0          837272 2022-05-09 13:27 bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/cat -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/chattr -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/chgrp -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/chmod -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/chown -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/cp -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/date -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/dd -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/df -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/dmesg -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/dnsdomainname -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/dumpkmap -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/echo -> /bin/busybox
    lrwxrwxrwx 0/0               0 2022-05-23 12:51 bin/ed -> /bin/busybox