+
+
+#==================#
+# static-builder #==================================================
+#
+# Static files are collected here. Statics are then copied into
+# the nginx image, and staticfiles.json manifest is copied back
+# into the test and prod images.
+#
+FROM app AS static-builder
+
+RUN python manage.py collectstatic --noinput
+
+
+###########
+# nginx ############################################################
+#
+# Static files for production nginx. Config is mounted.
+#
+FROM nginx:alpine AS nginx
+
+ARG UID
+ARG GID
+
+# COPY nginx.conf conf.d/...
+
+RUN addgroup -g $GID app && addgroup nginx app
+COPY --from=static-builder /app/var/static /app/var/static
+
+
+#===============#
+# polish-dict #=====================================================
+#
+# Polish hunspell dictionary without diacritics, to allow
+# full text search without diacritics.
+#
+FROM ${PYTHON_IMAGE} AS polish-dict
+
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends hunspell-pl \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY scripts/fold_hunspell.py /usr/local/bin/fold_hunspell.py
+
+RUN set -eu; \
+ mkdir /out; cd /tmp; \
+ enc="$(sed -n 's/^SET[[:space:]]*//p' /usr/share/hunspell/pl_PL.aff | tr -d '\r')"; \
+ iconv -f "${enc:-UTF-8}" -t UTF-8 /usr/share/hunspell/pl_PL.dic > pl.dict; \
+ iconv -f "${enc:-UTF-8}" -t UTF-8 /usr/share/hunspell/pl_PL.aff > pl.affix; \
+ python3 /usr/local/bin/fold_hunspell.py pl.dict pl.affix \
+ /out/polish.dict /out/polish.affix; \
+ dpkg-query -W -f='hunspell-pl ${Version}\n' hunspell-pl > /out/polish.version
+
+
+##############
+# postgres #########################################################
+#
+# Postgres with the dictionary from polish-dict.
+#
+FROM postgres:18 AS postgres
+
+COPY --from=polish-dict /out/ /tmp/polish-dict/
+RUN mv /tmp/polish-dict/* "/usr/share/postgresql/$PG_MAJOR/tsearch_data/" \
+ && rmdir /tmp/polish-dict
+
+COPY scripts/postgres-polish.sql /docker-entrypoint-initdb.d/10-postgres-polish.sql
+
+
+##########
+# test #############################################################
+#
+# Production image plus test requirements. Defined before `prod`,
+# so that `prod` stays the default (last) stage.
+#
+FROM app AS test
+
+USER root
+COPY requirements/requirements-test.txt /tmp/
+RUN pip install --no-cache-dir -r /tmp/requirements-test.txt
+USER app
+RUN mkdir -p /app/var/counters
+COPY --from=static-builder /app/var/static/staticfiles.json /app/var/static/staticfiles.json
+CMD ["./manage.py", "test"]
+
+
+##########
+# prod #############################################################
+#
+# Production image: app + staticfiles.json manifest.
+#
+FROM app AS prod
+
+COPY --from=static-builder /app/var/static/staticfiles.json /app/var/static/staticfiles.json