# syntax=docker/dockerfile:1.7

# =====================================================================
# Stage 1 — Frontend (статика для встроенной раздачи)
# =====================================================================
FROM node:20-alpine AS frontend-builder
WORKDIR /app/frontend
RUN npm install -g pnpm@9
# Сначала только манифесты — слой с зависимостями кешируется отдельно.
COPY frontend/package.json frontend/pnpm-lock.yaml ./
# "cyberhack" — не публикуемый npm-пакет, а собранный wasm-pack бандл из
# отдельного репозитория (Cyberhack), завендоренный прямо сюда (см.
# frontend/vendor/README, если появится) — иначе pnpm install не смог бы
# разрешить `file:./vendor/cyberhack` в CI, где второй репозиторий не
# чекаутится. Должен быть скопирован ДО pnpm install, а не вместе с
# остальным `frontend/`, — иначе разрешение зависимости упадёт.
COPY frontend/vendor ./vendor
RUN pnpm install --frozen-lockfile
COPY frontend/ .
RUN pnpm build

# =====================================================================
# Stage 2 — Cargo Chef (план зависимостей для эффективного кеша слоёв)
# =====================================================================
FROM rust:latest AS chef
RUN apt-get update \
    && apt-get install -y --no-install-recommends pkg-config libssl-dev \
    && rm -rf /var/lib/apt/lists/*
RUN cargo install cargo-chef --locked
WORKDIR /app

FROM chef AS planner
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo chef prepare --recipe-path recipe.json

# =====================================================================
# Stage 3 — Сборка бэкенда
# =====================================================================
FROM chef AS builder
# Слой зависимостей: пересобирается только при изменении Cargo.toml/Cargo.lock.
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
# Теперь исходники. sqlx работает в offline-режиме — БД при сборке не нужна.
ENV SQLX_OFFLINE=true
COPY Cargo.toml Cargo.lock ./
COPY src ./src
COPY migrations ./migrations
RUN cargo build --release --bin netrunner-control-plane

# =====================================================================
# Stage 4 — Минимальный рантайм-образ
# =====================================================================
FROM debian:bookworm-slim AS runtime
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates libssl3 curl \
    && rm -rf /var/lib/apt/lists/* \
    && useradd -r -u 10001 -m -d /app netrunner
WORKDIR /app

COPY --from=builder /app/target/release/netrunner-control-plane .
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
COPY migrations ./migrations
COPY templates ./templates

RUN chown -R netrunner:netrunner /app
USER netrunner

ENV FRONTEND_DIR=/app/frontend/dist \
    PORT=8080
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
    CMD curl -fsS "http://localhost:${PORT}/health" || exit 1

CMD ["./netrunner-control-plane"]
