Tuesday, September 13, 2022

tar hanging when extracting an archive during a Docker build

Consider the following excerpt of a Dockerfile building nginx: 

RUN \
mkdir -p /usr/src/ngx_brotli \
&& cd /usr/src/ngx_brotli \
&& git init \
&& git remote add origin https://github.com/google/ngx_brotli.git \
&& git fetch --depth 1 origin $NGX_BROTLI_COMMIT \
&& git checkout --recurse-submodules -q FETCH_HEAD \
&& git submodule update --init --depth 1 \
&& cd .. \
&& curl -fSL https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \
&& curl -fSL https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz.asc  -o nginx.tar.gz.asc \
        && sha512sum nginx.tar.gz nginx.tar.gz.asc \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --keyserver keyserver.ubuntu.com --recv-keys 13C82A63B603576156E30A4EA0EA981B66B0D967 \
&& gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz \
        && rm -rf "$GNUPGHOME" \
&& tar -C /usr/src -vxzf nginx.tar.gz

Looks pretty simple, right? Yet it's hanging. Halfway through the archive extraction, tar goes into an endless busyloop:

root@docker-desktop:/# strace -fp 29116
strace: Process 29116 attached
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
wait4(-1, 0x7ffff15dcf24, WNOHANG, NULL) = 0
[...]

More interestingly, I couldn't reproduce this by manually running the shell commands one by one in an identical interactive container.

I realized that the gpg --recv-keys call left behind a couple process, dirmngr and gpg-agent, and that those appear to be the culprits (for reasons not yet clear to me).

Easiest way to "fix" this was to ask them to terminate by deleting the $GNUPGHOME directory (which dirmngr watches with inotify).

Just posting this here in case anyone else ever gets puzzled the way I did.