|
| 1 | +# syntax=docker/dockerfile:1 |
| 2 | +# |
| 3 | +# Self-contained, reproducible CUDA image built from Debian 13 (trixie). |
| 4 | +# Every artifact is hash-pinned: base by digest, apt by immutable snapshot (InRelease sha256), Node tarball and NVIDIA .debs by sha256. |
| 5 | +# No giant CUDA/cuDNN images; only the modular packages (nvcc/cudart/cublas) the ggml CUDA backend actually links are installed, so nothing above the unavoidable cuBLAS payload is fetched. |
| 6 | +# |
| 7 | +# Build (requires BuildKit, default in Docker >= 23): |
| 8 | +# docker build -f docker/Dockerfile.cuda-slim -t stable-diffusion.cpp:cuda-slim . |
| 9 | +# Run (host NVIDIA driver + nvidia-container-toolkit required). Mount a folder with your model files at /models and pass the model path via --model: |
| 10 | +# docker run --rm --gpus all -v "$PWD/models:/models" -p 80:80 stable-diffusion.cpp:cuda-slim --model /models/sd_xl_base_1.0.safetensors |
| 11 | +# docker run --rm --gpus all -v "$PWD/models:/models" --entrypoint sd-cli stable-diffusion.cpp:cuda-slim -m /models/sd_xl_base_1.0.safetensors |
| 12 | +# |
| 13 | +# CUDA-gated ARGs (rebuild to change the compiled architectures / variants): |
| 14 | +# docker build --build-arg CUDA_ARCHITECTURES="89;120" -f docker/Dockerfile.cuda-slim -t stable-diffusion.cpp:cuda-slim . |
| 15 | + |
| 16 | +########## |
| 17 | +# Builder |
| 18 | +########## |
| 19 | +FROM docker.io/library/debian:13.4-slim@sha256:109e2c65005bf160609e4ba6acf7783752f8502ad218e298253428690b9eaa4b AS builder |
| 20 | + |
| 21 | +COPY <<-EOF /etc/apt/sources.list.d/debian.sources |
| 22 | + Types: deb |
| 23 | + URIs: http://snapshot.debian.org/archive/debian/20260421T000000Z |
| 24 | + Suites: trixie trixie-updates |
| 25 | + Components: main |
| 26 | + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg |
| 27 | + |
| 28 | + Types: deb |
| 29 | + URIs: http://snapshot.debian.org/archive/debian-security/20260421T000000Z |
| 30 | + Suites: trixie-security |
| 31 | + Components: main |
| 32 | + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg |
| 33 | +EOF |
| 34 | + |
| 35 | +# Debian toolchain, pinned to the immutable snapshot (InRelease hashes below). |
| 36 | +# gcc/g++-13 = the CUDA 13.3-supported host compiler; build-essential also satisfies cuda-nvcc's own Depends before the .debs are installed. |
| 37 | +RUN --mount=type=cache,target=/var/cache/apt/archives,sharing=locked <<-EOF |
| 38 | + set -e |
| 39 | + rm -f /var/cache/apt/archives/lock |
| 40 | + rm -f /etc/apt/sources.list |
| 41 | + echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid-until |
| 42 | + apt-get update |
| 43 | + echo "15c884d9b15ba5d0737d7d728e89d5e02963e178dfe766ed28ac901f751ed80f /var/lib/apt/lists/snapshot.debian.org_archive_debian-security_20260421T000000Z_dists_trixie-security_InRelease |
| 44 | +afbe76555f36895eb644ebbf627fea7621c1299bea5af23cafc9e4d4527d8001 /var/lib/apt/lists/snapshot.debian.org_archive_debian_20260421T000000Z_dists_trixie-updates_InRelease |
| 45 | +7592e4ccb4658a58bfe485d3356b3c983bf8ccff7fca1f6091e4d4296284ed18 /var/lib/apt/lists/snapshot.debian.org_archive_debian_20260421T000000Z_dists_trixie_InRelease" | sha256sum -c |
| 46 | + apt-get install -y --no-install-recommends build-essential ca-certificates curl git cmake g++-13 |
| 47 | + rm -rf /var/lib/apt/lists/* |
| 48 | +EOF |
| 49 | + |
| 50 | +# Node 22 LTS (needed to build the server frontend). Pinned by sha256; >10MB so it is cached. |
| 51 | +RUN --mount=type=cache,target=/tmp/dl,sharing=locked <<-EOF |
| 52 | + set -e |
| 53 | + export PATH=/opt/node/bin:$PATH |
| 54 | + if [ ! -s /tmp/dl/node.tar.xz ]; then |
| 55 | + curl -fsSL --retry 10 --retry-delay 5 -o /tmp/dl/node.tar.xz 'https://nodejs.org/dist/v22.23.2/node-v22.23.2-linux-x64.tar.xz' |
| 56 | + fi |
| 57 | + echo 'd60acfe00a2932254bb0ad20e01b0d74397a0875595de719654b214f4b03f307 /tmp/dl/node.tar.xz' | sha256sum -c |
| 58 | + if [ ! -d /opt/node ]; then |
| 59 | + tar -xJf /tmp/dl/node.tar.xz -C /tmp/dl |
| 60 | + mv /tmp/dl/node-v22.23.2-linux-x64 /opt/node |
| 61 | + fi |
| 62 | + node --version |
| 63 | + npm install -g pnpm@10.15.1 |
| 64 | +EOF |
| 65 | +ENV PATH=/opt/node/bin:$PATH |
| 66 | + |
| 67 | +# Modular NVIDIA CUDA 13.3 debs (dev toolchain for ggml's CUDA backend). |
| 68 | +# Manifest is `<sha256> <url>` in dpkg dependency order; downloading and sha256-checking every artifact makes the fetch resumable and pinned. |
| 69 | +COPY <<-EOF /cuda.lock |
| 70 | + 7fb49a9a684e97f48374c230b7a548cee61f62ff925d09238f038aba601dbdb2 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cccl-13-3_13.3.3.4.1-1_amd64.deb |
| 71 | + 145419ba2fc00ce07fc254aa28780aa9c8a7a5be3b57852919d9baf16db00c20 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-crt-13-3_13.3.73-1_amd64.deb |
| 72 | + d3c825bfd40d6be5293854ea140cffdd66e66845be6595fc76e03c1240085ce8 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-cudart-13-3_13.3.29-1_amd64.deb |
| 73 | + 600e5cf3685d0afae85970ba02451358068b7b56c954999b9149900ec5d940d9 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-cudart-dev-13-3_13.3.29-1_amd64.deb |
| 74 | + db20e2e39cfa3a570581df1534de3a31810e9db5b8454b7605a333c07c677d90 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-culibos-dev-13-3_13.3.33-1_amd64.deb |
| 75 | + 9ff314357a66e7602d0fe9a354052f60f7571138e9d4e1e98f3dd06cd899e021 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-driver-dev-13-3_13.3.29-1_amd64.deb |
| 76 | + b0691b6c6e700ee023aa1cbc7a72dd0afaaacbb2dc788eff0b1aa5033ef57639 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-nvcc-13-3_13.3.73-1_amd64.deb |
| 77 | + c71420541f81628f551cb26ab91ca4dfb2458f118d11c538ccf3dcc548e6abcf https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-13-3-config-common_13.3.29-1_all.deb |
| 78 | + 7177da13bf1d6e33ad591b7f79602665f2af3aaf1bc9306809b830c1650218a6 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-13-config-common_13.3.29-1_all.deb |
| 79 | + a0ed2214ecf40c980a5a215fde943255da103c32695b004ad7efc7df622a5e30 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-config-common_13.3.29-1_all.deb |
| 80 | + 42ce8b29846fabcc224e46b80efc805c6d5a4bf7f3bc3f1480fe3feecd00d70a https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/libcublas-13-3_13.6.0.2-1_amd64.deb |
| 81 | + 043ba517dd5b64973e4a12c340d6e1085122ac931a4e68ae960201d6142ac6f5 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/libcublas-dev-13-3_13.6.0.2-1_amd64.deb |
| 82 | + 1e381ce2834f15512c95729a0e49e540c899c6a08d90d6da009461430b85b48e https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/libnvptxcompiler-13-3_13.3.73-1_amd64.deb |
| 83 | + ec1330e0fb4d4e789609bc273f38dcbb577fd5d8726601d237b6f78075ba80f1 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/libnvvm-13-3_13.3.73-1_amd64.deb |
| 84 | +EOF |
| 85 | + |
| 86 | +# Download, verify and install exactly the set in /cuda.lock (not a glob: the |
| 87 | +# cache mount is shared with the runtime stage). dpkg resolves install order. |
| 88 | +RUN --mount=type=cache,target=/tmp/cuda,sharing=locked <<-EOF |
| 89 | + set -e |
| 90 | + cd /tmp/cuda |
| 91 | + pkgs= |
| 92 | + while read -r sha url; do |
| 93 | + [ -n "$sha" ] || continue |
| 94 | + fn=${url##*/} |
| 95 | + if [ ! -s "$fn" ]; then |
| 96 | + curl -fsSL --retry 10 --retry-delay 5 -o "$fn" "$url" |
| 97 | + fi |
| 98 | + echo "$sha /tmp/cuda/$fn" | sha256sum -c |
| 99 | + pkgs="$pkgs $fn" |
| 100 | + done < /cuda.lock |
| 101 | + # shellcheck disable=SC2086 |
| 102 | + dpkg -i $pkgs |
| 103 | + rm /cuda.lock |
| 104 | + /usr/local/cuda/bin/nvcc --version |
| 105 | +EOF |
| 106 | +ENV CUDACXX=/usr/local/cuda/bin/nvcc |
| 107 | + |
| 108 | +WORKDIR /sd.cpp |
| 109 | + |
| 110 | +# Copy only the C++ build inputs so the heavy compile below is not invalidated by web-UI source edits. |
| 111 | +# The web UI (examples/server/frontend) is copied in a later, separate layer and served from disk at runtime. |
| 112 | +# NOTE: if new C++ server source files are added, the server globs below must be extended to match them. |
| 113 | +# NOTE: a trailing-slash dest copies *directory* contents into that dir, flattening them |
| 114 | +# and letting a copied file (e.g. thirdparty/CMakeLists.txt) collide with the root file. |
| 115 | +# Directory sources must get their own dest path (no trailing slash) to keep the layout. |
| 116 | +COPY CMakeLists.txt /sd.cpp/CMakeLists.txt |
| 117 | +COPY cmake /sd.cpp/cmake |
| 118 | +COPY ggml /sd.cpp/ggml |
| 119 | +COPY include /sd.cpp/include |
| 120 | +COPY src /sd.cpp/src |
| 121 | +COPY thirdparty /sd.cpp/thirdparty |
| 122 | +COPY examples/CMakeLists.txt /sd.cpp/examples/CMakeLists.txt |
| 123 | +COPY examples/common /sd.cpp/examples/common |
| 124 | +COPY examples/cli /sd.cpp/examples/cli |
| 125 | +COPY examples/server/CMakeLists.txt /sd.cpp/examples/server/CMakeLists.txt |
| 126 | +COPY examples/server/*.cpp /sd.cpp/examples/server/ |
| 127 | +COPY examples/server/*.h /sd.cpp/examples/server/ |
| 128 | + |
| 129 | +ARG CUDA_ARCHITECTURES="" |
| 130 | +ARG GGML_CUDA_FA_ALL_QUANTS="" |
| 131 | +ARG GGML_CUDA_ENABLE_DYNAMIC_CPU_BACKENDS=ON |
| 132 | + |
| 133 | +# Heavy compile: every CUDA kernel and C++ object, plus sd-cli and sd-server (UI is served from disk at runtime, so SD_SERVER_BUILD_FRONTEND stays OFF). |
| 134 | +# Any change that is not in the web UI keeps this layer cached, so a UI-only edit does not recompile CUDA/C++. |
| 135 | +RUN <<-EOF |
| 136 | + set -e |
| 137 | + set -- \ |
| 138 | + -DSD_CUDA=ON \ |
| 139 | + -DGGML_NATIVE=OFF \ |
| 140 | + -DCMAKE_CUDA_HOST_COMPILER=/usr/bin/g++-13 \ |
| 141 | + -DSD_SERVER_BUILD_FRONTEND=OFF |
| 142 | + if [ "${GGML_CUDA_ENABLE_DYNAMIC_CPU_BACKENDS}" = "ON" ]; then |
| 143 | + rpath='$ORIGIN' |
| 144 | + set -- "$@" \ |
| 145 | + -DSD_BUILD_SHARED_LIBS=ON \ |
| 146 | + -DGGML_NATIVE=OFF \ |
| 147 | + -DSD_BUILD_SHARED_GGML_LIB=ON \ |
| 148 | + -DGGML_BACKEND_DL=ON \ |
| 149 | + -DGGML_CPU_ALL_VARIANTS=ON \ |
| 150 | + -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \ |
| 151 | + "-DCMAKE_INSTALL_RPATH=$rpath" |
| 152 | + fi |
| 153 | + if [ -n "${CUDA_ARCHITECTURES}" ]; then |
| 154 | + set -- "$@" "-DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCHITECTURES}" |
| 155 | + fi |
| 156 | + if [ -n "${GGML_CUDA_FA_ALL_QUANTS}" ]; then |
| 157 | + set -- "$@" "-DGGML_CUDA_FA_ALL_QUANTS=${GGML_CUDA_FA_ALL_QUANTS}" |
| 158 | + fi |
| 159 | + cmake . -B ./build "$@" |
| 160 | + cmake --build ./build --config Release -j$(nproc) |
| 161 | + # Fail here (in the builder) rather than later at a cross-stage COPY --from=builder, |
| 162 | + # so a missing/moved binary output is diagnosed where it is produced. |
| 163 | + test -x /sd.cpp/build/bin/sd-cli |
| 164 | + test -x /sd.cpp/build/bin/sd-server |
| 165 | +EOF |
| 166 | + |
| 167 | +# Web UI dependencies only invalidates when the manifest/lockfile changes |
| 168 | +WORKDIR /sd.cpp/examples/server/frontend |
| 169 | +COPY examples/server/frontend/package.json examples/server/frontend/pnpm-lock.yaml /sd.cpp/examples/server/frontend/ |
| 170 | +RUN --mount=type=cache,target=/root/.local/share/pnpm,sharing=locked pnpm install |
| 171 | + |
| 172 | +# Web UI source (only what the build needs: Vite/tsconfig, the entry HTML, and src/). |
| 173 | +# NOTE: if new files are added to the frontend build, extend the lists below. |
| 174 | +COPY examples/server/frontend/vite.config.js examples/server/frontend/tsconfig.json examples/server/frontend/index.html /sd.cpp/examples/server/frontend/ |
| 175 | +COPY examples/server/frontend/src /sd.cpp/examples/server/frontend/src |
| 176 | + |
| 177 | +# Build the UI (uses the deps installed above), producing dist/index.html. |
| 178 | +RUN --mount=type=cache,target=/root/.local/share/pnpm,sharing=locked pnpm run build |
| 179 | + |
| 180 | +########## |
| 181 | +# Runtime |
| 182 | +########## |
| 183 | +FROM docker.io/library/debian:13.4-slim@sha256:109e2c65005bf160609e4ba6acf7783752f8502ad218e298253428690b9eaa4b |
| 184 | + |
| 185 | +COPY <<-EOF /etc/apt/sources.list.d/debian.sources |
| 186 | + Types: deb |
| 187 | + URIs: http://snapshot.debian.org/archive/debian/20260421T000000Z |
| 188 | + Suites: trixie trixie-updates |
| 189 | + Components: main |
| 190 | + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg |
| 191 | + |
| 192 | + Types: deb |
| 193 | + URIs: http://snapshot.debian.org/archive/debian-security/20260421T000000Z |
| 194 | + Suites: trixie-security |
| 195 | + Components: main |
| 196 | + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg |
| 197 | +EOF |
| 198 | + |
| 199 | +# libgomp1 = OpenMP runtime for the ggml CPU backends; ca-certificates/curl = TLS for the pinned NVIDIA runtime debs fetched next. |
| 200 | +RUN --mount=type=cache,target=/var/cache/apt/archives,sharing=locked <<-EOF |
| 201 | + set -e |
| 202 | + rm -f /var/cache/apt/archives/lock |
| 203 | + rm -f /etc/apt/sources.list |
| 204 | + echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid-until |
| 205 | + apt-get update |
| 206 | + echo "15c884d9b15ba5d0737d7d728e89d5e02963e178dfe766ed28ac901f751ed80f /var/lib/apt/lists/snapshot.debian.org_archive_debian-security_20260421T000000Z_dists_trixie-security_InRelease |
| 207 | +afbe76555f36895eb644ebbf627fea7621c1299bea5af23cafc9e4d4527d8001 /var/lib/apt/lists/snapshot.debian.org_archive_debian_20260421T000000Z_dists_trixie-updates_InRelease |
| 208 | +7592e4ccb4658a58bfe485d3356b3c983bf8ccff7fca1f6091e4d4296284ed18 /var/lib/apt/lists/snapshot.debian.org_archive_debian_20260421T000000Z_dists_trixie_InRelease" | sha256sum -c |
| 209 | + apt-get install -y --no-install-recommends libgomp1 tini ca-certificates curl |
| 210 | + rm -rf /var/lib/apt/lists/* |
| 211 | +EOF |
| 212 | + |
| 213 | +# CUDA runtime libs only (cudart + cuBLAS); no cuDNN, no toolkit. |
| 214 | +COPY <<-EOF /cuda.lock |
| 215 | + d3c825bfd40d6be5293854ea140cffdd66e66845be6595fc76e03c1240085ce8 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-cudart-13-3_13.3.29-1_amd64.deb |
| 216 | + c71420541f81628f551cb26ab91ca4dfb2458f118d11c538ccf3dcc548e6abcf https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-13-3-config-common_13.3.29-1_all.deb |
| 217 | + 7177da13bf1d6e33ad591b7f79602665f2af3aaf1bc9306809b830c1650218a6 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-13-config-common_13.3.29-1_all.deb |
| 218 | + a0ed2214ecf40c980a5a215fde943255da103c32695b004ad7efc7df622a5e30 https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-toolkit-config-common_13.3.29-1_all.deb |
| 219 | + 42ce8b29846fabcc224e46b80efc805c6d5a4bf7f3bc3f1480fe3feecd00d70a https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/libcublas-13-3_13.6.0.2-1_amd64.deb |
| 220 | +EOF |
| 221 | + |
| 222 | +RUN --mount=type=cache,target=/tmp/cuda,sharing=locked <<-EOF |
| 223 | + set -e |
| 224 | + cd /tmp/cuda |
| 225 | + pkgs= |
| 226 | + while read -r sha url; do |
| 227 | + [ -n "$sha" ] || continue |
| 228 | + fn=${url##*/} |
| 229 | + if [ ! -s "$fn" ]; then |
| 230 | + curl -fsSL --retry 10 --retry-delay 5 -o "$fn" "$url" |
| 231 | + fi |
| 232 | + echo "$sha /tmp/cuda/$fn" | sha256sum -c |
| 233 | + pkgs="$pkgs $fn" |
| 234 | + done < /cuda.lock |
| 235 | + # shellcheck disable=SC2086 |
| 236 | + dpkg -i $pkgs |
| 237 | + rm /cuda.lock |
| 238 | + apt-get purge -y curl ca-certificates |
| 239 | + apt-get autoremove -y |
| 240 | + apt-get clean |
| 241 | + rm -rf /var/lib/apt/lists/* |
| 242 | +EOF |
| 243 | + |
| 244 | +COPY --from=builder /sd.cpp/build/bin /sd.cpp/bin |
| 245 | + |
| 246 | +# Web UI built in the builder stage; served from disk at runtime so the UI and |
| 247 | +# the C++ binaries are built independently and never baked into the binary. |
| 248 | +COPY --from=builder /sd.cpp/examples/server/frontend/dist/index.html /sd.cpp/ui/index.html |
| 249 | + |
| 250 | +ENV PATH=/sd.cpp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
| 251 | +WORKDIR /sd.cpp |
| 252 | +EXPOSE 80 |
| 253 | +VOLUME [ "/models" ] |
| 254 | +ENTRYPOINT [ "tini", "--", "sd-server", "--listen-ip", "0.0.0.0", "--listen-port", "80", "--serve-html-path", "/sd.cpp/ui/index.html" ] |
0 commit comments