|
1 | 1 | # Source: https://docs.astral.sh/uv/guides/integration/docker/#non-editable-installs |
2 | 2 | # |
| 3 | +# Build with a pre-configured DAPS toolchain image from openSUSE. |
| 4 | +# This version builds a wheel in a builder stage and installs it in a |
| 5 | +# clean runtime environment in the final stage. |
| 6 | +# |
3 | 7 | # Build it with: |
4 | 8 | # $ docker build -t docbuild:latest . |
5 | | -# -- or -- |
6 | | -# $ docker buildx build -t docbuild:latest . |
7 | 9 | # |
8 | | -# If you want to skip the jing installation step, use: |
9 | | -# $ docker build --build-arg WITH_JING=false -t docbuild:latest . |
10 | 10 |
|
11 | | -ARG PYTHON_VERSION=3.13-slim |
| 11 | +ARG OPENSUSE_VERSION=15.6 |
| 12 | +ARG IMAGE="registry.opensuse.org/documentation/containers/${OPENSUSE_VERSION}/opensuse-daps-toolchain:latest" |
12 | 13 |
|
13 | | -# ------- Stage 1: Build the environment ---------------- |
14 | | -FROM python:${PYTHON_VERSION} AS builder |
| 14 | +# ------- Stage 1: Build the runtime environment ---------------- |
| 15 | +FROM ${IMAGE} AS builder |
15 | 16 |
|
16 | | -# Create a non-root user |
| 17 | +# Create a non-root user. |
17 | 18 | RUN useradd -m app |
18 | | -USER app |
19 | 19 |
|
20 | | -# Install uv |
| 20 | +# Install uv. |
21 | 21 | COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ |
22 | 22 |
|
23 | | -# Change the working directory |
24 | | -WORKDIR /app |
| 23 | +# Set the working directory to the user's home. |
| 24 | +WORKDIR /home/app |
25 | 25 |
|
26 | | -# Install dependencies |
27 | | -RUN --mount=type=cache,target=/root/.cache/uv \ |
28 | | - --mount=type=bind,source=uv.lock,target=uv.lock \ |
29 | | - --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ |
30 | | - uv sync --frozen --no-install-project --no-editable |
| 26 | +# Copy all project source files. |
| 27 | +COPY . . |
31 | 28 |
|
32 | | -# Copy the project into the intermediate image |
33 | | -ADD --chown=app:app . /app |
34 | | - |
35 | | -# Sync the project |
| 29 | +# Build the wheel, create a venv, and install the wheel into it. |
| 30 | +# This is all done as root to avoid cache permission issues. |
36 | 31 | RUN --mount=type=cache,target=/root/.cache/uv \ |
37 | | - uv sync --frozen --no-editable |
38 | | - |
39 | | -# ------- Stage 2: Build/provide the application -------- |
40 | | -FROM python:${PYTHON_VERSION} |
41 | | - |
42 | | -# Allow conditional installation of jing for XML validation |
43 | | -ARG WITH_JING=true |
44 | | - |
45 | | -# Install runtime dependencies like jing for XML validation |
46 | | -RUN if [ "$WITH_JING" = "true" ]; then \ |
47 | | - apt-get update && apt-get install -y --no-install-recommends jing && rm -rf /var/lib/apt/lists/*; \ |
48 | | - fi |
49 | | - |
50 | | -# Create a non-root user to match the builder stage |
| 32 | + set -e; export HOME=/home/app && \ |
| 33 | + uv build --wheel && \ |
| 34 | + uv venv && \ |
| 35 | + uv pip install dist/*.whl |
| 36 | + |
| 37 | +# Fix permissions for the runtime files. |
| 38 | +RUN chown -R app:users /home/app |
| 39 | + |
| 40 | +# ------- Stage 2: Create the final, lean image -------- |
| 41 | +FROM ${IMAGE} |
| 42 | + |
| 43 | +# --- OPTIMIZATION STEP --- |
| 44 | +# As root, remove unnecessary files to reduce the final image size. |
| 45 | +# This must be done as root, before creating the 'app' user. |
| 46 | +# RUN set -x; \ |
| 47 | +# rpm -v --erase --nodeps --force python3-cssselect python3 python3-base python3-lxml python3-gobject \ |
| 48 | +# ca-certificates cracklib cups-config diffutils fdupes \ |
| 49 | +# gio-branding-openSUSE gstreamer gtk2-tools gtk3-data gtk3-schema gtk3-tools \ |
| 50 | +# hicolor-icon-theme info ncurses-utils netcfg openSUSE-release perl5 pinentry \ |
| 51 | +# Mesa Mesa-dri Mesa-gallium Mesa-libEGL1 Mesa-libGL1 libglvnd libgstgl; \ |
| 52 | +# rm -rf /usr/include \ |
| 53 | +# /usr/lib/{browser-plugins,gstreamer-*,ca-certificates,keyboxd,locale,perl5,git,gpg-*,getconf,scdaemon,ssh,systemd,tmpfiles.d} \ |
| 54 | +# /usr/local/* \ |
| 55 | +# /usr/sbin/{fdisk,sfdisk,g13-syshelp,fsck.minix,partx,mkswap,zramctl} \ |
| 56 | +# /var/log/* \ |
| 57 | +# /var/cache/{zypp,ldconfig,fontconfig,cups} \ |
| 58 | +# /var/adm/* \ |
| 59 | +# /var/lib/{YaST2,alternatives,ca-certificates,selinux,xkb,misc} || true |
| 60 | + |
| 61 | +# --- DIAGNOSTIC STEP --- |
| 62 | +# Add this temporary command to see the size of top-level directories |
| 63 | +# before the cleanup step. This helps identify what is taking up space. |
| 64 | +# RUN du -sh /usr/lib/* | sort -rh | head -n 20 > /du-usrlib-sort.txt |
| 65 | + |
| 66 | + |
| 67 | +# Create the same non-root user. |
51 | 68 | RUN useradd -m app |
52 | 69 |
|
53 | | -# Copy the environment, but not the source code |
54 | | -COPY --from=builder --chown=app:app /app/.venv /app/.venv |
| 70 | +# Copy only the essential runtime directories from the builder. |
| 71 | +# This results in a lean final image without build artifacts or source code. |
| 72 | +COPY --from=builder --chown=app:users /home/app/.venv /home/app/.venv |
| 73 | +COPY --from=builder --chown=app:users /home/app/.local /home/app/.local |
55 | 74 |
|
56 | | -# Set the working directory |
57 | | -WORKDIR /app |
| 75 | +# Switch to the non-root user for security. |
| 76 | +USER app |
58 | 77 |
|
59 | | -# Add the virtual environment's bin directory to the PATH |
60 | | -ENV PATH="/app/.venv/bin:${PATH}" |
| 78 | +# Set the working directory. |
| 79 | +WORKDIR /home/app |
61 | 80 |
|
62 | | -# Switch to the non-root user for security |
63 | | -USER app |
| 81 | +# Set the PATH to include the virtual environment's bin directory. |
| 82 | +ENV PATH="/home/app/.venv/bin:${PATH}" |
| 83 | +ENV LANG=en_US.UTF-8 |
| 84 | +ENV LC_ALL=en_US.UTF-8 |
| 85 | +ENV TERM=xterm-256color |
64 | 86 |
|
65 | | -# Run the application |
66 | | -CMD ["docbuild"] |
| 87 | +# Run the application. |
| 88 | +# ENTRYPOINT [ "docbuild" ] |
| 89 | +# CMD ["docbuild", "--env-config", "env-production.toml", "--help"] |
0 commit comments