# LibreOffice conversion service. Multi-arch: builds natively on the Oracle
# Ampere (arm64) VM and on x86 alike. Ubuntu 24.04 ships LibreOffice 24.2,
# which imports Office files noticeably better than Debian 12's 7.4.
FROM node:22-bookworm-slim AS node

FROM ubuntu:24.04
# Node runtime only (the server has no npm dependencies).
COPY --from=node /usr/local/bin/node /usr/local/bin/node

# Office suites without the desktop UI, plus fonts. python3-uno drives Calc
# for spreadsheets (src/calc_fit.py: every column fitted to the page width).
# Fonts matter more than
# anything else for output quality: a document whose font is missing gets a
# substitute, and lines reflow. Carlito/Caladea are metric-compatible with
# Calibri/Cambria and Liberation with Arial/Times/Courier, so Office
# documents keep their line breaks. Noto + Amiri + KACST cover Arabic, Urdu
# and the South Asian scripts our visitors use.
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
      libreoffice-writer-nogui libreoffice-calc-nogui libreoffice-impress-nogui libreoffice-draw-nogui \
      fonts-liberation2 fonts-crosextra-carlito fonts-crosextra-caladea fonts-dejavu-core \
      fonts-noto-core fonts-noto-cjk fonts-hosny-amiri fonts-kacst fonts-noto-ui-core \
      python3-uno python3-venv \
      tini \
 && apt-get clean && rm -rf /var/lib/apt/lists/* /usr/share/doc/* \
 && fc-cache -f

# PDF to Word: pdf2docx in its own venv (pinned). --system-site-packages
# keeps python3-uno importable for calc_fit.py from the same interpreter.
COPY requirements.txt /tmp/requirements.txt
RUN python3 -m venv --system-site-packages /opt/py \
 && /opt/py/bin/pip install --no-cache-dir -r /tmp/requirements.txt \
 && rm /tmp/requirements.txt

WORKDIR /app
COPY package.json ./
COPY src ./src

# This service's own source, served at /source (AGPL-3.0 because of PyMuPDF,
# see SOURCE.md). Only the files listed here go in; .env never reaches the
# build (.dockerignore).
COPY LICENSE SOURCE.md Dockerfile docker-compose.yml requirements.txt .env.example package.json .dockerignore /tmp/source/converter/
COPY src /tmp/source/converter/src
COPY test /tmp/source/converter/test
RUN tar -czf /app/source.tar.gz -C /tmp/source converter && rm -rf /tmp/source

# Unprivileged user (uid 1000, ships with the image); the container also
# runs read-only with /tmp as tmpfs.
USER ubuntu
ENV NODE_ENV=production PORT=8080 WORK_DIR=/tmp/converter HOME=/tmp PYTHON_BIN=/opt/py/bin/python3 PYTHONDONTWRITEBYTECODE=1
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD node -e "fetch('http://127.0.0.1:8080/healthz').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["node", "src/server.mjs"]
