# =================================================================== # Stage 1: Build the frontend # =================================================================== FROM node:22-alpine AS frontend-builder WORKDIR /app # Copy package files first for dependency caching COPY frontend/package.json frontend/package-lock.json ./ RUN npm ci # Copy source and build COPY frontend/ ./ RUN npm run build # =================================================================== # Stage 2: Build the Rust backend # =================================================================== FROM rust:1.88-bookworm AS builder WORKDIR /app # Copy manifests and source for building COPY backend/Cargo.toml backend/Cargo.lock ./ COPY backend/src/ src/ COPY backend/migrations/ migrations/ # Set sqlx offline mode (no live DB needed during build) ENV SQLX_OFFLINE=true RUN cargo build --release # =================================================================== # Stage 3: Minimal runtime image # =================================================================== FROM debian:bookworm-slim AS runtime # Install only what the binary needs at runtime RUN apt-get update \ && apt-get install -y --no-install-recommends \ ca-certificates \ libssl3 \ curl \ && rm -rf /var/lib/apt/lists/* # Create non-root user RUN groupadd --system appuser \ && useradd --system --gid appuser --home-dir /app --no-create-home --shell /usr/sbin/nologin appuser WORKDIR /app # Copy backend binary COPY --from=builder /app/target/release/ai-synth-backend ./ai-synth-backend # Copy migrations (run at startup) COPY --from=builder /app/migrations/ ./migrations/ # Copy built frontend COPY --from=frontend-builder /app/dist/ ./static/ # Set ownership RUN chown -R appuser:appuser /app USER appuser ENV PORT=8080 EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD curl -f http://localhost:8080/api/v1/health || exit 1 ENTRYPOINT ["./ai-synth-backend"] CMD ["serve"]