|
@@ -4,6 +4,7 @@ FROM node:22-bookworm AS deps
|
|
|
# 使用阿里云镜像源
|
|
# 使用阿里云镜像源
|
|
|
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources
|
|
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources
|
|
|
|
|
|
|
|
|
|
+ENV COREPACK_NPM_REGISTRY=https://registry.npmmirror.com
|
|
|
RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
|
|
|
|
|
|
RUN apt-get update && \
|
|
RUN apt-get update && \
|
|
@@ -37,6 +38,7 @@ FROM node:22-bookworm-slim AS runtime
|
|
|
|
|
|
|
|
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources
|
|
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources
|
|
|
|
|
|
|
|
|
|
+ENV COREPACK_NPM_REGISTRY=https://registry.npmmirror.com
|
|
|
RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
|
|
|
|
|
|
RUN apt-get update && \
|
|
RUN apt-get update && \
|
|
@@ -93,13 +95,47 @@ RUN mkdir -p /usr/share/fonts/truetype/noto && \
|
|
|
cp assets/fonts/NotoSansSC-Regular.ttf assets/fonts/NotoSansSC-Bold.ttf /usr/share/fonts/truetype/noto/ && \
|
|
cp assets/fonts/NotoSansSC-Regular.ttf assets/fonts/NotoSansSC-Bold.ttf /usr/share/fonts/truetype/noto/ && \
|
|
|
fc-cache -f
|
|
fc-cache -f
|
|
|
|
|
|
|
|
|
|
+# Bundle Remotion's headless Chrome so rendering needs NO network at runtime.
|
|
|
|
|
+# Remotion normally auto-downloads chrome-headless-shell from Google's CDN
|
|
|
|
|
+# (storage.googleapis.com / remotion.media) on first render, but that is
|
|
|
|
|
+# ~5KB/s from CN networks and stalls indefinitely. Fetch the SAME binary
|
|
|
|
|
+# Remotion wants from the Aliyun-backed npmmirror binary mirror at build time
|
|
|
|
|
+# and lay it out exactly as Remotion's BrowserFetcher expects, so
|
|
|
|
|
+# ensureBrowser() finds it present (revision.local && existsSync(executablePath))
|
|
|
|
|
+# and skips the download. Version is read from the installed @remotion/renderer
|
|
|
|
|
+# so this auto-tracks Remotion upgrades instead of hardcoding a number.
|
|
|
|
|
+RUN set -eux; \
|
|
|
|
|
+ SRC=/app/node_modules/@remotion/renderer/dist/browser/get-chrome-download-url.js; \
|
|
|
|
|
+ VERSION=$(grep -oE "TESTED_VERSION = '[0-9.]+'" "$SRC" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | head -1); \
|
|
|
|
|
+ test -n "$VERSION"; \
|
|
|
|
|
+ CACHE=/app/node_modules/.remotion/chrome-headless-shell; \
|
|
|
|
|
+ mkdir -p "$CACHE/linux64"; \
|
|
|
|
|
+ URL="https://registry.npmmirror.com/-/binary/chrome-for-testing/${VERSION}/linux64/chrome-headless-shell-linux64.zip"; \
|
|
|
|
|
+ node -e "const fs=require('fs');fetch(process.argv[1]).then(r=>r.arrayBuffer()).then(b=>fs.writeFileSync(process.argv[2],Buffer.from(b)))" "$URL" /tmp/chs.zip; \
|
|
|
|
|
+ python3 -m zipfile -e /tmp/chs.zip "$CACHE/linux64/"; \
|
|
|
|
|
+ rm -f /tmp/chs.zip; \
|
|
|
|
|
+ BIN="$CACHE/linux64/chrome-headless-shell-linux64/chrome-headless-shell"; \
|
|
|
|
|
+ chmod +x "$BIN"; \
|
|
|
|
|
+ printf '%s' "$VERSION" > "$CACHE/VERSION"
|
|
|
|
|
+
|
|
|
# Run as the non-root `node` user (uid/gid 1000, shipped in the base image) so
|
|
# Run as the non-root `node` user (uid/gid 1000, shipped in the base image) so
|
|
|
# the image is Pod Security "restricted"-friendly. Only the writable paths are
|
|
# the image is Pod Security "restricted"-friendly. Only the writable paths are
|
|
|
# chowned to keep the layer small: the PVC-backed output, Next.js' .next cache,
|
|
# chowned to keep the layer small: the PVC-backed output, Next.js' .next cache,
|
|
|
# and a HOME for Remotion's browser / faster-whisper model download cache.
|
|
# and a HOME for Remotion's browser / faster-whisper model download cache.
|
|
|
ENV HOME=/home/node
|
|
ENV HOME=/home/node
|
|
|
-RUN mkdir -p /app/output /home/node && \
|
|
|
|
|
- chown -R node:node /app/output /home/node /app/apps/web/.next
|
|
|
|
|
|
|
+# Remotion downloads its headless Chrome into <projectRoot>/node_modules/.remotion
|
|
|
|
|
+# (see @remotion/renderer browser/get-download-destination.js — it walks up to the
|
|
|
|
|
+# nearest package.json, here /app, then uses node_modules/.remotion), and the
|
|
|
|
|
+# bundler's webpack writes a cache to packages/templates/node_modules/.cache. Both
|
|
|
|
|
+# node_modules trees are root-owned from the build, but the container runs as the
|
|
|
|
|
+# non-root `node` user, so these runtime-writable cache dirs must be pre-created
|
|
|
|
|
+# and chowned — otherwise rendering aborts with
|
|
|
|
|
+# `EACCES: permission denied, mkdir '/app/node_modules/.remotion'`.
|
|
|
|
|
+RUN mkdir -p /app/output /home/node \
|
|
|
|
|
+ /app/node_modules/.remotion \
|
|
|
|
|
+ /app/packages/templates/node_modules/.cache && \
|
|
|
|
|
+ chown -R node:node /app/output /home/node /app/apps/web/.next \
|
|
|
|
|
+ /app/node_modules/.remotion /app/packages/templates/node_modules/.cache
|
|
|
USER node
|
|
USER node
|
|
|
|
|
|
|
|
EXPOSE 3000
|
|
EXPOSE 3000
|