ARG CADDY_IMAGE=caddy:2.8.4-alpine ARG NODE_IMAGE=node:21-alpine3.20 # ── Stage 1: Build React app ────────────────────────────────────────────────── FROM $NODE_IMAGE AS builder WORKDIR /app # Install deps first (layer cache) COPY package.json package-lock.json* yarn.lock* ./ RUN NODE_OPTIONS=--max-old-space-size=4096 npm install --legacy-peer-deps --prefer-offline 2>/dev/null || \ NODE_OPTIONS=--max-old-space-size=4096 npm install --legacy-peer-deps # Copy source and build COPY . . RUN NODE_OPTIONS=--max-old-space-size=4096 npm run build # ── Stage 2: Install server deps ────────────────────────────────────────────── FROM $NODE_IMAGE AS server-deps WORKDIR /srv COPY server/package.json server/package-lock.json* ./ RUN npm install --omit=dev --no-audit --prefer-offline # ── Stage 3: Production image (Caddy + Node.js) ─────────────────────────────── FROM $CADDY_IMAGE # Install Node.js to run the Facebook OAuth2 microserver RUN apk add --no-cache nodejs # Copy built React app from builder COPY --from=builder /app/build /ui/build # Copy Caddy config COPY Caddyfile /ui/Caddyfile # Copy Node.js FB server + its deps COPY server /ui/server COPY --from=server-deps /srv/node_modules /ui/server/node_modules # Copy entrypoint script COPY docker-entrypoint.sh /ui/docker-entrypoint.sh RUN chmod +x /ui/docker-entrypoint.sh # Persistent volume for FB OAuth2 tokens (config.json) VOLUME ["/data/fb"] WORKDIR /ui EXPOSE 3000 # Runtime environment variables (overridden at runtime via -e or docker-compose) ENV CORE_ADDRESS="" ENV YTDLP_URL="" ENV FB_SERVER_URL="" ENV YTDLP_HOST="192.168.1.20:8282" CMD ["/ui/docker-entrypoint.sh"]