-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
201 lines (173 loc) · 8.49 KB
/
Copy pathContainerfile
File metadata and controls
201 lines (173 loc) · 8.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# --------------------------------------------------------------------------
# THIS FILE IS AUTOGENERATED - DO NOT EDIT MANUALLY
#
# Source: Containerfile.j2
# --------------------------------------------------------------------------
ARG BASE_VERSION=15.1-latest
ARG UPSTREAM_URL="https://api.github.com/repos/immich-app/immich/releases/latest"
ARG ONNXRUNTIME_RELEASES_API="https://api.github.com/repos/daemonless/immich-ml/releases"
FROM ghcr.io/daemonless/base:${BASE_VERSION} AS builder
ARG UPSTREAM_URL
ARG ONNXRUNTIME_RELEASES_API
# Build dependencies
RUN pkg update && pkg install -y \
jq \
python312 py312-pip py312-setuptools py312-wheel \
py312-numpy py312-pillow py312-orjson py312-scipy py312-scikit-learn py312-scikit-image \
py312-pydantic2 py312-pydantic-settings \
py312-fastapi py312-uvicorn py312-gunicorn \
py312-huggingface-hub py312-tokenizers \
py312-onnx \
py312-albumentations py312-albucore \
git-lite gmake pkgconf \
FreeBSD-clang FreeBSD-clibs-dev FreeBSD-clang-dev FreeBSD-utilities-dev \
opencv cmake ninja \
openblas gcc \
distcc ccache \
&& pkg clean -ay
# Configure ccache + distcc
ENV CCACHE_DIR=/data/ccache
ENV CCACHE_PREFIX=distcc
ARG DISTCC_HOSTS="localhost"
ENV DISTCC_HOSTS=${DISTCC_HOSTS}
ENV PATH="/usr/local/libexec/ccache:$PATH"
ENV CCACHE_PATH="/usr/bin:/usr/local/bin"
ENV CC="/usr/local/libexec/ccache/clang"
ENV CXX="/usr/local/libexec/ccache/clang++"
ENV CMAKE_C_COMPILER="/usr/local/libexec/ccache/clang"
ENV CMAKE_CXX_COMPILER="/usr/local/libexec/ccache/clang++"
# Download pre-built onnxruntime wheel (auto-detect latest release)
RUN --mount=type=secret,id=github_token \
GITHUB_TOKEN=$(cat /run/secrets/github_token 2>/dev/null || echo "") && \
if [ -n "${GITHUB_TOKEN}" ]; then \
printf 'machine api.github.com login x-access-token password %s\nmachine github.com login x-access-token password %s\n' \
"${GITHUB_TOKEN}" "${GITHUB_TOKEN}" > /root/.netrc && \
chmod 600 /root/.netrc; \
fi && \
ONNX_TAG=$(fetch -qo - "${ONNXRUNTIME_RELEASES_API}" | jq -r '[.[] | select(.tag_name | startswith("onnxruntime-"))] | first | .tag_name') && \
ONNX_VERSION=$(echo "${ONNX_TAG}" | sed 's/onnxruntime-//') && \
WHEEL="onnxruntime-${ONNX_VERSION}-cp312-cp312-freebsd_15_1_release_amd64.whl" && \
echo "Downloading onnxruntime ${ONNX_VERSION}" && \
fetch -o /tmp/onnxruntime.whl "https://github.com/daemonless/immich-ml/releases/download/${ONNX_TAG}/${WHEEL}" && \
rm -f /root/.netrc
# Create virtual environment with system packages
RUN python3.12 -m venv --system-site-packages /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
ENV VIRTUAL_ENV="/opt/venv"
# Upgrade pip and install onnxruntime wheel
RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
bsdtar -xf /tmp/onnxruntime.whl -C /opt/venv/lib/python3.12/site-packages/ && \
rm -f /tmp/onnxruntime.whl
# Clone immich source (resolve latest version from upstream)
WORKDIR /build
RUN --mount=type=secret,id=github_token \
GITHUB_TOKEN=$(cat /run/secrets/github_token 2>/dev/null || echo "") && \
if [ -n "${GITHUB_TOKEN}" ]; then \
printf 'machine api.github.com login x-access-token password %s\n' "${GITHUB_TOKEN}" > /root/.netrc && \
chmod 600 /root/.netrc; \
fi && \
IMMICH_VERSION=$(fetch -qo - "${UPSTREAM_URL}" | jq -r '.tag_name') && \
echo "Resolved IMMICH_VERSION=$IMMICH_VERSION" && \
git clone --depth 1 --branch ${IMMICH_VERSION} \
https://github.com/immich-app/immich.git . && \
echo "${IMMICH_VERSION}" > /tmp/immich_version && \
rm -f /root/.netrc
WORKDIR /build/machine-learning
# Install remaining dependencies not available from ports
# Note: py312-numpy on 15.1-latest is numpy 2.x (2.4.6). immich-ml previously
# ran on numpy<2 (py311-numpy 1.26.4); onnxruntime cp312 is built against the
# same latest/py312 numpy, so they're consistent — watch for numpy-2 runtime issues.
RUN pip install --no-cache-dir \
aiocache \
ftfy \
python-multipart \
rich
# Install insightface for face recognition
RUN pip install --no-cache-dir --no-deps insightface && \
pip install --no-cache-dir prettytable easydict cython
# Patch pyproject.toml for FreeBSD compatibility
RUN sed -i '' 's/uvicorn[standard]/uvicorn/g' pyproject.toml && \
sed -i '' '/opencv-python-headless/d' pyproject.toml
# Install the app
RUN pip install --no-cache-dir --no-deps . && \
pip install --no-cache-dir --no-deps rapidocr && \
pip install --no-cache-dir \
starlette \
httptools \
omegaconf \
colorlog \
requests \
pyclipper \
shapely \
pyyaml
# https://github.com/immich-app/immich/pull/28610
COPY patches/immich-28610-ocr-model_root_dir.patch /tmp/immich-28610.patch
RUN patch -d /opt/venv/lib/python3.12/site-packages -p1 < /tmp/immich-28610.patch && rm /tmp/immich-28610.patch
# Production image
FROM ghcr.io/daemonless/base:${BASE_VERSION}
ARG FREEBSD_ARCH=amd64
ARG ONNXRUNTIME_RELEASES_API
ARG PACKAGES="python312 py312-numpy py312-pillow py312-orjson py312-scipy py312-scikit-learn py312-scikit-image py312-pydantic2 py312-pydantic-settings py312-fastapi py312-uvicorn py312-gunicorn py312-huggingface-hub py312-tokenizers py312-onnx py312-albumentations py312-albucore openblas geos opencv"
ARG UPSTREAM_URL="https://api.github.com/repos/immich-app/immich/releases/latest"
ARG UPSTREAM_JQ=".tag_name"
ARG HEALTHCHECK_ENDPOINT="http://localhost:3003/ping"
ENV HEALTHCHECK_URL="${HEALTHCHECK_ENDPOINT}"
# --- Metadata (Injected by Generator) ---
LABEL org.opencontainers.image.title="Immich Machine Learning" \
org.opencontainers.image.description="Machine learning service for Immich — handles facial recognition, image classification, and semantic search using ONNX models." \
org.opencontainers.image.source="https://github.com/daemonless/immich-ml" \
org.opencontainers.image.url="https://immich.app/" \
org.opencontainers.image.version="latest" \
org.opencontainers.image.licenses="AGPL-3.0" \
org.opencontainers.image.vendor="daemonless" \
org.opencontainers.image.authors="daemonless" \
io.daemonless.category="Photos & Media" \
io.daemonless.port="3003" \
io.daemonless.volumes="/cache,/config" \
io.daemonless.arch="${FREEBSD_ARCH}" \
io.daemonless.upstream-url="${UPSTREAM_URL}" \
io.daemonless.upstream-jq="${UPSTREAM_JQ}" \
io.daemonless.healthcheck-url="${HEALTHCHECK_ENDPOINT}" \
io.daemonless.packages="${PACKAGES}"
# Install runtime dependencies
RUN pkg update && \
pkg install -y ${PACKAGES} && \
pkg clean -ay && \
rm -rf /var/cache/pkg/* /var/db/pkg/repos/*
# Copy virtual environment from builder (root-owned, world-readable)
COPY --from=builder /opt/venv /opt/venv
# Install onnxruntime wheel into venv (auto-detect latest release)
RUN --mount=type=secret,id=github_token \
GITHUB_TOKEN=$(cat /run/secrets/github_token 2>/dev/null || echo "") && \
if [ -n "${GITHUB_TOKEN}" ]; then \
printf 'machine api.github.com login x-access-token password %s\nmachine github.com login x-access-token password %s\n' \
"${GITHUB_TOKEN}" "${GITHUB_TOKEN}" > /root/.netrc && \
chmod 600 /root/.netrc; \
fi && \
ONNX_TAG=$(fetch -qo - "${ONNXRUNTIME_RELEASES_API}" | python3.12 -c "import sys,json; releases=[r for r in json.load(sys.stdin) if r['tag_name'].startswith('onnxruntime-')]; print(releases[0]['tag_name'])") && \
ONNX_VERSION=$(echo "${ONNX_TAG}" | sed 's/onnxruntime-//') && \
WHEEL="onnxruntime-${ONNX_VERSION}-cp312-cp312-freebsd_15_1_release_amd64.whl" && \
echo "Downloading onnxruntime ${ONNX_VERSION}" && \
fetch -o /tmp/onnxruntime.whl "https://github.com/daemonless/immich-ml/releases/download/${ONNX_TAG}/${WHEEL}" && \
bsdtar -xf /tmp/onnxruntime.whl -C /opt/venv/lib/python3.12/site-packages/ && \
rm -f /tmp/onnxruntime.whl /root/.netrc
# Copy version from builder
COPY --from=builder /tmp/immich_version /tmp/immich_version
# Create directories, write version, and fix permissions
RUN mkdir -p /config /cache /app && \
cp /tmp/immich_version /app/version && \
chown bsd:bsd /config /cache && \
chmod -R a+rX /opt/venv
# Copy service files
COPY root/ /
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* 2>/dev/null || true
ENV PATH="/opt/venv/bin:$PATH"
ENV VIRTUAL_ENV="/opt/venv"
ENV MACHINE_LEARNING_HOST=0.0.0.0
ENV MACHINE_LEARNING_PORT=3003
ENV MACHINE_LEARNING_CACHE_FOLDER=/cache
ENV SKIP_CHOWN=true
# --- Expose (Injected by Generator) ---
EXPOSE 3003
# --- Volumes (Injected by Generator) ---
VOLUME /cache /config