Files
computer-playbook/roles/web-app-bridgy-fed/files/Dockerfile
kevinveenbirkenbachandClaude Opus 5 10c5b35e88 feat(images): move seven roles off the Debian codename base onto slim
A '-bookworm' tag names its Debian release by codename, which carries no
ordering, so nothing can raise it across a Debian major and the base stays
frozen on that release for as long as the pin stands. Moving to '-slim'
drops the codename and takes the smaller image at the same time.

The tag hides that this is two changes at once: node:26-slim and
python:3.x-slim are trixie today, so those six roles cross Debian 12 to 13
and lose the toolchain the full buildpack-deps image carried. node:24-slim
is still bookworm and its manifest is byte-identical to
node:24-bookworm-slim, so flowise changes nothing today; what it gains is a
tag that will follow the rebase instead of pinning Debian 12 forever.

Each image was built with --no-cache and the steps read back rather than
the exit code: postmarks installs git 2.47.3-0+deb13u1 and 304 npm
packages, bookwyrm builds through its runtime stage so the libjpeg62-turbo,
libsass1, libffi8, libxslt1.1 and libmagic1 it hardcodes do exist on
trixie, roulette-wheel compiles its webpack bundle. Two were additionally
exercised at runtime: sharp loads its prebuilt binding in the simpleicons
image, and bridgy-fed imports secp256k1 and constructs flask_app.app.
web-svc-cdn has no Dockerfile, so its build script's seven tools were
checked for presence instead.

bridgy-fed needs pkg-config, autoconf, automake and libtool to survive the
move. secp256k1 vendors libsecp256k1 and builds it from source: without
pkg-config the metadata step refuses outright, and with it autogen.sh exits
127. python:3.14-bookworm is the full buildpack-deps image and ships both;
slim does not. They land in the build stage only, so the runtime image
stays slim.

The flowise min-storage marker still claimed a bookworm-slim base and now
names what is actually built.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:00:51 +02:00

60 lines
1.9 KiB
Docker

# Runtime image for Bridgy Fed (Flask), built from a clone of upstream.
#
# Both stages carry /usr/local over rather than reinstalling, so the
# python-version-specific site-packages path never has to be hardcoded, and
# gunicorn is present at runtime instead of the entrypoint dying with
# `gunicorn: not found` in a restart loop.
#
# Upstream serves oauth_dropins assets from /app/oauth_dropins_static and ships
# no such directory, so the package's own static tree is linked in.
#
# BRIDGY_REF is a commit, because upstream publishes no tags. `git clone
# --branch` refuses a commit, hence the fetch of the single ref instead.
ARG PY_BASE
FROM ${PY_BASE} AS build
ARG BRIDGY_REPO_URL
ARG BRIDGY_REF
RUN rm -rf /var/lib/apt/lists/* && \
apt-get -o Acquire::Retries=3 update && apt-get -o Acquire::Retries=3 install -y --no-install-recommends \
git build-essential pkg-config autoconf automake libtool curl ca-certificates && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN git init -q . && \
git remote add origin "${BRIDGY_REPO_URL}" && \
git fetch -q --depth=1 origin "${BRIDGY_REF}" && \
git checkout -q --detach FETCH_HEAD
RUN pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
RUN python - <<'PY'
import oauth_dropins, pathlib, os
target = pathlib.Path(oauth_dropins.__file__).parent / 'static'
link = pathlib.Path('/app/oauth_dropins_static')
try:
if link.exists() or link.is_symlink():
link.unlink()
os.symlink(str(target), str(link))
except FileExistsError:
pass
print('Symlinked oauth_dropins_static ->', target)
PY
FROM ${PY_BASE}
ARG CONTAINER_PORT
ENV PORT=${CONTAINER_PORT}
WORKDIR /app
COPY --from=build /app /app
COPY --from=build /usr/local /usr/local
RUN useradd -r -m -d /nonroot appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE ${PORT}
CMD ["sh", "-lc", "exec gunicorn -w 2 -k gthread -b 0.0.0.0:${PORT} flask_app:app"]