# ── Stage 1: Build ──────────────────────────────────────────────────────────── FROM mirror.soroushasadi.com/dotnet/sdk:10.0 AS build WORKDIR /src # Restore dependencies first (layer-cache friendly) COPY DrSousan.Api.csproj NuGet.Config ./ RUN ok=0; \ for i in 1 2 3 4 5; do \ dotnet restore DrSousan.Api.csproj --configfile NuGet.Config && ok=1 && break; \ echo "Restore attempt $i failed, retrying in 30s..."; sleep 30; \ done; \ [ "$ok" = "1" ] # Copy everything and publish COPY . . RUN dotnet publish DrSousan.Api.csproj \ -c Release \ -o /app/publish \ --no-restore # ── Stage 2: Runtime ────────────────────────────────────────────────────────── FROM mirror.soroushasadi.com/dotnet/aspnet:10.0 AS runtime WORKDIR /app # Create directories for persistent volumes and set ownership # .NET 10 aspnet image ships with a built-in non-root user "app" (uid 1654) RUN mkdir -p /data /app/wwwroot/uploads COPY --from=build /app/publish . EXPOSE 8080 # /data → SQLite DB (mount as named volume) # /app/wwwroot/uploads → uploaded images (mount as named volume) VOLUME ["/data", "/app/wwwroot/uploads"] ENV ASPNETCORE_URLS=http://+:8080 ENV ASPNETCORE_ENVIRONMENT=Production RUN apt-get update -qq && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* HEALTHCHECK --interval=15s --timeout=10s --start-period=30s --retries=3 \ CMD curl -f http://localhost:8080/healthz || exit 1 ENTRYPOINT ["dotnet", "DrSousan.Api.dll"]