Search code examples
dockertardocker-rundocker-exec

Piping tar archive to host fails on docker run but works on docker exec


I'm trying to get some libraries out of a Docker image, since I temporarily need it in another environment.

Since I need symlinks to persist through this, I'm trying to tar the directory and pipe it to my hot system to immediately untar it there. In the end I want to pipe them directly into a running Kubernetes Pod.

Since I don't have any environment running with the image, that I need the files from, I tried to do the following:

docker run --rm bitnami/postgresql:11.22.0-debian-11-r4 \
    tar cf - -C /usr/lib/x86_64-linux-gnu . | tar xf -

This results in

tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors
write /dev/stdout: broken pipe

But when I do this in an already running container it works.

Start a docker container with the image and open a bash (so it does not start the postgres service but stays alive):

docker run --rm -it --name my-postgresql bitnami/postgresql:11.22.0-debian-11-r4 -- bash

No open up a new terminal on your host and execute the following:

docker exec my-postgresql \
    tar cf - -C /usr/lib/x86_64-linux-gnu/ . |\
    tar xf -

This works like a charm.

Can anyone explain to me, what I do wrong in the former example? Thanks in advance!


Solution

  • The bitnami postgres image includes an ENTRYPOINT script:

    $ docker image inspect bitnami/postgresql:11.22.0-debian-11-r4   -f '{{ .Config.Entrypoint }}'
    [/opt/bitnami/scripts/postgresql/entrypoint.sh]
    

    That script produces some output on stdout before tar produces any output; this results in data that can't be processed by the reading tar command. You can avoid that problem by replacing the entrypoint:

    docker run --rm --entrypoint tar bitnami/postgresql:11.22.0-debian-11-r4 \
      cf - -C /usr/lib/x86_64-linux-gnu . |
      tar xf -