# Stage 1: Build frontend FROM node:22-alpine AS frontend-build WORKDIR /app/web # Install pnpm RUN corepack enable && corepack prepare pnpm@latest --activate # Copy frontend package files COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./ # Install dependencies RUN pnpm install --frozen-lockfile # Copy frontend source COPY web/ ./ # Build frontend (SSR with adapter-node) RUN export BETTER_AUTH_SECRET="place-holder-for-build" && pnpm build # Stage 2: Build backend FROM dart:stable AS backend-build WORKDIR /app # Resolve app dependencies COPY pubspec.* ./ RUN dart pub get # Copy app source code and compile COPY bin/ ./bin/ RUN dart compile exe bin/server.dart -o bin/server # Stage 3: Runtime image with Node.js, libvips and Dart runtime FROM node:22-bookworm-slim AS runtime # Install libvips, ca-certificates and other dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ libvips-tools \ ca-certificates \ curl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # Copy the compiled Dart server COPY --from=backend-build /app/bin/server /app/bin/server # Copy the built frontend (Node.js SSR app) COPY --from=frontend-build /app/web/build /app/web/build # Create data and cache directories RUN mkdir -p /app/data /app/cache # Copy startup script COPY docker/entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh # Set environment variables (can be overridden at runtime) ENV PORT=8080 \ HOST=0.0.0.0 \ DATA_DIR=/app/data \ CACHE_DIR=/app/cache \ BACKEND_URL=http://127.0.0.1:8081 \ NODE_ENV=production # Expose port (frontend serves on this port) EXPOSE 8080 # Start both services using entrypoint script ENTRYPOINT ["/app/entrypoint.sh"]