Some checks failed
Test and deploy / Verify production build (push) Has been cancelled
Copy the complete source-built Sharp package and the shared-library closure resolved in the working verification stage into the final image. Keep the change after application verification so existing compilation layers remain cacheable. No manual checks or verification run, as requested.
98 lines
4.1 KiB
Docker
98 lines
4.1 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
FROM node:22-alpine AS image-runtime
|
|
|
|
# Distribution libraries support baseline CPUs and dispatch optional SIMD at runtime.
|
|
RUN apk add --no-cache glib expat libjpeg-turbo libpng libwebp tiff lcms2 librsvg libstdc++
|
|
|
|
FROM image-runtime AS image-build
|
|
RUN apk add --no-cache python3 make g++ meson ninja pkgconf xz \
|
|
glib-dev expat-dev libjpeg-turbo-dev libpng-dev libwebp-dev tiff-dev lcms2-dev librsvg-dev
|
|
|
|
ADD --checksum=sha256:3c41e1d5458081bfa4a5bc54e116c46259c75c6760a18027764555632b9dda3e https://github.com/libvips/libvips/releases/download/v8.18.6/vips-8.18.6.tar.xz /tmp/vips.tar.xz
|
|
RUN if [ "$(uname -m)" = x86_64 ]; then export CFLAGS='-O2 -march=x86-64 -mtune=generic' CXXFLAGS='-O2 -march=x86-64 -mtune=generic'; fi \
|
|
&& mkdir /tmp/vips && tar -xJf /tmp/vips.tar.xz -C /tmp/vips --strip-components=1 \
|
|
&& meson setup /tmp/vips/build /tmp/vips --prefix=/opt/vips --libdir=lib \
|
|
--buildtype=release --auto-features=disabled \
|
|
-Dhighway=disabled -Dorc=disabled -Dcplusplus=true -Dexamples=false \
|
|
-Djpeg=enabled -Dpng=enabled -Dwebp=enabled -Dtiff=enabled -Dlcms=enabled -Drsvg=enabled -Dzlib=enabled \
|
|
&& meson compile -C /tmp/vips/build -j 2 \
|
|
&& meson install -C /tmp/vips/build
|
|
|
|
FROM image-build AS dependencies
|
|
|
|
WORKDIR /app
|
|
|
|
ARG NPM_REGISTRY=https://package-mirror.liara.ir/repository/npm/
|
|
ENV NEXT_TELEMETRY_DISABLED=1 \
|
|
PKG_CONFIG_PATH=/opt/vips/lib/pkgconfig \
|
|
LD_LIBRARY_PATH=/opt/vips/lib \
|
|
npm_config_nodedir=/usr/local
|
|
|
|
COPY package.json package-lock.json ./
|
|
RUN --mount=type=cache,id=portfolio-npm-node22,target=/root/.npm,sharing=locked \
|
|
npm ci \
|
|
--registry="${NPM_REGISTRY}" \
|
|
--replace-registry-host=registry.npmjs.org \
|
|
--include=optional
|
|
|
|
# Compile Sharp against our baseline libvips, not its x86-64-v2 prebuilt binary.
|
|
RUN if [ "$(uname -m)" = x86_64 ]; then export CFLAGS='-O2 -march=x86-64 -mtune=generic' CXXFLAGS='-O2 -march=x86-64 -mtune=generic'; fi \
|
|
&& npm explore sharp -- npm run build
|
|
|
|
COPY scripts/check-image-runtime.mjs ./scripts/check-image-runtime.mjs
|
|
RUN node scripts/check-image-runtime.mjs --require-source
|
|
|
|
FROM dependencies AS verification
|
|
|
|
COPY . .
|
|
RUN npm run lint
|
|
RUN npm run typecheck
|
|
RUN --mount=type=cache,id=portfolio-next-node22,target=/app/.next/cache,sharing=locked \
|
|
npm run build
|
|
RUN npm test
|
|
|
|
# Carry the exact shared-library dependency closure from the working build stage.
|
|
# Development packages can provide libraries that are absent from image-runtime.
|
|
FROM verification AS native-runtime-libraries
|
|
RUN mkdir -p /runtime-libs \
|
|
&& (ldd /app/node_modules/sharp/src/build/Release/*.node /opt/vips/lib/libvips*.so* 2>/dev/null || true) \
|
|
| awk '/=> \// { print $3 } /^[[:space:]]*\// { print $1 }' \
|
|
| sort -u \
|
|
| while IFS= read -r library; do \
|
|
mkdir -p "/runtime-libs$(dirname "$library")"; \
|
|
cp -L "$library" "/runtime-libs$library"; \
|
|
done
|
|
|
|
FROM image-runtime AS runtime
|
|
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production \
|
|
NEXT_TELEMETRY_DISABLED=1 \
|
|
HOSTNAME=0.0.0.0 \
|
|
PORT=3000 \
|
|
DATA_DIR=/data \
|
|
LD_LIBRARY_PATH=/opt/vips/lib
|
|
|
|
RUN addgroup --system --gid 1001 nodejs \
|
|
&& adduser --system --uid 1001 nextjs
|
|
|
|
COPY --from=verification --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=verification --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
COPY --from=verification --chown=nextjs:nodejs /app/public ./public
|
|
COPY --from=image-build /opt/vips/lib /opt/vips/lib
|
|
# Preserve the package and its native dependency closure beyond Next's tracing.
|
|
COPY --from=dependencies --chown=nextjs:nodejs /app/node_modules/sharp/ ./node_modules/sharp/
|
|
COPY --from=native-runtime-libraries /runtime-libs/ /
|
|
COPY scripts/check-image-runtime.mjs ./scripts/check-image-runtime.mjs
|
|
RUN node scripts/check-image-runtime.mjs --require-source
|
|
RUN mkdir -p .next/cache /data && chown -R nextjs:nodejs .next/cache /data
|
|
|
|
USER nextjs
|
|
EXPOSE 3000
|
|
|
|
HEALTHCHECK --interval=2s --timeout=2s --start-period=3s --retries=30 \
|
|
CMD ["node", "-e", "fetch('http://127.0.0.1:3000/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
|
|
|
|
CMD ["node", "server.js"]
|