Files
simplex-chat/scripts/store-service/Dockerfile
T

111 lines
4.4 KiB
Docker

# syntax=docker/dockerfile:1
# Built from the repository root, not this directory, because the COPY paths are repo-relative.
# The Haskell stage compiles simplexmq and simplex-chat from source, which takes hours on a cold
# cache and needs about 15 GB.
ARG UBUNTU=24.04
ARG GHC=9.6.3
ARG CABAL=3.10.2.0
ARG NODE=24
# The checkout page's dist/ is gitignored, so this stage builds it.
FROM node:${NODE}-bookworm-slim AS badges
WORKDIR /badges
COPY apps/simplex-store-service/web/package.json apps/simplex-store-service/web/package-lock.json ./
RUN npm ci
COPY apps/simplex-store-service/web ./
RUN npm run build
# The names site from the apps/simplex-domains submodule. Its public/ links to the repository's
# fonts and images, so the whole submodule is copied, not only webapp/.
FROM node:${NODE}-bookworm-slim AS names
WORKDIR /names/webapp
COPY apps/simplex-domains/webapp/package.json apps/simplex-domains/webapp/package-lock.json ./
RUN npm ci
COPY apps/simplex-domains /names
RUN npm run build
FROM ubuntu:${UBUNTU} AS build
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 \
libpq-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"
# Set explicitly so the cache mount below matches where cabal 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
# Excluding web/ keeps a webapp edit from invalidating this layer and re-running the cabal build,
# and the binary does not depend on it.
COPY --exclude=web apps/simplex-store-service ./apps/simplex-store-service
# The store and build tree are cache mounts rather than layers, so the binary is copied out inside
# the same RUN because dist-newstyle does not exist in the resulting layer.
RUN --mount=type=cache,target=/root/.cabal \
--mount=type=cache,target=/src/dist-newstyle \
set -eu; \
cabal update; \
cabal build --flags="+client_postgres" exe:simplex-store-service; \
mkdir -p /out; \
cp "$(cabal list-bin --flags="+client_postgres" exe:simplex-store-service)" /out/simplex-store-service; \
strip /out/simplex-store-service
FROM ubuntu:${UBUNTU} AS runtime
ENV DEBIAN_FRONTEND=noninteractive
# Built with +client_postgres, so the binary needs libpq and there is no SQLite backend.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates dumb-init libgmp10 libpq5 libssl3 zlib1g && \
rm -rf /var/lib/apt/lists/*
# Set these to your own uid and gid so the state volume is readable without root.
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} badge && \
useradd -u ${USER_UID} -g ${USER_GID} -m -d /home/badge badge
COPY --from=build /out/simplex-store-service /usr/local/bin/simplex-store-service
COPY --from=badges /badges/dist /srv/badges
COPY --from=names /names/webapp/dist /srv/names
USER badge
WORKDIR /home/badge
EXPOSE 8080 8081
# There is no HEALTHCHECK because the listener answers before the chat side has an address, so it
# would report healthy too early.
# The flags live in CMD so `docker compose run` can replace them while dumb-init still forwards
# signals.
ENTRYPOINT ["dumb-init", "--", "simplex-store-service"]
# Without --yes-migrate the service blocks on stdin at every schema change, and a container has no
# console to answer.
CMD ["-d", "postgresql://simplex@127.0.0.1:5432/badge_service", "--create-schema", "--yes-migrate", "--service-config", "/etc/simplex-store-service/store_service.ini"]