mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-20 10:30:07 +00:00
* feat: add simplex-support-bot-light * feat: package simplex-support-bot-light for docker * docs: document simplex-support-bot-light * fix: make a missing config actionable and bounded * docs: note the attached compose Ctrl+C behaviour * refactor: use the library for startup and custom data * refactor: drop the display-name workaround * style: shorten the startup comment * build: build the core and the library into the image * docs: correct where the image type rule comes from * fix: log what the core said a command got wrong * build: run the container as the operator's uid * docs: keep the container uid in .env * docs: tighten the README
131 lines
5.7 KiB
Docker
131 lines
5.7 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# Built from the repository root, not this directory: the image is made from the
|
|
# Haskell core and the Python library in this tree, neither of them released.
|
|
#
|
|
# docker compose build # from apps/simplex-support-bot-light
|
|
# docker build -f apps/simplex-support-bot-light/Dockerfile .
|
|
#
|
|
# The first stage compiles libsimplex from src/. That is a full GHC build of
|
|
# simplexmq and simplex-chat: hours on a cold cache, and it needs ~15 GB.
|
|
|
|
ARG UBUNTU=24.04
|
|
# The released libs are built on 22.04; a lib built here has to load on a runtime
|
|
# with the same glibc or newer, not the other way round.
|
|
ARG UBUNTU_LIBS=22.04
|
|
ARG GHC=9.6.3
|
|
ARG CABAL=3.10.2.0
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# libsimplex — the cabal invocation of scripts/desktop/build-lib-linux.sh, which
|
|
# is what produces the .so the published libs archive is repackaged from.
|
|
# --------------------------------------------------------------------------- #
|
|
FROM ubuntu:${UBUNTU_LIBS} AS libsimplex
|
|
|
|
ARG GHC
|
|
ARG CABAL
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential ca-certificates curl git libgmp3-dev libnuma-dev \
|
|
libsqlite3-dev libssl-dev llvm pkg-config zlib1g-dev && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
ENV BOOTSTRAP_HASKELL_NONINTERACTIVE=1 \
|
|
BOOTSTRAP_HASKELL_GHC_VERSION=${GHC} \
|
|
BOOTSTRAP_HASKELL_CABAL_VERSION=${CABAL} \
|
|
BOOTSTRAP_HASKELL_INSTALL_NO_STACK=true \
|
|
BOOTSTRAP_HASKELL_INSTALL_NO_STACK_HOOK=true
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
|
|
ENV PATH="/root/.ghcup/bin:/root/.cabal/bin:$PATH"
|
|
# Explicit, so the cache mount below is where cabal actually keeps its store.
|
|
ENV CABAL_DIR=/root/.cabal
|
|
|
|
WORKDIR /src
|
|
COPY cabal.project simplex-chat.cabal README.md PRIVACY.md ./
|
|
COPY scripts/cabal.project.local.linux ./cabal.project.local
|
|
COPY src ./src
|
|
|
|
# Cache mounts, not layers: the Haskell store and the build tree survive a
|
|
# source change, which is the difference between minutes and hours. The RTS and
|
|
# package libraries are copied next to libsimplex.so because its rpath is $ORIGIN.
|
|
RUN --mount=type=cache,target=/root/.cabal \
|
|
--mount=type=cache,target=/src/dist-newstyle \
|
|
set -eu; \
|
|
cabal update; \
|
|
cabal build lib:simplex-chat \
|
|
--ghc-options='-optl-Wl,-rpath,$ORIGIN -optl-Wl,-soname,libsimplex.so -flink-rts -threaded' \
|
|
--constraint 'simplexmq +client_library' \
|
|
--constraint 'simplex-chat +client_library'; \
|
|
lib=$(ls -t /src/dist-newstyle/build/*/ghc-${GHC}/simplex-chat-*/build/libHSsimplex-chat-*-inplace-ghc${GHC}.so | head -1); \
|
|
build_dir=$(dirname "$lib"); \
|
|
mv "$lib" "$build_dir/libsimplex.so"; \
|
|
mkdir -p /libs; \
|
|
ldd "$build_dir/libsimplex.so" | grep ghc | cut -d' ' -f 3 | xargs -I {} cp {} /libs/; \
|
|
cp "$build_dir/libsimplex.so" /libs/
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# the bot
|
|
# --------------------------------------------------------------------------- #
|
|
# libsimplex is a glibc build and will not load on musl, and it is compiled
|
|
# against this image's libraries in the stage above.
|
|
FROM ubuntu:${UBUNTU}
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl dumb-init libffi8 libgmp10 libnuma1 && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
|
|
mv /root/.local/bin/uv /usr/local/bin/uv
|
|
|
|
# The ids that must own ./state on the host; a bind mount keeps host ownership.
|
|
# Build with your own to avoid needing root to read the bot's state:
|
|
# USER_UID=$(id -u) USER_GID=$(id -g) docker compose build
|
|
ARG USER_UID=1000
|
|
ARG USER_GID=1000
|
|
|
|
# ubuntu:24.04 ships a default user at 1000, so drop whoever holds the ids.
|
|
RUN if existing_user=$(getent passwd ${USER_UID} | cut -d: -f1) && [ -n "${existing_user}" ]; then \
|
|
userdel -r "${existing_user}" 2>/dev/null || userdel "${existing_user}"; \
|
|
fi && \
|
|
if existing_group=$(getent group ${USER_GID} | cut -d: -f1) && [ -n "${existing_group}" ]; then \
|
|
groupdel "${existing_group}" 2>/dev/null || true; \
|
|
fi && \
|
|
groupadd -g ${USER_GID} supportbot && \
|
|
useradd -u ${USER_UID} -g ${USER_GID} -m -d /home/supportbot supportbot
|
|
|
|
# Applies only when /data is not bind-mounted; a bind mount keeps the host
|
|
# directory's ownership and mode.
|
|
RUN mkdir -p /data && chown supportbot:supportbot /data && chmod 0700 /data
|
|
|
|
# Read by simplex_chat._native instead of downloading a release, which is what
|
|
# makes the bot run against the core built above rather than the published one.
|
|
COPY --from=libsimplex /libs /opt/simplex/libs
|
|
ENV SIMPLEX_LIBS_DIR=/opt/simplex/libs
|
|
|
|
USER supportbot
|
|
WORKDIR /home/supportbot
|
|
|
|
ENV VIRTUAL_ENV=/home/supportbot/.venv
|
|
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
|
|
|
# The library is installed from this tree: the APIs the bot uses
|
|
# (install_signal_handlers, sync_profile, api_merge_*_custom_data) are unreleased.
|
|
COPY --chown=supportbot:supportbot packages/simplex-chat-python /home/supportbot/simplex-chat-python
|
|
RUN uv venv --python 3.12 "$VIRTUAL_ENV" && \
|
|
uv pip install /home/supportbot/simplex-chat-python
|
|
|
|
COPY --chown=supportbot:supportbot apps/simplex-support-bot-light /home/supportbot/app
|
|
RUN uv pip install -e /home/supportbot/app
|
|
|
|
ENV PYTHONUNBUFFERED=1
|
|
|
|
# No HEALTHCHECK: /health is published for an external monitor, and a container
|
|
# check would restart a bot whose chat controller is merely slow.
|
|
|
|
# Exec form: shell form would run under `sh -c`, which does not forward SIGTERM
|
|
# to the bot, so the graceful-stop path in __main__.py would never fire.
|
|
ENTRYPOINT ["dumb-init", "--", "support-bot-light", "--config", "/etc/support-bot-light/config.toml"]
|