From a5d76e109feab9aa1d8a3b2d757ef91734c5e385 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 19:03:27 +0000 Subject: [PATCH] =?UTF-8?q?feat(docker):=20multi-stage=20Dockerfile=20?= =?UTF-8?q?=E2=80=94=20pnpm=20SPA=20build=20+=20dotnet=20publish=20+=20asp?= =?UTF-8?q?net:9.0=20runtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..deead7f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +# syntax=docker/dockerfile:1.7 + +# 1. Frontend build — pnpm 9 via corepack matches pnpm-lock.yaml lockfileVersion 9.0. +# Vite's outDir is "../src/VolcanicCore.Api/wwwroot" relative to frontend/, +# so we build under /build and pre-create the target so the .. path resolves. +FROM node:20-alpine AS web +RUN corepack enable && corepack prepare pnpm@9.15.9 --activate +WORKDIR /build +RUN mkdir -p src/VolcanicCore.Api/wwwroot +COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml frontend/ +RUN cd frontend && pnpm install --frozen-lockfile +COPY frontend/ frontend/ +RUN cd frontend && pnpm build +# → /build/src/VolcanicCore.Api/wwwroot/{index.html, assets/…} + +# 2. Backend publish — restore cache-friendly by copying every .csproj first. +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS api +WORKDIR /src +COPY VolcanicCore.sln global.json ./ +COPY src/VolcanicCore.Core/VolcanicCore.Core.csproj src/VolcanicCore.Core/ +COPY src/VolcanicCore.Persistence/VolcanicCore.Persistence.csproj src/VolcanicCore.Persistence/ +COPY src/VolcanicCore.Nodes/VolcanicCore.Nodes.csproj src/VolcanicCore.Nodes/ +COPY src/VolcanicCore.Providers/VolcanicCore.Providers.csproj src/VolcanicCore.Providers/ +COPY src/VolcanicCore.Api/VolcanicCore.Api.csproj src/VolcanicCore.Api/ +RUN dotnet restore src/VolcanicCore.Api/VolcanicCore.Api.csproj +COPY src/ src/ +RUN dotnet publish src/VolcanicCore.Api/VolcanicCore.Api.csproj \ + -c Release -o /out --no-restore /p:UseAppHost=false + +# 3. Runtime — aspnet:9.0 (Debian bookworm-slim). Not distroless: we need curl +# for HEALTHCHECK and the plain OS layer for IronPython's P/Invoke surface. +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime +WORKDIR /app +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* +COPY --from=api /out ./ +# Overlay the SPA build on top of the (empty) wwwroot that came from the publish. +COPY --from=web /build/src/VolcanicCore.Api/wwwroot/ ./wwwroot/ +RUN mkdir -p /data +ENV ASPNETCORE_ENVIRONMENT=Production \ + ASPNETCORE_URLS=http://+:8080 \ + DATA_DIRECTORY=/data +EXPOSE 8080 +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD curl -fsS http://127.0.0.1:8080/api/health || exit 1 +ENTRYPOINT ["dotnet", "VolcanicCore.Api.dll"]