From 259582179a005249ca1b0f045b22058ec1a3fdda Mon Sep 17 00:00:00 2001 From: Yanis Srairi Date: Sat, 9 May 2026 10:23:55 +0200 Subject: [PATCH 1/2] rewrite: Dockerfile as multi-stage build --- Dockerfile | 134 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 40 deletions(-) diff --git a/Dockerfile b/Dockerfile index fb1225d..640f8c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,49 +1,103 @@ -FROM ubuntu:22.04 - -# Install build tools, ForeFire dependencies, AND Python environment -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - build-essential \ - libnetcdf-c++4-dev \ - cmake \ - curl \ - python3 \ - python3-pip \ - python3-dev \ - git && \ - rm -rf /var/lib/apt/lists/* - -# Install Python dependencies for testing -RUN pip3 install --no-cache-dir lxml xarray netCDF4 +ARG UBUNTU_IMAGE=ubuntu:24.04 -WORKDIR /forefire -ENV FOREFIREHOME=/forefire +# Stage 1: builder +FROM ${UBUNTU_IMAGE} AS builder + +ARG DEBIAN_FRONTEND=noninteractive + +# Keep the BuildKit apt cache mount populated across builds: disable +# docker-clean's post-install hooks AND tell apt to keep downloaded .debs. +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + rm -f /etc/apt/apt.conf.d/docker-clean \ + && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \ + > /etc/apt/apt.conf.d/keep-cache \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + libnetcdf-c++4-dev \ + python3-dev \ + python3-pip + +WORKDIR /build + +# LICENSE is required by CPack at configure time (CMakeLists includes CPack). +COPY --link CMakeLists.txt LICENSE ./ +COPY --link app/ ./app/ +# tools/ is needed at configure time: CMakeLists.txt invokes +# tools/check_all_lfs.bash and references tools/runANN/ANNTest.cpp. +COPY --link tools/ ./tools/ +COPY --link src/ ./src/ + +RUN cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \ + && cmake --build build -j"$(nproc)" + +COPY --link bindings/ ./bindings/ -# Copy build configuration first (rarely changes) -COPY CMakeLists.txt cmake-build.sh LICENSE ./ +RUN --mount=type=cache,target=/root/.cache/pip \ + pip3 wheel --no-deps --wheel-dir /wheels ./bindings/python -# Copy source code and applications -COPY src/ ./src/ -COPY app/ ./app/ -COPY tools/runANN/ ./tools/runANN/ -# Build and install the ForeFire C++ library -RUN sh cmake-build.sh +# Stage 2: runtime +FROM ${UBUNTU_IMAGE} -# Add the main forefire executable to the PATH -RUN cp /forefire/bin/forefire /usr/local/bin/ +ARG DEBIAN_FRONTEND=noninteractive -# Use pip to install the Python bindings -COPY bindings/ ./bindings/ -RUN pip3 install ./bindings/python +ENV FOREFIREHOME=/forefire \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 -# Copy everything else (changes most frequently - docs, tests, etc.) -COPY . . +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + rm -f /etc/apt/apt.conf.d/docker-clean \ + && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \ + > /etc/apt/apt.conf.d/keep-cache \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + libnetcdf-c++4-1 \ + python3 \ + python3-pip \ + ca-certificates \ + curl -# WE COULD USE A CUSTOM ENTRYPOINT SCRIPT TO START THE HTTP SERVER AND RUN THE DEMO SIMULATION -# COPY tools/devops/entrypoint.sh /usr/local/bin/entrypoint.sh -# RUN chmod +x /usr/local/bin/entrypoint.sh -# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +RUN --mount=type=cache,target=/root/.cache/pip \ + pip3 install --break-system-packages \ + lxml xarray netCDF4 + +COPY --from=builder --link /build/bin/forefire /usr/local/bin/forefire +COPY --from=builder --link /build/lib/libforefireL.so /usr/local/lib/ +COPY --from=builder --link /wheels/ /tmp/wheels/ + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip3 install --break-system-packages /tmp/wheels/*.whl \ + && rm -rf /tmp/wheels \ + && ldconfig + +# Non-root user at UID 1000 so files written to mounted volumes get the +# host user's ownership. Ubuntu 24.04 ships a default `ubuntu` user at +# 1000, so we drop it first to free the slot. The /forefire/bin symlink +# keeps `../../bin/forefire` working in test scripts (tests/runff/ff-run.bash:16). +RUN userdel --remove ubuntu 2>/dev/null || true \ + && groupadd --gid 1000 forefire \ + && useradd --gid 1000 --uid 1000 --create-home --shell /bin/bash forefire \ + && mkdir -p /forefire/bin \ + && ln -s /usr/local/bin/forefire /forefire/bin/forefire \ + && chown -R 1000:1000 /forefire + +COPY --chown=1000:1000 app/ /forefire/app/ +COPY --chown=1000:1000 bindings/ /forefire/bindings/ +COPY --chown=1000:1000 tests/ /forefire/tests/ +COPY --chown=1000:1000 tools/ /forefire/tools/ + +LABEL org.opencontainers.image.source="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/forefireAPI/forefire" \ + org.opencontainers.image.documentation="https://forefire.readthedocs.io/" \ + org.opencontainers.image.description="ForeFire is an open-source code for wildland fire spread models" \ + org.opencontainers.image.licenses="GPL-3.0-or-later" \ + org.opencontainers.image.title="forefire" + +USER forefire +WORKDIR /forefire -# Set the entrypoint to bash for interactive sessions -CMD ["bash"] \ No newline at end of file +EXPOSE 8000 +CMD ["bash"] From 13e23e9797e142bcbf05670cc2aa6a0f4886aa11 Mon Sep 17 00:00:00 2001 From: Yanis Srairi Date: Mon, 11 May 2026 17:24:51 +0200 Subject: [PATCH 2/2] [docker] drop tools/devops old WIP (#144) --- tools/devops/Dockerfile.base | 22 ----------- tools/devops/Dockerfile.multistage | 60 ------------------------------ tools/devops/entrypoint.sh | 34 ----------------- tools/devops/readme.md | 10 ----- 4 files changed, 126 deletions(-) delete mode 100644 tools/devops/Dockerfile.base delete mode 100644 tools/devops/Dockerfile.multistage delete mode 100644 tools/devops/entrypoint.sh delete mode 100644 tools/devops/readme.md diff --git a/tools/devops/Dockerfile.base b/tools/devops/Dockerfile.base deleted file mode 100644 index 6ca310c..0000000 --- a/tools/devops/Dockerfile.base +++ /dev/null @@ -1,22 +0,0 @@ -FROM ubuntu:22.04 - -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - build-essential \ - libnetcdf-c++4-dev \ - cmake - -WORKDIR /forefire -ENV FOREFIREHOME=/forefire - -# we could only copy src, cmakelists.txt and cmake-build.sh -COPY . . - -# install forefire -RUN sh cmake-build.sh - -# add executable to PATH -RUN cp /forefire/bin/forefire /usr/local/bin/ - -# Set the entrypoint to bash for interactive sessions -CMD ["bash"] \ No newline at end of file diff --git a/tools/devops/Dockerfile.multistage b/tools/devops/Dockerfile.multistage deleted file mode 100644 index 8bfcc21..0000000 --- a/tools/devops/Dockerfile.multistage +++ /dev/null @@ -1,60 +0,0 @@ -# File: tools/Dockerfile.multistage -# Target: Creates an optimized, smaller final image using a multi-stage build. -# Contains full Python support. - -# --- STAGE 1: The "Builder" --- -# This stage is a temporary environment used to compile the C++ code. -# It contains all the heavy build tools, which will NOT be in the final image. -FROM ubuntu:22.04 AS builder - -# Install build tools and C++ dependencies -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - build-essential \ - libnetcdf-c++4-dev \ - cmake \ - git && \ - rm -rf /var/lib/apt/lists/* - -WORKDIR /src - -# Copy all source code into the builder stage -COPY . . - -# Build the C++ library and executable -RUN sh cmake-build.sh - - -# --- STAGE 2: The "Final Image" --- -# This is the final, clean image that will be distributed. -# It starts from a fresh Ubuntu base and only pulls in what's necessary. -FROM ubuntu:22.04 - -# Install only the RUNTIME dependencies needed for ForeFire and the Python bindings. -# As requested, we use libnetcdf-c++4-dev here for consistency with the build stage. -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - libnetcdf-c++4-dev \ - libgomp1 \ - python3 \ - g++ \ - python3-pip \ - python3-dev && \ - rm -rf /var/lib/apt/lists/* - -WORKDIR /forefire -ENV FOREFIREHOME=/forefire - -# The magic step: Copy the ENTIRE built project from the 'builder' stage. -# This brings over the compiled libs, binaries, and the source code needed for the bindings. -COPY --from=builder /src/ . - -# Add the forefire executable to the system's PATH -RUN cp /forefire/bin/forefire /usr/local/bin/ - -# Install the Python bindings and their dependencies (numpy, etc.) -# This compiles the C++ extension using the headers we just copied. -RUN pip3 install ./bindings/python - -# Set the default command to start a bash shell -CMD ["bash"] \ No newline at end of file diff --git a/tools/devops/entrypoint.sh b/tools/devops/entrypoint.sh deleted file mode 100644 index fa15f6e..0000000 --- a/tools/devops/entrypoint.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -set -e - -echo "🔥 ForeFire Quick Start Demo" -echo "==============================" -echo "" - -# Navigate to the test directory -cd /forefire/tests/runff - -echo "📁 Working directory: $(pwd)" -echo "🌐 Starting ForeFire with HTTP server..." -echo "" -echo "Once started, open your browser to: http://localhost:8000" -echo "To run the demo simulation, type: include[real_case.ff]" -echo "To stop, press Ctrl+C" -echo "" - -# Function to handle graceful shutdown -cleanup() { - echo "" - echo "🛑 Shutting down ForeFire..." - exit 0 -} - -# Set up signal handlers for graceful shutdown -trap cleanup SIGINT SIGTERM - -# Start forefire and automatically launch HTTP server -forefire -l & -FOREFIRE_PID=$! - -# Wait for the forefire process -wait $FOREFIRE_PID diff --git a/tools/devops/readme.md b/tools/devops/readme.md deleted file mode 100644 index 8726ea1..0000000 --- a/tools/devops/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -## Alternative Dockerfiles - -WIP - -- Dockerfile without python to make the image smaller -- Multistage build to make the also smaller (490 vs 620 mb) - -``` -docker build -f tools/docker/Dockerfile.multistage -t forefire:multistage . -``` \ No newline at end of file