FROM oven/bun:1.4.0 AS source WORKDIR /app COPY package.json bun.lock ./ COPY apps/web/package.json apps/web/package.json COPY apps/worker/package.json apps/worker/package.json COPY packages/contracts/package.json packages/contracts/package.json COPY packages/database/package.json packages/database/package.json COPY packages/email/package.json packages/email/package.json COPY packages/storage/package.json packages/storage/package.json # Keep native optional dependencies beside their packages for Next's external # module loading and standalone tracing (including Sharp's Linux binaries). RUN bun install --frozen-lockfile --linker hoisted --network-concurrency 8 COPY . . FROM source AS builder ARG NEXT_PUBLIC_APP_URL ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL NEXT_TELEMETRY_DISABLED=1 # Build-only resource controls for the shared Coolify VM; not runtime settings. ENV NEXT_BUILD_CPUS=2 RAYON_NUM_THREADS=2 UV_THREADPOOL_SIZE=2 MALLOC_ARENA_MAX=2 NODE_OPTIONS=--max-old-space-size=1536 # Build-only placeholders; never copy production secrets into image layers. RUN DATABASE_URL=postgres://build:build@127.0.0.1:5432/build BETTER_AUTH_SECRET=build-only-placeholder-secret-not-for-runtime BETTER_AUTH_URL=$NEXT_PUBLIC_APP_URL bun run --filter @album/web build FROM oven/bun:1.4.0 AS web WORKDIR /app ENV NODE_ENV=production HOSTNAME=0.0.0.0 PORT=3000 NEXT_TELEMETRY_DISABLED=1 COPY --from=builder --chown=bun:bun /app/apps/web/.next/standalone ./ # Next's standalone trace can omit libvips shared libraries loaded by Sharp. COPY --from=builder --chown=bun:bun /app/node_modules/@img ./node_modules/@img COPY --from=builder --chown=bun:bun /app/apps/web/.next/static ./apps/web/.next/static COPY --from=builder --chown=bun:bun /app/apps/web/public ./apps/web/public COPY --from=builder --chown=bun:bun /app/scripts/check-production-env.ts ./scripts/check-production-env.ts USER bun RUN cd /app/apps/web && bun -e 'import sharp from "sharp"; const image = await sharp({create:{width:8,height:8,channels:3,background:"white"}}).webp().toBuffer(); if (!image.length) throw new Error("Sharp runtime smoke test failed");' EXPOSE 3000 CMD ["sh", "-c", "bun scripts/check-production-env.ts && exec bun apps/web/server.js"] FROM source AS worker ENV NODE_ENV=production USER bun CMD ["sh", "-c", "bun scripts/check-production-env.ts && exec bun apps/worker/src/index.ts"] FROM worker AS migrate WORKDIR /app/packages/database CMD ["bun", "src/migrate.ts"] FROM dxflrs/garage:v2.3.0 AS garage COPY docker/garage.production.toml /etc/garage.toml