|
|
@@ -1,17 +1,30 @@
|
|
|
# Stage 1: Install dependencies (isolated layout, same as local dev)
|
|
|
FROM node:22-bookworm AS deps
|
|
|
|
|
|
-# 使用阿里云镜像源
|
|
|
-RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources
|
|
|
+# Mirror switch: default ON (国内镜像源) for fast local/China builds.
|
|
|
+# CI/CD on the release branch builds with --build-arg USE_CN_MIRROR=0 to use
|
|
|
+# official sources (deb.debian.org / registry.npmjs.org / pypi.org /
|
|
|
+# storage.googleapis.com). Resolved per-stage below.
|
|
|
+ARG USE_CN_MIRROR=1
|
|
|
|
|
|
-ENV COREPACK_NPM_REGISTRY=https://registry.npmmirror.com
|
|
|
-RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then REG=https://registry.npmmirror.com; \
|
|
|
+ else REG=https://registry.npmjs.org; fi; \
|
|
|
+ corepack enable && \
|
|
|
+ COREPACK_NPM_REGISTRY=$REG corepack prepare pnpm@10.24.0 --activate
|
|
|
|
|
|
-RUN apt-get update && \
|
|
|
+# 系统包 + Python 依赖:国内源时改 apt 源并走阿里云 pypi;官方源时全用默认
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then \
|
|
|
+ sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources; \
|
|
|
+ PIP_INDEX=https://mirrors.aliyun.com/pypi/simple/; \
|
|
|
+ else \
|
|
|
+ PIP_INDEX=https://pypi.org/simple; \
|
|
|
+ fi; \
|
|
|
+ apt-get update && \
|
|
|
apt-get install -y --no-install-recommends ffmpeg python3 python3-pip && \
|
|
|
- rm -rf /var/lib/apt/lists/*
|
|
|
-
|
|
|
-RUN pip3 install --break-system-packages -i https://mirrors.aliyun.com/pypi/simple/ faster-whisper
|
|
|
+ rm -rf /var/lib/apt/lists/* && \
|
|
|
+ pip3 install --break-system-packages -i "$PIP_INDEX" faster-whisper
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
@@ -27,7 +40,10 @@ COPY packages/text/package.json packages/text/
|
|
|
COPY packages/audio/package.json packages/audio/
|
|
|
COPY packages/renderer/package.json packages/renderer/
|
|
|
|
|
|
-RUN pnpm config set registry https://registry.npmmirror.com && \
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then REG=https://registry.npmmirror.com; \
|
|
|
+ else REG=https://registry.npmjs.org; fi; \
|
|
|
+ pnpm config set registry "$REG" && \
|
|
|
pnpm install --frozen-lockfile
|
|
|
|
|
|
# Stage 2: Build
|
|
|
@@ -43,20 +59,32 @@ RUN pnpm build && rm -rf apps/web/.next/cache
|
|
|
# Stage 3: Runtime — fresh prod install with hoisted layout
|
|
|
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
|
|
|
+# Mirror switch (see deps stage): default ON for local/China; CI passes
|
|
|
+# --build-arg USE_CN_MIRROR=0 for official sources.
|
|
|
+ARG USE_CN_MIRROR=1
|
|
|
|
|
|
-ENV COREPACK_NPM_REGISTRY=https://registry.npmmirror.com
|
|
|
-RUN corepack enable && corepack prepare pnpm@10.24.0 --activate
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then REG=https://registry.npmmirror.com; \
|
|
|
+ else REG=https://registry.npmjs.org; fi; \
|
|
|
+ corepack enable && \
|
|
|
+ COREPACK_NPM_REGISTRY=$REG corepack prepare pnpm@10.24.0 --activate
|
|
|
|
|
|
-RUN apt-get update && \
|
|
|
+# 系统包(ffmpeg + Chrome 运行库 + 字体)+ Python 依赖:国内源时改 apt 源并走阿里云 pypi;官方源时全用默认
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then \
|
|
|
+ sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources; \
|
|
|
+ PIP_INDEX=https://mirrors.aliyun.com/pypi/simple/; \
|
|
|
+ else \
|
|
|
+ PIP_INDEX=https://pypi.org/simple; \
|
|
|
+ fi; \
|
|
|
+ apt-get update && \
|
|
|
apt-get install -y --no-install-recommends \
|
|
|
ffmpeg python3 python3-pip fontconfig \
|
|
|
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
|
|
|
libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
|
|
|
libgbm1 libpango-1.0-0 libcairo2 libasound2 && \
|
|
|
- rm -rf /var/lib/apt/lists/*
|
|
|
-
|
|
|
-RUN pip3 install --break-system-packages -i https://mirrors.aliyun.com/pypi/simple/ faster-whisper
|
|
|
+ rm -rf /var/lib/apt/lists/* && \
|
|
|
+ pip3 install --break-system-packages -i "$PIP_INDEX" faster-whisper
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
@@ -73,12 +101,14 @@ COPY --from=build /app/packages/text/package.json packages/text/
|
|
|
COPY --from=build /app/packages/audio/package.json packages/audio/
|
|
|
COPY --from=build /app/packages/renderer/package.json packages/renderer/
|
|
|
|
|
|
-# Install production deps with hoisted layout (everything flat at root node_modules)
|
|
|
-RUN pnpm config set registry https://registry.npmmirror.com && \
|
|
|
- pnpm install --frozen-lockfile --prod --config.node-linker=hoisted
|
|
|
-
|
|
|
-# Re-create workspace symlinks at root so any package can resolve @pipeline/* by walking up
|
|
|
-RUN mkdir -p node_modules/@pipeline && \
|
|
|
+# Install production deps with hoisted layout (everything flat at root node_modules),
|
|
|
+# then re-create the workspace symlinks at root so any package can resolve @pipeline/* by walking up.
|
|
|
+RUN set -eux; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then REG=https://registry.npmmirror.com; \
|
|
|
+ else REG=https://registry.npmjs.org; fi; \
|
|
|
+ pnpm config set registry "$REG" && \
|
|
|
+ pnpm install --frozen-lockfile --prod --config.node-linker=hoisted && \
|
|
|
+ mkdir -p node_modules/@pipeline && \
|
|
|
ln -s ../../packages/shared node_modules/@pipeline/shared && \
|
|
|
ln -s ../../packages/core node_modules/@pipeline/core && \
|
|
|
ln -s ../../packages/tts node_modules/@pipeline/tts && \
|
|
|
@@ -116,17 +146,21 @@ RUN mkdir -p /usr/share/fonts/truetype/noto && \
|
|
|
# (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
|
|
|
+# (host flips to storage.googleapis.com/chrome-for-testing-public when
|
|
|
+# USE_CN_MIRROR=0, for the overseas CI/release build)
|
|
|
# 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; \
|
|
|
+ if [ "$USE_CN_MIRROR" = "1" ]; then CHROME_BASE=https://registry.npmmirror.com/-/binary/chrome-for-testing; \
|
|
|
+ else CHROME_BASE=https://storage.googleapis.com/chrome-for-testing-public; fi; \
|
|
|
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"; \
|
|
|
+ URL="$CHROME_BASE/${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; \
|
|
|
@@ -145,13 +179,19 @@ RUN set -eux; \
|
|
|
# umask 022 plus the explicit `chmod +x` on the binary), so the node user
|
|
|
# can read and execute it. We only chmod the .remotion *directory* 777 so a
|
|
|
# stray write (none expected once chrome is pre-placed) can still succeed.
|
|
|
+# Remotion resolves its chrome cache to <nearest-package.json>/node_modules/.remotion
|
|
|
+# from the SERVER's runtime cwd (/app/apps/web), not the image build dir (/app).
|
|
|
+# The binary lives at /app/node_modules/.remotion (pre-placed above); expose it at the
|
|
|
+# path the server actually probes so ensureBrowser() finds it and skips the download.
|
|
|
ENV HOME=/home/node
|
|
|
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/packages/templates/node_modules/.cache && \
|
|
|
- chmod 777 /app/node_modules/.remotion
|
|
|
+ chmod 777 /app/node_modules/.remotion && \
|
|
|
+ mkdir -p /app/apps/web/node_modules && \
|
|
|
+ ln -sfnT /app/node_modules/.remotion /app/apps/web/node_modules/.remotion
|
|
|
USER node
|
|
|
|
|
|
EXPOSE 3000
|