You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于scratch镜像缩减ASP.NET Core Docker分发镜像体积可行吗?

Great question! The approach you’re considering—using a scratch image to package just your ASP.NET Core app files and pairing it with the official microsoft/aspnetcore runtime via Docker Compose—totally works, and it’s a clever way to cut down on the size of the artifact you need to ship to your test servers. Here’s how to implement it step by step:

1. Build a Minimal scratch Image for Your App Files

First, you’ll create a multi-stage Dockerfile to compile your app and copy only the published files into a scratch base image. This results in an extremely small image (just your app’s files, no runtime dependencies):

Create a file named Dockerfile.app with this content:

# Stage 1: Build and publish the ASP.NET Core app
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# Copy project file first to leverage Docker cache
COPY ["YourAppName.csproj", "."]
RUN dotnet restore "YourAppName.csproj"
# Copy remaining source code
COPY . .
WORKDIR "/src/."
RUN dotnet publish "YourAppName.csproj" -c Release -o /app/publish

# Stage 2: Create the minimal app file image
FROM scratch
WORKDIR /app
COPY --from=build /app/publish .

Build this image with:

docker build -t your-app-files:latest -f Dockerfile.app .

This image will only contain your compiled app files—no runtime, no OS libraries—so its size will be just a few MBs (depending on your app) instead of hundreds of MBs like the full microsoft/aspnetcore image.

2. Use Docker Compose to Pair the Runtime and App Files

Next, you’ll create a docker-compose.yml that combines the official ASP.NET Core runtime image with your scratch app file image. The trick here is to use a data container (from your scratch image) to share the app files with the runtime container:

version: '3.8'

services:
  # The runtime container that runs your app
  app:
    image: mcr.microsoft.com/dotnet/aspnet:8.0
    ports:
      - "8080:80" # Adjust ports to match your app
    volumes_from:
      - app-files # Mounts the /app directory from the data container
    working_dir: /app
    command: ["dotnet", "YourAppName.dll"] # Replace with your app's DLL name

  # The data container that holds your app files
  app-files:
    image: your-app-files:latest
    volumes:
      - /app # Exposes the /app directory as a volume
    command: ["tail", "-f", "/dev/null"] # Keeps the container running to share the volume

3. Distribute and Run on Test Servers

Your distribution workflow becomes much lighter now:

  1. On your build machine, export the small app file image:
    docker save -o app-files.tar your-app-files:latest
    
  2. Transfer this tiny .tar file to your test server (via SCP, FTP, etc.—it’ll be way faster than sending the full runtime image).
  3. On the test server, load the image:
    docker load -i app-files.tar
    
  4. Run docker-compose up -d—Docker will pull the microsoft/aspnetcore runtime image if it’s not already present, then start both containers. The runtime container will access your app files from the data container and run the app.

Key Notes to Keep in Mind

  • Version Compatibility: Ensure the SDK version used to build your app (in Dockerfile.app) matches the runtime image version (in docker-compose.yml). For example, if you use SDK 8.0, use the aspnet:8.0 runtime image.
  • Native Dependencies: If your app relies on system-level native libraries (e.g., for image processing or database drivers), scratch won’t include these. In that case, use mcr.microsoft.com/dotnet/runtime-deps:8.0 instead of scratch—it’s still much smaller than the full aspnet image and includes the necessary system dependencies for .NET apps.
  • Updating Apps: When you push a new version, rebuild the your-app-files image with a new tag (e.g., v2), update the tag in docker-compose.yml, then run docker-compose up -d on the test server. You may need to stop and remove the old app-files container first to ensure the new files are used.
  • Alternative Workflow: If your test servers have internet access, consider using a multi-stage build to create a slim runtime image directly (combining the runtime base image with your app files). This avoids the data container complexity, and Docker will only pull the delta when updating:
    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /src
    COPY ["YourAppName.csproj", "."]
    RUN dotnet restore
    COPY . .
    RUN dotnet publish -c Release -o /app/publish
    
    FROM mcr.microsoft.com/dotnet/aspnet:8.0
    WORKDIR /app
    COPY --from=build /app/publish .
    ENTRYPOINT ["dotnet", "YourAppName.dll"]
    

内容的提问来源于stack exchange,提问作者JohnC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:24:11