# syntax=docker/dockerfile:1.7
ARG CUDA_VERSION=12.9.1
ARG UBUNTU_VERSION=24.04
ARG SD_CPP_REF=master
ARG CUDA_ARCHS="50-virtual;60-virtual;61-virtual;70-virtual;75-virtual;80-virtual;86-real;89-real;90-virtual;100-real;101-real;103-real;120a-real;121a-real"

# ============================================================
# SECTION 01: CUDA BASE
# ============================================================
FROM nvidia/cuda:${CUDA_VERSION}-devel-ubuntu${UBUNTU_VERSION} AS s01-cuda-base
RUN printf 'section-01 cuda base\n' > /build-checkpoint-01.txt

# ============================================================
# SECTION 02: TOOLCHAIN
# ============================================================
FROM s01-cuda-base AS s02-toolchain
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
      git ca-certificates cmake ninja-build build-essential pkg-config \
      libcurl4-openssl-dev binutils file libwebp-dev python3 python3-pip \
    && rm -rf /var/lib/apt/lists/*
RUN nvcc --version && cmake --version && ninja --version && c++ --version
RUN printf 'section-02 toolchain\n' > /build-checkpoint-02.txt

# ============================================================
# SECTION 03: STABLE-DIFFUSION.CPP SOURCE
# ============================================================
FROM s02-toolchain AS s03-sd-source
ARG SD_CPP_REF
WORKDIR /src/stable-diffusion.cpp
RUN set -eux; \
    git init .; \
    git remote add origin https://github.com/leejet/stable-diffusion.cpp.git; \
    git fetch --depth 1 origin "${SD_CPP_REF}"; \
    git checkout --detach FETCH_HEAD; \
    git submodule update --init --recursive; \
    git rev-parse HEAD | tee /stable-diffusion-cpp-commit.txt
RUN printf 'section-03 sd source\n' > /build-checkpoint-03.txt

# ============================================================
# SECTION 04: CMAKE CONFIGURE
# ============================================================
FROM s03-sd-source AS s04-cmake-configure
ARG CUDA_ARCHS
WORKDIR /src/stable-diffusion.cpp
RUN set -eux; \
    printf 'CUDA_ARCHS=%s\n' "${CUDA_ARCHS}" | tee /cuda-architectures.txt; \
    cmake -S . -B build -G Ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DSD_CUDA=ON \
      -DSD_BUILD_EXAMPLES=ON \
      -DSD_SERVER_BUILD_FRONTEND=OFF \
      -DSD_USE_SYSTEM_WEBP=ON \
      -DSD_WEBM=OFF \
      -DGGML_NATIVE=OFF \
      -DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}"; \
    test -f build/build.ninja
RUN printf 'section-04 cmake configure\n' > /build-checkpoint-04.txt

# ============================================================
# SECTION 05: GGML CPU
# ============================================================
FROM s04-cmake-configure AS s05-ggml-cpu
WORKDIR /src/stable-diffusion.cpp
RUN cmake --build build --target ggml-base ggml-cpu -j"$(nproc)"
RUN printf 'section-05 ggml cpu\n' > /build-checkpoint-05.txt

# ============================================================
# SECTION 06: GGML CUDA
# ============================================================
FROM s05-ggml-cpu AS s06-ggml-cuda
WORKDIR /src/stable-diffusion.cpp
RUN --mount=type=cache,target=/root/.cache \
    cmake --build build --target ggml-cuda -j"$(nproc)"
RUN printf 'section-06 ggml cuda\n' > /build-checkpoint-06.txt

# ============================================================
# SECTION 07: SD CORE
# ============================================================
FROM s06-ggml-cuda AS s07-sd-core
WORKDIR /src/stable-diffusion.cpp
RUN cmake --build build --target stable-diffusion -j"$(nproc)"
RUN printf 'section-07 sd core\n' > /build-checkpoint-07.txt

# ============================================================
# SECTION 08: SD SERVER
# ============================================================
FROM s07-sd-core AS s08-server-link
WORKDIR /src/stable-diffusion.cpp
RUN set -eux; \
    test -f /usr/local/cuda/lib64/stubs/libcuda.so; \
    install -d /usr/local/lib/cuda-stubs; \
    ln -sf /usr/local/cuda/lib64/stubs/libcuda.so /usr/local/lib/cuda-stubs/libcuda.so.1; \
    ln -sf /usr/local/cuda/lib64/stubs/libcuda.so /usr/lib/x86_64-linux-gnu/libcuda.so.1; \
    LD_LIBRARY_PATH=/usr/local/lib/cuda-stubs:/usr/local/cuda/lib64/stubs:${LD_LIBRARY_PATH:-} \
      cmake --build build --target sd-server -j"$(nproc)"; \
    test -x build/bin/sd-server
RUN printf 'section-08 sd server link\n' > /build-checkpoint-08.txt

# ============================================================
# SECTION 09: SMOKE TEST
# ============================================================
FROM s08-server-link AS s09-smoke-test
WORKDIR /src/stable-diffusion.cpp
RUN set -eux; \
    file build/bin/sd-server; \
    LD_LIBRARY_PATH=/usr/local/lib/cuda-stubs:/usr/local/cuda/lib64/stubs:${LD_LIBRARY_PATH:-} \
      ldd build/bin/sd-server | tee /sd-server.ldd; \
    if grep -q 'not found' /sd-server.ldd; then cat /sd-server.ldd; exit 1; fi
RUN printf 'section-09 smoke test\n' > /build-checkpoint-09.txt

# ============================================================
# SECTION 10: RUNTIME BASE
# ============================================================
FROM nvidia/cuda:${CUDA_VERSION}-runtime-ubuntu${UBUNTU_VERSION} AS s10-runtime-base
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
      python3 python3-pip ca-certificates curl libgomp1 libwebp7 \
    && rm -rf /var/lib/apt/lists/*
RUN printf 'section-10 runtime base\n' > /build-checkpoint-10.txt

# ============================================================
# SECTION 11: PYTHON DEPS
# ============================================================
FROM s10-runtime-base AS s11-python-deps
WORKDIR /opt/appliance
COPY requirements.txt /opt/appliance/requirements.txt
RUN python3 -m pip install --break-system-packages --no-cache-dir -r /opt/appliance/requirements.txt
RUN printf 'section-11 python deps\n' > /build-checkpoint-11.txt

# ============================================================
# SECTION 12: APP SOURCE
# ============================================================
FROM s11-python-deps AS s12-app-source
WORKDIR /opt/appliance
COPY app /opt/appliance/app
RUN printf 'section-12 app source\n' > /build-checkpoint-12.txt

# ============================================================
# SECTION 13: FINAL RUNTIME
# ============================================================
FROM s12-app-source AS s13-runtime
WORKDIR /opt/appliance
COPY --from=s09-smoke-test /src/stable-diffusion.cpp/build/bin/sd-server /usr/local/bin/sd-server
COPY --from=s09-smoke-test /src/stable-diffusion.cpp/build/bin/*.so* /usr/local/lib/sdcpp/
COPY --from=s09-smoke-test /stable-diffusion-cpp-commit.txt /opt/appliance/stable-diffusion-cpp-commit.txt
COPY --from=s09-smoke-test /cuda-architectures.txt /opt/appliance/cuda-architectures.txt
ENV LD_LIBRARY_PATH=/usr/local/lib/sdcpp:${LD_LIBRARY_PATH}
ENV MODEL_PATHS=/models \
    CONFIG_DIR=/config \
    RESULTS_DIR=/results \
    SD_SERVER=/usr/local/bin/sd-server \
    TEST_PORT=8080 \
    SETTINGS_PORT=8081 \
    QUEUE_PORT=8082 \
    INTERNAL_ENGINE_PORT=8083 \
    PYTHONUNBUFFERED=1
VOLUME ["/models", "/config", "/results"]
EXPOSE 8080 8081 8082
STOPSIGNAL SIGTERM
ENTRYPOINT ["python3", "/opt/appliance/app/main.py"]
