Skip to content

Commit

Permalink
Corrected for JVM crash by using more robust LTS JRE base image, sabi…
Browse files Browse the repository at this point in the history
…ng 200MB in final image size
  • Loading branch information
Colin Hill committed Feb 8, 2025
1 parent 42f10c3 commit 5d439e2
Showing 1 changed file with 117 additions and 104 deletions.
221 changes: 117 additions & 104 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,109 +24,110 @@ COPY ext/patches/signal-cli-native-arch.patch /tmp/signal-cli-native-arch.patch
RUN arch="$(uname -m)"; \
case "$arch" in \
aarch64) cp /tmp/libsignal-client-libraries/arm64/libsignal_jni.so /tmp/libsignal_jni.so ;; \
armv7l) cp /tmp/libsignal-client-libraries/armv7/libsignal_jni.so /tmp/libsignal_jni.so ;; \
armv7l) cp /tmp/libsignal-client-libraries/armv7/libsignal_jni.so /tmp/libsignal_jni.so ;; \
x86_64) cp /tmp/libsignal-client-libraries/x86-64/libsignal_jni.so /tmp/libsignal_jni.so ;; \
*) echo "Unknown architecture" && exit 1 ;; \
*) echo "Unknown architecture" && exit 1 ;; \
esac;

RUN dpkg-reconfigure debconf --frontend=noninteractive \
&& apt-get -qq update \
&& apt-get -qqy install --no-install-recommends \
wget software-properties-common git locales zip unzip \
file build-essential libz-dev zlib1g-dev < /dev/null > /dev/null \
&& rm -rf /var/lib/apt/lists/*

RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
apt-utils \
wget \
software-properties-common \
git \
locales \
zip \
unzip \
file \
build-essential \
libz-dev \
zlib1g-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
&& dpkg-reconfigure --frontend=noninteractive locales \
&& update-locale LANG=en_US.UTF-8

ENV JAVA_OPTS="-Djdk.lang.Process.launchMechanism=vfork"

ENV LANG en_US.UTF-8
ENV LANG=en_US.UTF-8

RUN cd /tmp/ \
&& git clone https://github.com/swaggo/swag.git swag-${SWAG_VERSION} \
&& cd swag-${SWAG_VERSION} \
&& git checkout -q v${SWAG_VERSION} \
&& make -s < /dev/null > /dev/null \
&& cp /tmp/swag-${SWAG_VERSION}/swag /usr/bin/swag \
&& rm -r /tmp/swag-${SWAG_VERSION}
&& git clone https://github.com/swaggo/swag.git swag-${SWAG_VERSION} \
&& cd swag-${SWAG_VERSION} \
&& git checkout -q v${SWAG_VERSION} \
&& make -s < /dev/null > /dev/null \
&& cp /tmp/swag-${SWAG_VERSION}/swag /usr/bin/swag \
&& rm -r /tmp/swag-${SWAG_VERSION}

RUN cd /tmp/ \
&& wget -nv https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}.tar.gz -O /tmp/signal-cli.tar.gz \
&& tar xf signal-cli.tar.gz
&& wget -nv https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}.tar.gz -O /tmp/signal-cli.tar.gz \
&& tar xf signal-cli.tar.gz

# build native image with graalvm

RUN arch="$(uname -m)"; \
case "$arch" in \
aarch64) wget -nv https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_linux-aarch64_bin.tar.gz -O /tmp/gvm.tar.gz ;; \
armv7l) echo "GRAALVM doesn't support 32bit" ;; \
x86_64) wget -nv https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${GRAALVM_VERSION}/graalvm-community-jdk-${GRAALVM_VERSION}_linux-x64_bin.tar.gz -O /tmp/gvm.tar.gz ;; \
*) echo "Invalid architecture" ;; \
*) echo "Invalid architecture" ;; \
esac;

RUN if [ "$(uname -m)" = "x86_64" ]; then \
cd /tmp \
&& git clone https://github.com/AsamK/signal-cli.git signal-cli-${SIGNAL_CLI_VERSION}-source \
&& cd signal-cli-${SIGNAL_CLI_VERSION}-source \
&& git checkout -q v${SIGNAL_CLI_VERSION} \
&& cd /tmp && mkdir -p /tmp/graalvm && tar xf gvm.tar.gz -C /tmp/graalvm --strip-components=1 \
&& export GRAALVM_HOME=/tmp/graalvm \
&& export PATH=/tmp/graalvm/bin:$PATH \
&& cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \
&& sed -i 's/Signal-Android\/5.22.3/Signal-Android\/5.51.7/g' src/main/java/org/asamk/signal/BaseConfig.java \
&& ./gradlew build \
&& ./gradlew installDist \
&& ls build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar || (echo "\n\nsignal-client jar file with version ${LIBSIGNAL_CLIENT_VERSION} not found. Maybe the version needs to be bumped in the signal-cli-rest-api Dockerfile?\n\n" && echo "Available version: \n" && ls build/install/signal-cli/lib/libsignal-client-* && echo "\n\n" && exit 1) \
&& cd /tmp \
&& cp signal-cli-${SIGNAL_CLI_VERSION}-source/build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar libsignal-client.jar \
&& zip -qu libsignal-client.jar libsignal_jni.so \
&& cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \
&& git apply /tmp/signal-cli-native.patch \
&& git apply /tmp/signal-cli-native-arch.patch \
&& ./gradlew -q nativeCompile; \
elif [ "$(uname -m)" = "aarch64" ] ; then \
echo "Use native image from @morph027 (https://packaging.gitlab.io/signal-cli/) for arm64 - many thanks to @morph027" \
&& curl -fsSL https://packaging.gitlab.io/signal-cli/gpg.key | apt-key add - \
&& echo "deb https://packaging.gitlab.io/signal-cli focal main" > /etc/apt/sources.list.d/morph027-signal-cli.list \
&& mkdir -p /tmp/signal-cli-native \
&& cd /tmp/signal-cli-native \
#&& wget https://gitlab.com/packaging/signal-cli/-/jobs/3716873649/artifacts/download?file_type=archive -O /tmp/signal-cli-native/archive.zip \
#&& unzip archive.zip \
#&& mv signal-cli-native-arm64/*deb . \
&& apt-get -qq update \
&& apt-get -qq download signal-cli-native=${SIGNAL_CLI_NATIVE_PACKAGE_VERSION} < /dev/null > /dev/null \
&& ar x *.deb \
&& tar xf data.tar.gz \
&& mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \
&& cp /tmp/signal-cli-native/usr/bin/signal-cli-native /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \
cd /tmp \
&& git clone https://github.com/AsamK/signal-cli.git signal-cli-${SIGNAL_CLI_VERSION}-source \
&& cd signal-cli-${SIGNAL_CLI_VERSION}-source \
&& git checkout -q v${SIGNAL_CLI_VERSION} \
&& cd /tmp && mkdir -p /tmp/graalvm && tar xf gvm.tar.gz -C /tmp/graalvm --strip-components=1 \
&& export GRAALVM_HOME=/tmp/graalvm \
&& export PATH=/tmp/graalvm/bin:$PATH \
&& cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \
&& sed -i 's/Signal-Android\/5.22.3/Signal-Android\/5.51.7/g' src/main/java/org/asamk/signal/BaseConfig.java \
&& ./gradlew build \
&& ./gradlew installDist \
&& ls build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar || (echo "\n\nsignal-client jar file with version ${LIBSIGNAL_CLIENT_VERSION} not found. Maybe the version needs to be bumped in the signal-cli-rest-api Dockerfile?\n\n" && echo "Available version: \n" && ls build/install/signal-cli/lib/libsignal-client-* && echo "\n\n" && exit 1) \
&& cd /tmp \
&& cp signal-cli-${SIGNAL_CLI_VERSION}-source/build/install/signal-cli/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar libsignal-client.jar \
&& zip -qu libsignal-client.jar libsignal_jni.so \
&& cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source \
&& git apply /tmp/signal-cli-native.patch \
&& git apply /tmp/signal-cli-native-arch.patch \
&& ./gradlew -q nativeCompile; \
elif [ "$(uname -m)" = "aarch64" ] ; then \
echo "Use native image from @morph027 (https://packaging.gitlab.io/signal-cli/) for arm64 - many thanks to @morph027" \
&& curl -fsSL https://packaging.gitlab.io/signal-cli/gpg.key | apt-key add - \
&& echo "deb https://packaging.gitlab.io/signal-cli focal main" > /etc/apt/sources.list.d/morph027-signal-cli.list \
&& mkdir -p /tmp/signal-cli-native \
&& cd /tmp/signal-cli-native \
&& apt-get update \
&& apt-get -qq download signal-cli-native=${SIGNAL_CLI_NATIVE_PACKAGE_VERSION} < /dev/null > /dev/null \
&& ar x *.deb \
&& tar xf data.tar.gz \
&& mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \
&& cp /tmp/signal-cli-native/usr/bin/signal-cli-native /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \
elif [ "$(uname -m)" = "armv7l" ] ; then \
echo "GRAALVM doesn't support 32bit" \
&& echo "Creating temporary file, otherwise the below copy doesn't work for armv7" \
&& mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \
&& touch /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \
echo "GRAALVM doesn't support 32bit" \
&& echo "Creating temporary file, otherwise the below copy doesn't work for armv7" \
&& mkdir -p /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile \
&& touch /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli; \
else \
echo "Unknown architecture"; \
echo "Unknown architecture"; \
fi;

# replace libsignal-client

RUN ls /tmp/signal-cli-${SIGNAL_CLI_VERSION}/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar || (echo "\n\nsignal-client jar file with version ${LIBSIGNAL_CLIENT_VERSION} not found. Maybe the version needs to be bumped in the signal-cli-rest-api Dockerfile?\n\n" && echo "Available version: \n" && ls /tmp/signal-cli-${SIGNAL_CLI_VERSION}/lib/libsignal-client-* && echo "\n\n" && exit 1)

# workaround until upstream is fixed
RUN cd /tmp/signal-cli-${SIGNAL_CLI_VERSION}/lib \
&& unzip signal-cli-${SIGNAL_CLI_VERSION}.jar \
&& sed -i 's/Signal-Android\/5.22.3/Signal-Android\/5.51.7/g' org/asamk/signal/BaseConfig.class \
&& zip -r signal-cli-${SIGNAL_CLI_VERSION}.jar org/ META-INF/ \
&& rm -rf META-INF \
&& rm -rf org
&& unzip signal-cli-${SIGNAL_CLI_VERSION}.jar \
&& sed -i 's/Signal-Android\/5.22.3/Signal-Android\/5.51.7/g' org/asamk/signal/BaseConfig.class \
&& zip -r signal-cli-${SIGNAL_CLI_VERSION}.jar org/ META-INF/ \
&& rm -rf META-INF \
&& rm -rf org

RUN cd /tmp/ \
&& zip -qu /tmp/signal-cli-${SIGNAL_CLI_VERSION}/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar libsignal_jni.so \
&& zip -qr signal-cli-${SIGNAL_CLI_VERSION}.zip signal-cli-${SIGNAL_CLI_VERSION}/* \
&& zip -qu /tmp/signal-cli-${SIGNAL_CLI_VERSION}/lib/libsignal-client-${LIBSIGNAL_CLIENT_VERSION}.jar libsignal_jni.so \
&& zip -qr signal-cli-${SIGNAL_CLI_VERSION}.zip signal-cli-${SIGNAL_CLI_VERSION}/* \
&& unzip -q /tmp/signal-cli-${SIGNAL_CLI_VERSION}.zip -d /opt \
&& rm -f /tmp/signal-cli-${SIGNAL_CLI_VERSION}.zip
&& rm -f /tmp/signal-cli-${SIGNAL_CLI_VERSION}.zip

COPY src/api /tmp/signal-cli-rest-api-src/api
COPY src/client /tmp/signal-cli-rest-api-src/client
Expand All @@ -138,40 +139,52 @@ COPY src/go.mod /tmp/signal-cli-rest-api-src/
COPY src/go.sum /tmp/signal-cli-rest-api-src/
COPY src/plugin_loader.go /tmp/signal-cli-rest-api-src/

# build signal-cli-rest-api
RUN ls -la /tmp/signal-cli-rest-api-src
RUN cd /tmp/signal-cli-rest-api-src && swag init
RUN cd /tmp/signal-cli-rest-api-src && go build -o signal-cli-rest-api main.go
RUN cd /tmp/signal-cli-rest-api-src && go test ./client -v

# build supervisorctl_config_creator
RUN cd /tmp/signal-cli-rest-api-src/scripts && go build -o jsonrpc2-helper

# build plugin_loader
RUN cd /tmp/signal-cli-rest-api-src/scripts && go build -o jsonrpc2-helper
RUN cd /tmp/signal-cli-rest-api-src && go build -buildmode=plugin -o signal-cli-rest-api_plugin_loader.so plugin_loader.go

# Start a fresh container for release container
FROM eclipse-temurin:21-jre AS release-amd64
FROM eclipse-temurin:21-jre AS release-arm64
FROM ubuntu:jammy AS release-armv7

# eclipse-temurin doesn't provide a OpenJDK 21 image for armv7 (see https://github.com/adoptium/containers/issues/502). Until this
# is fixed we use the standard ubuntu image
#FROM eclipse-temurin:21-jre-jammy

FROM ubuntu:jammy
# Final stage - will automatically select the appropriate base image
FROM release-${TARGETARCH} AS final

ENV GIN_MODE=release

ENV PORT=8080

ARG SIGNAL_CLI_VERSION
ARG BUILD_VERSION_ARG
ARG TARGETARCH

ENV BUILD_VERSION=$BUILD_VERSION_ARG
ENV SIGNAL_CLI_REST_API_PLUGIN_SHARED_OBJ_DIR=/usr/bin/

RUN dpkg-reconfigure debconf --frontend=noninteractive \
&& apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends util-linux supervisor netcat openjdk-21-jre curl locales < /dev/null > /dev/null \
&& rm -rf /var/lib/apt/lists/*
# Install required packages
RUN if [ "${TARGETARCH}" = "armv7" ]; then \
apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends openjdk-21-jre \
&& groupadd -g 1000 signal-api \
&& useradd --no-log-init -M -d /home -s /bin/bash -u 1000 -g 1000 signal-api; \
else \
# For amd64 and arm64, rename existing user to signal-api
existing_user=$(getent passwd 1000 | cut -d: -f1) \
&& if [ -n "$existing_user" ] && [ "$existing_user" != "signal-api" ]; then \
usermod -l signal-api "$existing_user" \
&& groupmod -n signal-api $(getent group 1000 | cut -d: -f1); \
fi; \
fi \
&& apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends \
util-linux \
supervisor \
netcat-traditional \
curl \
locales \
&& rm -rf /var/lib/apt/lists/*

COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/signal-cli-rest-api /usr/bin/signal-cli-rest-api
COPY --from=buildcontainer /opt/signal-cli-${SIGNAL_CLI_VERSION} /opt/signal-cli-${SIGNAL_CLI_VERSION}
Expand All @@ -180,25 +193,25 @@ COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/scripts/jsonrpc2-helper
COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/signal-cli-rest-api_plugin_loader.so /usr/bin/signal-cli-rest-api_plugin_loader.so
COPY entrypoint.sh /entrypoint.sh

# Set up directories and symlinks
RUN ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli /usr/bin/signal-cli \
&& ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native /usr/bin/signal-cli-native \
&& mkdir -p /signal-cli-config/ \
&& mkdir -p /home/.local/share/signal-cli \
&& chown -R signal-api:signal-api /home/.local/share/signal-cli /signal-cli-config

RUN groupadd -g 1000 signal-api \
&& useradd --no-log-init -M -d /home -s /bin/bash -u 1000 -g 1000 signal-api \
&& ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli /usr/bin/signal-cli \
&& ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native /usr/bin/signal-cli-native \
&& mkdir -p /signal-cli-config/ \
&& mkdir -p /home/.local/share/signal-cli

# remove the temporary created signal-cli-native on armv7, as GRAALVM doesn't support 32bit
RUN arch="$(uname -m)"; \
case "$arch" in \
armv7l) echo "GRAALVM doesn't support 32bit" && rm /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native /usr/bin/signal-cli-native ;; \
esac;
# Remove signal-cli-native on armv7 as GRAALVM doesn't support 32bit
RUN if [ "${TARGETARCH}" = "armv7" ]; then \
echo "GRAALVM doesn't support 32bit" \
&& rm /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native /usr/bin/signal-cli-native; \
fi

# Set up locale
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8

ENV LANG en_US.UTF-8
ENV LANG=en_US.UTF-8

EXPOSE ${PORT}

Expand Down

0 comments on commit 5d439e2

Please sign in to comment.