# Multi-stage Dockerfile for .NET 9 ASP.NET Core application with pnpm # Stage 1: Base runtime image FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base WORKDIR /app EXPOSE 8080 EXPOSE 8081 # Create non-root user for security RUN groupadd -r appgroup && useradd -r -g appgroup appuser # Stage 2: Node.js build environment for frontend assets FROM node:20-alpine AS node-build WORKDIR /src # Install pnpm globally RUN npm install -g pnpm # Copy package files and install dependencies COPY package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile # Copy source files and build CSS COPY . . RUN pnpm run build # Stage 3: .NET SDK for building the application FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src # Copy project file and restore dependencies COPY *.csproj . RUN dotnet restore "BpsRwApp.csproj" # Copy source code COPY . . # Copy built frontend assets from node-build stage COPY --from=node-build /src/wwwroot/css/site.css ./wwwroot/css/ # Build the application RUN dotnet build "BpsRwApp.csproj" -c Release -o /app/build # Stage 4: Publish the application FROM build AS publish RUN dotnet publish "BpsRwApp.csproj" -c Release -o /app/publish /p:UseAppHost=false # Stage 5: Final runtime image FROM base AS final WORKDIR /app # Copy published application COPY --from=publish /app/publish . # Change ownership to non-root user RUN chown -R appuser:appgroup /app USER appuser # Configure environment ENV ASPNETCORE_ENVIRONMENT=Production ENV ASPNETCORE_URLS=http://+:8080 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 # Entry point ENTRYPOINT ["dotnet", "BpsRwApp.dll"]