Skip to content

Commit de9e3b2

Browse files
author
Leandro
committed
examples: add Docker build example (Kagami/go-face#76)
Multi-stage build: compiles dlib from source on Alpine (which has no dlib package), builds the detection example against it (dlib links statically, so the runtime stage doesn't need it), and produces a ~50MB runtime image with just the shared libraries the compiled binary actually needs (found via a missing-library failure on the first attempt: cblas is a separate runtime package from blas on Alpine, only pulled in transitively by blas-dev at build time). Includes two patches recurring across the upstream install-error reports (e.g. Kagami/go-face#75, #79, #83, #87): dlib's released source doesn't build with GCC 15+ (missing an implicit <cstdint> include) or CMake 4.x (rejects dlib's old cmake_minimum_required() declarations) without them. Verified by actually building and running the image: all 7 faces in elenco3.jpg detected and labeled correctly inside the container.
1 parent dc76931 commit de9e3b2

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ Try installing dlib/libjpeg with your distribution's package manager, or
9393
with old dlib packages such as libdlib18. If your system isn't covered here,
9494
open an issue with the distribution/version and we'll try to help.
9595

96+
### Docker
97+
98+
[`examples/Dockerfile`](examples/Dockerfile) builds dlib from source (Alpine
99+
has no dlib package) and compiles the detection example against it, ending
100+
with a ~50MB runtime image. Useful as a reference for containerized builds,
101+
and for the compiler/CMake compatibility patches it applies -- dlib's
102+
released source doesn't build out of the box with GCC 15+ or CMake 4.x.
103+
96104
## Installation
97105

98106
```bash

examples/Dockerfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Example multi-stage build: compiles dlib from source (Alpine has no dlib
2+
# package), builds the detection example against it, and produces a slim
3+
# runtime image with only the shared libraries the compiled binary needs.
4+
#
5+
# Build:
6+
# docker build -t go-recognizer-example -f examples/Dockerfile .
7+
# Run (mount your own fotos/models directories):
8+
# docker run --rm \
9+
# -v "$(pwd)/examples/fotos":/data/fotos:ro \
10+
# -v "$(pwd)/examples/models":/data/models:ro \
11+
# -v "$(pwd)/out":/data \
12+
# go-recognizer-example
13+
14+
# ---- dlib: compile dlib from source ----
15+
FROM golang:1.25-alpine AS dlib
16+
17+
RUN apk add --no-cache \
18+
cmake make g++ libstdc++ libgcc \
19+
jpeg-dev libpng-dev giflib-dev libjpeg-turbo-dev \
20+
blas-dev lapack-dev \
21+
ca-certificates wget
22+
23+
WORKDIR /
24+
ARG DLIB_VERSION=v19.24.8
25+
26+
RUN wget -q https://github.com/davisking/dlib/archive/${DLIB_VERSION}.tar.gz \
27+
&& tar xf ${DLIB_VERSION}.tar.gz \
28+
&& mv dlib-* dlib \
29+
&& mkdir -p dlib/build \
30+
# GCC 15+ dropped some implicit <cstdint> includes dlib relies on.
31+
&& sed -i '1i#include <cstdint>' dlib/dlib/serialize.h \
32+
# CMake 4.x refuses dlib's old cmake_minimum_required() declarations.
33+
&& find dlib -type f \( -name "CMakeLists.txt" -o -name "*.cmake" \) \
34+
-exec sed -i -E 's/cmake_minimum_required\s*\(\s*VERSION\s+[0-9.]+\s*\)/cmake_minimum_required(VERSION 3.10)/gI' {} + \
35+
&& cd dlib/build \
36+
&& cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.10 \
37+
-DCMAKE_BUILD_TYPE=Release \
38+
-DDLIB_PNG_SUPPORT=ON \
39+
-DDLIB_GIF_SUPPORT=ON \
40+
-DDLIB_JPEG_SUPPORT=ON .. \
41+
&& cmake --build . --config Release -- -j"$(nproc)" \
42+
&& make install \
43+
&& cd / && rm -rf dlib ${DLIB_VERSION}.tar.gz
44+
45+
# ---- builder: compile the Go example against dlib ----
46+
FROM dlib AS builder
47+
48+
WORKDIR /src
49+
COPY examples/ ./examples/
50+
51+
WORKDIR /src/examples
52+
RUN go mod tidy \
53+
&& CGO_ENABLED=1 go build -o /out/detection ./detection
54+
55+
# ---- runtime: slim image with just the compiled binary ----
56+
FROM alpine:latest
57+
58+
# blas/cblas/lapack, libjpeg-turbo/libpng/giflib: dlib's runtime
59+
# dependencies. dlib itself is statically linked into the binary (the
60+
# cmake build above produces libdlib.a, not a .so), so it isn't needed
61+
# here.
62+
RUN apk add --no-cache \
63+
libstdc++ libgomp \
64+
libjpeg-turbo libpng giflib \
65+
blas cblas lapack
66+
67+
COPY --from=builder /out/detection /usr/local/bin/detection
68+
69+
WORKDIR /data
70+
ENTRYPOINT ["/usr/local/bin/detection"]

0 commit comments

Comments
 (0)