Spaces:
Running
Running
| # Simplified build using official Node 22 slim and static ffmpeg | |
| FROM node:22-slim AS base | |
| # ----------------------------------------------------------------------------- | |
| # tools stage: install fonts and ffmpeg static binary | |
| # ----------------------------------------------------------------------------- | |
| FROM base AS tools | |
| USER root | |
| RUN apt-get update | |
| RUN apt-get update && apt-get install -y curl ca-certificates fonts-deva fonts-noto fonts-noto-cjk jq xz-utils | |
| RUN apt-get update && \ | |
| apt-get install -y fontconfig \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN mkdir -p /usr/local/bin | |
| # fetch and download the latest linux64 ffmpeg (cached layer) | |
| RUN DOWNLOAD_URL=$(curl -sSL https://api.github.com/repos/BtbN/FFmpeg-Builds/releases/latest \ | |
| | jq -r '.assets[] | select(.name | test("linux64.*(gpl|lgpl).*tar.xz")) | .browser_download_url' \ | |
| | head -n1) && \ | |
| if [ -z "$DOWNLOAD_URL" ]; then echo "failed to determine ffmpeg download url"; exit 1; fi && \ | |
| echo "downloading ffmpeg from $DOWNLOAD_URL" && \ | |
| curl -L "$DOWNLOAD_URL" -o /tmp/ffmpeg.tar.xz | |
| # extract ffmpeg archive into /opt/ffmpeg | |
| RUN mkdir -p /opt/ffmpeg && \ | |
| tar -xJ -C /opt/ffmpeg --strip-components=1 -f /tmp/ffmpeg.tar.xz && \ | |
| rm /tmp/ffmpeg.tar.xz | |
| ENV PATH="/opt/ffmpeg/bin:$PATH" | |
| ENV LD_LIBRARY_PATH="/opt/ffmpeg/lib:$LD_LIBRARY_PATH" | |
| # create app directory owned by non-root user | |
| RUN mkdir -p /app && chown -R 1000:1000 /app | |
| USER 1000 | |
| WORKDIR /app | |
| # ----------------------------------------------------------------------------- | |
| # common-utils builder | |
| # ----------------------------------------------------------------------------- | |
| FROM tools AS common-utils-builder | |
| USER 1000 | |
| WORKDIR /app | |
| COPY --chown=1000 common-utils/ ./common-utils | |
| WORKDIR /app/common-utils | |
| RUN npm ci && npm run build && echo "Common-utils build completed successfully" | |
| # ----------------------------------------------------------------------------- | |
| # dependencies installation | |
| # ----------------------------------------------------------------------------- | |
| FROM tools AS dependencies | |
| USER 1000 | |
| WORKDIR /app | |
| COPY --chown=1000 package*.json ./ | |
| COPY --chown=1000 .npmrc ./ | |
| COPY --from=common-utils-builder --chown=1000 /app/common-utils ./common-utils | |
| ENV NODE_ENV=production | |
| ENV CI=true | |
| RUN npm cache clean --force | |
| RUN set -e && \ | |
| echo "Starting dependency installation..." && \ | |
| (timeout 900 npm ci --verbose --ignore-scripts --production=false 2>&1 | tee /tmp/npm-install.log) || \ | |
| (echo "First attempt failed, cleaning cache and retrying..." && \ | |
| npm cache clean --force && \ | |
| rm -rf node_modules package-lock.json && \ | |
| timeout 900 npm install --verbose --ignore-scripts --production=false 2>&1 | tee -a /tmp/npm-install.log) || \ | |
| (echo "Second attempt failed, trying with reduced concurrency..." && \ | |
| npm cache clean --force && \ | |
| rm -rf node_modules && \ | |
| timeout 1200 npm install --verbose --maxsockets 1 --production=false 2>&1 | tee -a /tmp/npm-install.log) | |
| RUN echo "Running postinstall scripts..." && \ | |
| echo "Skipping common-utils build in postinstall as it's already built" && \ | |
| node ffmpeg-fix.js 2>&1 | tee -a /tmp/postinstall.log || echo "ffmpeg-fix completed" && \ | |
| npm rebuild --verbose 2>&1 | tee -a /tmp/npm-rebuild.log || \ | |
| echo "Some rebuilds failed, but continuing..." | |
| RUN node -e "console.log('Node version:', process.version)" && \ | |
| node -e "require('react'); console.log('React OK')" && \ | |
| node -e "require('remotion'); console.log('Remotion OK')" && \ | |
| ls -la node_modules/.bin/ | head -20 | |
| # ----------------------------------------------------------------------------- | |
| # final production image | |
| # ----------------------------------------------------------------------------- | |
| FROM tools AS final | |
| RUN mkdir -p /app/public /app/out /app/frames /app/uploads && chown -R 1000:1000 /app | |
| COPY --from=dependencies --chown=1000 /app/node_modules ./app/node_modules | |
| COPY --from=dependencies --chown=1000 /app/package*.json ./app/ | |
| COPY --from=dependencies --chown=1000 /app/common-utils ./app/common-utils | |
| USER 1000 | |
| WORKDIR /app | |
| COPY --chown=1000 . ./ | |
| COPY --chown=1000 start.sh /app/start.sh | |
| RUN chmod +x /app/start.sh | |
| RUN npm i | |
| RUN echo "Verifying installation..." && \ | |
| node -e "console.log('Final verification - Node:', process.version)" && \ | |
| npm list --depth=0 | head -10 || true | |
| EXPOSE 7860 3000 8083 | |
| CMD ["sh", "/app/start.sh"] | |
| # build: docker build -f Dockerfile.build.lean -t semibit/render-farm:lean . | |
| # run : docker run -p 8083:8083 -it --rm semibit/render-farm:lean | |