We have the following Dockerfile (I have removed the unecessary parts) which we have used for well over a year now and suddenly, when it gets to the gpg --batch --verify...
step the build hangs during CodeBuild and ultimately times out. I have been researching for the past few days, but I cannot find anything related.
FROM amazoncorretto:11-alpine-jdk
ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
ENV TZ America/New_York
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ /etc/timezone
WORKDIR /usr/local/tomee
# add the things we need to build the image
RUN apk update \
&& apk add sudo \
&& apk add tar \
&& apk add gpg \
&& apk add curl \
&& apk add gpg-agent \
&& apk add bash
# add the users and sudo for Lacework
RUN adduser -S tomee
RUN addgroup tomee \
&& addgroup tomee tomee
RUN addgroup sudo \
&& addgroup tomee sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# download and import the GPG keys
RUN set -x \
&& curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' -o GPG_KEYS | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u \
&& gpg --import GPG_KEYS
# verify keys
RUN set -xe \
&& for key in $GPG_KEYS; do \
gpg --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" || \
gpg --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys "$key" ; \
done
# TOMEE variables
# Apache changes the version from time to time and removes the old version.
# When they do that, you have to go to https://dist.apache.org/repos/dist/release/tomee/ to what see version is available
# then match that here
ENV TOMEE_VER 8.0.15
ENV TOMEE_BUILD webprofile
# set up Apache/TOMEE
RUN set -x \
&& curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc \
&& curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz \
&& echo "verifying gpg signature" \
&& gpg --list-keys \
&& gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz \
&& tar -zxf tomee.tar.gz \
&& mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee \
&& rm -Rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} \
&& rm -Rf /usr/local/tomee/webapps/docs \
&& rm bin/*.bat \
&& rm tomee.tar.gz* \
&& chown -R tomee:tomee /usr/local/tomee
# put everything in the right place with the correct permissions
COPY $PWD/server.xml /usr/local/tomee/conf/
RUN chown -R tomee:tomee /usr/local/tomee/conf
COPY $PWD/target/application/META-INF/ /usr/local/tomee/webapps/ROOT/META-INF/
COPY $PWD/target/application/WEB-INF/ /usr/local/tomee/webapps/ROOT/WEB-INF/
COPY $PWD/target/application.war /usr/local/tomee/webapps/ROOT.war
RUN chown -R tomee:tomee /usr/local/tomee/webapps/
USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]
To replicate this, I set up an EC2 instance and installed Docker on the instance. Here is where the build hangs:
+ curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz.asc -o tomee.tar.gz.asc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 833 100 833 0 0 17455 0 --:--:-- --:--:-- --:--:-- 17723
+ curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz -o tomee.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 47.4M 100 47.4M 0 0 118M 0 --:--:-- --:--:-- --:--:-- 118M
+ echo 'verifying gpg signature'
verifying gpg signature
+ gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz
gpg: Signature made Mon May 8 12:36:19 2023 UTC
gpg: using RSA key B83D15E72253ED1104EB4FBBDAB472F0E5B8A431
If I comment out the batch verify, the build completes successfully.
REPOSITORY TAG IMAGE ID CREATED SIZE
gpg-test latest 1aead64a5120 12 seconds ago 350MB
amazoncorretto 11-alpine-jdk 60ba21c1871e 2 weeks ago 274MB
Now I can run the image. When I bash into the image I can see the GPG_KEYS
file so I run the import:
gpg --import GPG_KEYS
That works properly, so I get the Apache-Tomee downloads:
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz.asc -o tomee.tar.gz.asc
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-8.0.15/apache-tomee-8.0.15-webprofile.tar.gz -o tomee.tar.gz
So the container now has the files and I run the batch verify command manually and it completes successfully:
5ab9673fdbe2:/usr/local/tomee$ gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz
gpg: Signature made Mon May 8 12:36:19 2023 UTC
gpg: using RSA key B83D15E72253ED1104EB4FBBDAB472F0E5B8A431
gpg: Good signature from "Richard Zowalla (Code Signing Key) <rzo1@apache.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: B83D 15E7 2253 ED11 04EB 4FBB DAB4 72F0 E5B8 A431
Why is gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz
failing during the building of the image?
As a side note: one of our developers is running Docker Desktop and his build process hangs at the exact same spot. Others who are building the images with Lima (https://itnext.io/replace-docker-desktop-with-lima-88ec6f9d6a19) do not encounter the problem so it leads me to believe that something in the Docker eco-system is causing an issue.
Have I missed anything obvious?
UPDATE
I added gpg --list-keys
to the Dockerfile immediately above the batch verify line and it hangs at the list-keys
command. All of the other GPG commands work prior to that.
I added the -v
to the list keys command and I am getting the following:
verifying gpg signature
+ gpg --list-keys -v
gpg: enabled compatibility flags:
gpg: using pgp trust model
gpg: no running keyboxd - starting '/usr/libexec/keyboxd'
gpg: waiting for the keyboxd to come up ... (5s)
UPDATE
I have solved the keyboxd issue by adding && export GNUPGHOME="$(mktemp -d)" \
prior to any GPG command.
I believe I have isolated the issue to this line:
&& gpg --import GPG_KEYS
The import occurs, but when I try to loop through the keys there is no $GPG_KEYS
environment variable, so there is no public key available. You can see here that the OP actually spells out the key listing in the Dockerfile, but that seems inefficient to me. Running TomEE API in Docker container successful, but reverse proxy returns a 404
YET ANOTHER UPDATE I have been fiddling with this quite a bit today and finally was able to cleanly get the GPG keys exported to an ENV variable as you can see here:
+ export 'GPG_KEYS=/tmp/tmp.hoJlmJ/pubring.kbx
---------------------------
pub dsa1024 2006-01-05 [SC]
9056B710F1E332780DE7AF34CBAEBE39A46C4CA1
uid [ unknown] Some Dude <somedude@apache.org>
sub elg2048 2006-01-05 [E]
pub rsa2048 2014-01-21 [SC]
F067B8140F5DD80E1D3B5D92318242FE9A0B1183
uid [ unknown] Another Dude <anotherdudek@apache.org>
sub rsa2048 2014-01-21 [E]
...and so on
Running printenv
inside the image build shows the keys
+ printenv
HOSTNAME=756af5d791b0
SHLVL=1
HOME=/root
GPG_KEYS=/tmp/tmp.hoJlmJ/pubring.kbx
---------------------------
pub dsa1024 2006-01-05 [SC]
9056B710F1E332780DE7AF34CBAEBE39A46C4CA1
uid [ unknown] Some Dude <somedude@apache.org>
sub elg2048 2006-01-05 [E]
pub rsa2048 2014-01-21 [SC]
F067B8140F5DD80E1D3B5D92318242FE9A0B1183
uid [ unknown] Another Dude <anotherdudek@apache.org>
sub rsa2048 2014-01-21 [E]
...and so on
When I run the next command manually, it works. But running it in the Dockerfile fails (we should see output)
Step 13/21 : RUN set -xe && for key in $GPG_KEYS; do gpg -v --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" ; done
None of the output I would expect from the --keyserver
command is present.
We continued to research and set up a support request (unanswered) with AWS for why GPG started failing in Dockerfiles in CodeBuild.
All of the testing mentioned led to one conclusion, GPG calls worked properly from the command line on an EC2 instance and within a Docker container on that instance. Given that, we moved all of the GPG commands to a bash file, which is then called in the Dockerfile:
gpg-verify.sh
#!/bin/bash
# download and import the GPG keys
export GNUPGHOME="$(mktemp -d)"
curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' -o GPG_KEYS | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u
gpg --batch --import GPG_KEYS
export GPG_KEYS="$(gpg --list-keys)"
printenv
# verify keys
for key in $GPG_KEYS; do
gpg -v --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" ;
done
# set up Apache/TOMEE
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc
curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz
gpg --list-keys -v
gpg -v --batch --verify tomee.tar.gz.asc tomee.tar.gz
Updated Dockerfile:
FROM amazoncorretto:11-alpine-jdk
ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
ENV TZ America/New_York
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ /etc/timezone
WORKDIR /usr/local/tomee
# add the things we need to build the image
RUN apk update \
&& apk add sudo \
&& apk add tar \
&& apk add gnupg \
&& apk add curl \
&& apk add gpg-agent \
&& apk add bash \
&& apk add ca-certificates
# add the users and sudo for Lacework
RUN adduser -S tomee
RUN addgroup tomee \
&& addgroup tomee tomee
RUN addgroup sudo \
&& addgroup tomee sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# TOMEE variables
# Apache changes the version from time to time and removes the old version.
# When they do that, you have to go to https://dist.apache.org/repos/dist/release/tomee/ to what see version is available
# then match that here
ENV TOMEE_VER 8.0.15
ENV TOMEE_BUILD webprofile
# GPG Verification / TOMEE Download
COPY $PWD/gpg-verify.sh .
RUN ./gpg-verify.sh
RUN set -x \
&& tar -zxf tomee.tar.gz \
&& mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee \
&& rm -Rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} \
&& rm -Rf /usr/local/tomee/webapps/docs \
&& rm bin/*.bat \
&& rm tomee.tar.gz* \
&& chown -R tomee:tomee /usr/local/tomee
# put everything in the right place with the correct permissions
#COPY $PWD/server.xml /usr/local/tomee/conf/
RUN chown -R tomee:tomee /usr/local/tomee/conf
#COPY $PWD/target/application/META-INF/ /usr/local/tomee/webapps/ROOT/META-INF/
#COPY $PWD/target/application/WEB-INF/ /usr/local/tomee/webapps/ROOT/WEB-INF/
#COPY $PWD/target/application.war /usr/local/tomee/webapps/ROOT.war
RUN chown -R tomee:tomee /usr/local/tomee/webapps/
USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]
This, of course, seems quite counter-intuitive as the bash commands are the same commands that were being run within the Dockerfile. However, this works as we expect.
P.S. We have asked AWS about changes that would've caused the issues with GPG and will update this when a response is provided.