-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
200 lines (169 loc) · 8.88 KB
/
Containerfile
File metadata and controls
200 lines (169 loc) · 8.88 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
# --------------------------------------------------------------------------
# THIS FILE IS AUTOGENERATED - DO NOT EDIT MANUALLY
#
# Source: Containerfile.j2
# --------------------------------------------------------------------------
ARG BASE_VERSION=15
ARG UPSTREAM_URL="https://api.github.com/repos/immich-app/immich/releases/latest"
# Pull Linux image for pre-built corePlugin WASM (extism-js has no FreeBSD release)
FROM --platform=linux/amd64 ghcr.io/immich-app/immich-server:release AS linux-immich
# Jellyfin FFmpeg builder (HDR tonemapping support for immich thumbnails)
FROM ghcr.io/daemonless/base:${BASE_VERSION} AS jffmpeg-builder
RUN pkg update && pkg install -y \
FreeBSD-bmake FreeBSD-clibs-dev FreeBSD-clang FreeBSD-clang-dev FreeBSD-toolchain \
FreeBSD-utilities-dev FreeBSD-runtime-dev \
FreeBSD-zlib-dev FreeBSD-bzip2-dev FreeBSD-openssl-dev FreeBSD-xz-dev \
nasm vulkan-headers quilt pkgconf gmake perl5 \
libass libbluray chromaprint dav1d fdk-aac fontconfig freetype2 \
fribidi gmp harfbuzz lame libopenmpt opus libplacebo shaderc \
svt-av1 libtheora libvorbis libvpx vulkan-loader webp libx264 x265 \
sekrit-twc-zimg libzvbi gnutls libxml2 libiconv libva libdrm \
libvdpau libX11 alsa-lib sndio \
&& pkg clean -ay
RUN pkg install -y git && \
fetch -qo /tmp/ports.tar.zst \
"https://download.freebsd.org/ports/ports/ports.tar.zst" && \
mkdir -p /usr/ports/multimedia && \
tar -xf /tmp/ports.tar.zst -C /usr/ports --strip-components=1 \
ports/Mk ports/Templates ports/Keywords && \
rm /tmp/ports.tar.zst && \
git clone --depth=1 https://github.com/daemonless/freebsd-ports.git /tmp/freebsd-ports && \
cp -r /tmp/freebsd-ports/multimedia/jellyfin-ffmpeg /usr/ports/multimedia/ && \
rm -rf /tmp/freebsd-ports
WORKDIR /usr/ports/multimedia/jellyfin-ffmpeg
RUN make BATCH=yes MAKE_JOBS_NUMBER=4 install clean || \
(cat /usr/ports/multimedia/jellyfin-ffmpeg/work/jellyfin-ffmpeg-7.1.3-3/ffbuild/config.log && false)
RUN mkdir -p /tmp/packages && pkg create -o /tmp/packages/ jellyfin-ffmpeg
FROM ghcr.io/daemonless/base:${BASE_VERSION} AS builder
ARG UPSTREAM_URL
# Build dependencies (including C++ compiler and headers for native modules)
# FreeBSD base dev packages needed for pkg-config: openssl, zlib, xz (lzma), bzip2
RUN pkg update && pkg install -y \
jq \
node22 npm-node22 \
git-lite gmake pkgconf \
FreeBSD-clang FreeBSD-clibs-dev \
FreeBSD-openssl-dev FreeBSD-zlib-dev FreeBSD-xz-dev FreeBSD-bzip2-dev \
python311 \
vips \
ffmpeg \
p5-Image-ExifTool \
libheif \
libraw \
webp \
&& pkg clean -ay
# Set up compiler symlinks for node-gyp
RUN ln -sf /usr/bin/clang++ /usr/bin/c++ && \
ln -sf /usr/bin/clang /usr/bin/cc
# Enable corepack for pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Clone immich source (resolve latest version from upstream)
WORKDIR /build
RUN --mount=type=secret,id=github_token \
FETCH_URL="${UPSTREAM_URL}"; \
GITHUB_TOKEN=$(cat /run/secrets/github_token 2>/dev/null || echo ""); \
if [ -n "${GITHUB_TOKEN}" ]; then \
FETCH_URL=$(echo "${UPSTREAM_URL}" | sed "s|https://|https://x-access-token:${GITHUB_TOKEN}@|"); \
fi && \
IMMICH_VERSION=$(fetch -qo - "${FETCH_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
# Build server
WORKDIR /build/server
# Patch sharp to recognize UHDR loader (libvips 8.18+)
RUN pnpm install --frozen-lockfile && \
SHARP_DIR=$(find /build/node_modules/.pnpm -name 'sharp' -type d -path '*/node_modules/sharp' | head -1) && \
sed -i '' 's/VIPS,/VIPS, UHDR,/' "$SHARP_DIR/src/common.h" && \
sed -i '' 's/{ "VipsForeignLoadJpegFile"/{ "VipsForeignLoadUhdrFile", ImageType::UHDR },\n { "VipsForeignLoadUhdrBuffer", ImageType::UHDR },\n { "VipsForeignLoadJpegFile"/' "$SHARP_DIR/src/common.cc" && \
cd "$SHARP_DIR/src" && PYTHON=/usr/local/bin/python3.11 node-gyp rebuild
RUN pnpm build
# Deploy production dependencies only
RUN pnpm deploy --filter immich --prod /app && \
SHARP_BUILD=$(find /build/node_modules/.pnpm -name 'sharp-freebsd-x64.node' -path '*/src/build/Release/*' | head -1) && \
SHARP_DEST=$(find /app/node_modules/.pnpm -name 'sharp' -type d -path '*/node_modules/sharp' | head -1) && \
mkdir -p "$SHARP_DEST/src/build/Release" && \
cp "$SHARP_BUILD" "$SHARP_DEST/src/build/Release/"
# Build web UI (increase heap for vite build)
WORKDIR /build
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN pnpm --filter @immich/sdk --filter immich-web install --frozen-lockfile
RUN pnpm --filter @immich/sdk --filter immich-web build
RUN mkdir -p /app/www && cp -r /build/web/build/* /app/www/
# Copy pre-built corePlugin from Linux image (extism-js doesn't have FreeBSD releases)
# The WASM plugin is platform-independent, so we can use the Linux build
COPY --from=linux-immich /build/corePlugin /app/corePlugin
# Download geodata for reverse geocoding
RUN mkdir -p /app/geodata && \
fetch -o /app/geodata/admin1CodesASCII.txt https://download.geonames.org/export/dump/admin1CodesASCII.txt && \
fetch -o /app/geodata/admin2Codes.txt https://download.geonames.org/export/dump/admin2Codes.txt && \
fetch -o /app/geodata/cities500.zip https://download.geonames.org/export/dump/cities500.zip && \
unzip -o /app/geodata/cities500.zip -d /app/geodata && \
rm /app/geodata/cities500.zip && \
fetch -o /app/geodata/ne_10m_admin_0_countries.geojson "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_10m_admin_0_countries.geojson" && \
date +%Y-%m-%d > /app/geodata/geodata-date.txt
# Production image
FROM ghcr.io/daemonless/base:${BASE_VERSION}
ARG FREEBSD_ARCH=amd64
ARG PACKAGES="node22 vips ffmpeg p5-Image-ExifTool libheif libraw webp alsa-lib sndio sekrit-twc-zimg libopenmpt chromaprint libzvbi fdk-aac libtheora"
ARG UPSTREAM_URL="https://api.github.com/repos/immich-app/immich/releases/latest"
ARG UPSTREAM_JQ=".tag_name"
ARG HEALTHCHECK_ENDPOINT="http://localhost:2283/api/server-info/ping"
ENV HEALTHCHECK_URL="${HEALTHCHECK_ENDPOINT}"
# --- Metadata (Injected by Generator) ---
LABEL org.opencontainers.image.title="Immich Server" \
org.opencontainers.image.description="Self-hosted photo and video backup and management server with web UI, mobile sync, and shared albums." \
org.opencontainers.image.source="https://github.com/daemonless/immich-server" \
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="2283" \
io.daemonless.volumes="/config,/data" \
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} && \
mkdir -p /app && \
pkg clean -ay && \
rm -rf /var/cache/pkg/* /var/db/pkg/repos/* && \
rm -rf /usr/local/libexec/gcc14 /usr/local/bin/lto-dump14 && \
rm -f /usr/local/lib/libopcodes* /usr/local/lib/libbfd*
# Install jellyfin-ffmpeg (HDR tonemapping) and override system ffmpeg
COPY --from=jffmpeg-builder /tmp/packages/jellyfin-ffmpeg-*.pkg /tmp/
RUN pkg add -f /tmp/jellyfin-ffmpeg-*.pkg && \
rm /tmp/jellyfin-ffmpeg-*.pkg && \
ln -sf /usr/local/lib/jellyfin-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg && \
ln -sf /usr/local/lib/jellyfin-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
# Copy version and built application from builder
COPY --from=builder /tmp/immich_version /tmp/immich_version
COPY --from=builder --chown=bsd:bsd /app /app
# Create directories, write version, and symlinks (paths match Linux immich expectations)
RUN cp /tmp/immich_version /app/version && \
mkdir -p /config /data /build && \
mkdir -p /data/{encoded-video,thumbs,upload,profile,backups,library} && \
chown -R bsd:bsd /config /data /build && \
ln -sf /app/www /build/www && \
ln -sf /app/corePlugin /build/corePlugin && \
ln -sf /app/geodata /build/geodata && \
chown -h bsd:bsd /build/www /build/corePlugin /build/geodata && \
chmod 755 /app/geodata && chmod 644 /app/geodata/*
# Copy service files
COPY root/ /
RUN chmod +x /etc/services.d/*/run /etc/cont-init.d/* 2>/dev/null || true
WORKDIR /app
ENV NODE_ENV=production
ENV LD_LIBRARY_PATH="/usr/local/lib/jellyfin-ffmpeg/lib"
ENV IMMICH_PORT=2283
ENV IMMICH_MEDIA_LOCATION=/data
# --- Expose (Injected by Generator) ---
EXPOSE 2283
# --- Volumes (Injected by Generator) ---
VOLUME /config /data