Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 50 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ ARG SWAG_VERSION=1.16.4
ARG GRAALVM_VERSION=21.0.0
#ARG GRAALVM_VERSION=25.0.2

ARG S6_OVERLAY_VERSION=v3.2.2.0

ARG BUILD_VERSION_ARG=unset

FROM golang:1.24-bookworm AS buildcontainer
Expand Down Expand Up @@ -42,7 +44,7 @@ RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \

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} \
Expand Down Expand Up @@ -154,42 +156,61 @@ 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 debian:trixie-slim

# 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

ARG TARGETARCH # set by buildx
ARG SIGNAL_CLI_VERSION
ARG BUILD_VERSION_ARG
ENV GIN_MODE=release

ENV PORT=8080
# Set environment variables to keep the image clean
ENV DEBIAN_FRONTEND=noninteractive

ARG SIGNAL_CLI_VERSION
ARG BUILD_VERSION_ARG
ENV PORT=8080

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 update \
&& apt-get install -y --no-install-recommends util-linux supervisor netcat openjdk-21-jre curl locales \
RUN apt-get update \
&& apt-get install -y --no-install-recommends netcat-traditional openjdk-21-jre curl locales xz-utils\
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN if [ -z "$TARGETARCH" ]; then \
# Fallback for older Docker versions not using BuildKit
TARGETARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/'); \
else \
echo "Building for architecture: $TARGETARCH"; \
fi;

# install s6-overlay as service control system
RUN curl -fL -o /tmp/s6-overlay-noarch.tar.xz \
"https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" && \
tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \
if [ "$TARGETARCH" = "amd64" ]; then S6_ARCH="x86_64"; \
elif [ "$TARGETARCH" = "arm64" ]; then S6_ARCH="aarch64"; \
elif [ "$TARGETARCH" = "arm" ]; then S6_ARCH="arm"; \
else S6_ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/'); fi;\
curl -fL -o /tmp/s6-overlay-bin.tar.xz \
"https://github.com/just-containers/s6-overlay/releases/download/${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz" && \
tar -C / -Jxpf /tmp/s6-overlay-bin.tar.xz && \
rm /tmp/s6-overlay-*.tar.xz

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}
COPY --from=buildcontainer /tmp/signal-cli-${SIGNAL_CLI_VERSION}-source/build/native/nativeCompile/signal-cli /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli-native
COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/scripts/jsonrpc2-helper /usr/bin/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


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
&& mkdir -p /home/.local/share/signal-cli \
&& chown -R signal-api:signal-api /home

COPY --chmod=755 ./s6-services/ /etc/s6-overlay/s6-rc.d/

# remove the temporary created signal-cli-native on armv7, as GRAALVM doesn't support 32bit
RUN arch="$(uname -m)"; \
Expand All @@ -201,16 +222,24 @@ 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}

ENV SIGNAL_CLI_CONFIG_DIR=/home/.local/share/signal-cli
ENV SIGNAL_CLI_UID=1000
ENV SIGNAL_CLI_GID=1000
ENV SIGNAL_CLI_CHOWN_ON_STARTUP=true

ENTRYPOINT ["/entrypoint.sh"]
RUN mkdir -p /tmp/s6-runtime && chown -R signal-api:signal-api /tmp/s6-runtime /etc/s6-overlay

USER signal-api

# Mandatory ENV for non-root s6
ENV S6_RUNTIME_PATH=/tmp/s6-runtime
ENV S6_READ_ONLY_ROOT=1
ENV S6_VERBOSITY=2

WORKDIR /home

ENTRYPOINT ["/init"]

HEALTHCHECK --interval=20s --timeout=10s --retries=3 \
CMD curl -f http://localhost:${PORT}/v1/health || exit 1
43 changes: 43 additions & 0 deletions entrypoint.old.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/sh

set -x
set -e

[ -z "${SIGNAL_CLI_CONFIG_DIR}" ] && echo "SIGNAL_CLI_CONFIG_DIR environmental variable needs to be set! Aborting!" && exit 1;

usermod -u ${SIGNAL_CLI_UID} signal-api
groupmod -o -g ${SIGNAL_CLI_GID} signal-api

# Fix permissions to ensure backward compatibility if SIGNAL_CLI_CHOWN_ON_STARTUP is not set to "false"
if [ "$SIGNAL_CLI_CHOWN_ON_STARTUP" != "false" ]; then
echo "Changing ownership of ${SIGNAL_CLI_CONFIG_DIR} to ${SIGNAL_CLI_UID}:${SIGNAL_CLI_GID}"
chown ${SIGNAL_CLI_UID}:${SIGNAL_CLI_GID} -R ${SIGNAL_CLI_CONFIG_DIR}
else
echo "Skipping chown on startup since SIGNAL_CLI_CHOWN_ON_STARTUP is set to 'false'"
fi

# Show warning on docker exec
cat <<EOF >> /root/.bashrc
echo "WARNING: signal-cli-rest-api runs as signal-api (not as root!)"
echo "Run 'su signal-api' before using signal-cli!"
echo "If you want to use signal-cli directly, don't forget to specify the config directory. e.g: \"signal-cli --config ${SIGNAL_CLI_CONFIG_DIR}\""
EOF

cap_prefix="-cap_"
caps="$cap_prefix$(seq -s ",$cap_prefix" 0 $(cat /proc/sys/kernel/cap_last_cap))"

# TODO: check mode
if [ "$MODE" = "json-rpc" ]
then
/usr/bin/jsonrpc2-helper
if [ -n "$JAVA_OPTS" ] ; then
echo "export JAVA_OPTS='$JAVA_OPTS'" >> /etc/default/supervisor
fi
service supervisor start
supervisorctl start all
fi

export HOST_IP=$(hostname -I | awk '{print $1}')

# Start API as signal-api user
exec setpriv --reuid=${SIGNAL_CLI_UID} --regid=${SIGNAL_CLI_GID} --init-groups --inh-caps=$caps signal-cli-rest-api -signal-cli-config=${SIGNAL_CLI_CONFIG_DIR}
3 changes: 3 additions & 0 deletions s6-services/signal-api/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/command/with-contenv sh
# Use with-contenv to import environment variables like SIGNAL_CLI_CONFIG_DIR
exec signal-cli-rest-api -signal-cli-config="${SIGNAL_CLI_CONFIG_DIR}"
1 change: 1 addition & 0 deletions s6-services/signal-api/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
67 changes: 67 additions & 0 deletions s6-services/signal-json-rpc/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/command/with-contenv sh
# File: /etc/s6-overlay/s6-rc.d/signal-json-rpc/run

PIPE=/tmp/sigsocket1
PORT=6001

if [ "$MODE" != "json-rpc" ]; then
echo "Running as mode: $MODE - skipping json-rpc setup"
sleep infinity # do nothing, but keep service running
exit 0
fi

## general parameters for signal-cli
# set SIGNAL_CLI_CONFIG_DIR if not set
if [ -z "$SIGNAL_CLI_CONFIG_DIR" ]; then
SIGNAL_CLI_CONFIG_DIR="/home/.local/share/signal-cli/"
fi

jsonRpcConfig="${SIGNAL_CLI_CONFIG_DIR%/}/jsonrpc2.yml"

# here file to write config
cat > "$jsonRpcConfig" <<EOL
config:
<multi-account>:
tcp_port: $PORT
fifo_pathname: $PIPE
EOL

# Trust Identities
trustNewIdentitiesEnv="${JSON_RPC_TRUST_NEW_IDENTITIES:-}"
trustNewIdentities=""

if [ "$trustNewIdentitiesEnv" = "on-first-use" ]; then
trustNewIdentities=" --trust-new-identities on-first-use"
elif [ "$trustNewIdentitiesEnv" = "always" ]; then
trustNewIdentities=" --trust-new-identities always"
elif [ "$trustNewIdentitiesEnv" = "never" ]; then
trustNewIdentities=" --trust-new-identities never"
elif [ -n "$trustNewIdentitiesEnv" ]; then
# This mirrors your log.Fatal check
echo "Invalid JSON_RPC_TRUST_NEW_IDENTITIES environment variable set!" >&2
exit 1
fi

## parameters for jsonrpc mode
# Attachments
ignoreAttachments="${JSON_RPC_IGNORE_ATTACHMENTS:-}"
signalCliIgnoreAttachments=""
if [ "$ignoreAttachments" = "true" ]; then
signalCliIgnoreAttachments=" --ignore-attachments"
fi

# Stories
ignoreStories="${JSON_RPC_IGNORE_STORIES:-}"
signalCliIgnoreStories=""
if [ "$ignoreStories" = "true" ]; then
signalCliIgnoreStories=" --ignore-stories"
fi

# Load the pipe
[ -p "$PIPE" ] || mkfifo "$PIPE"

# Ensure permissions are correct for non-root
chmod 600 "$PIPE"

# Launch the circular communication
exec sh -c "nc -l -p "${PORT}" < $PIPE | signal-cli --output=json --config "${SIGNAL_CLI_CONFIG_DIR}" "${trustNewIdentities}" jsonRpc ${signalCliIgnoreAttachments} ${signalCliIgnoreStories} > $PIPE"
1 change: 1 addition & 0 deletions s6-services/signal-json-rpc/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
Empty file.
Empty file.
1 change: 1 addition & 0 deletions s6-services/user/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bundle