Multi stage sample docker file
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o out
# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyApp.dll"]
This Dockerfile uses Multi-Stage Build:
- Stage 1 → Build the app
- Stage 2 → Run the app
The RUN command executes during image build time, not when the container starts.
Stage 1 – Build Stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
- Pulls Microsoft .NET SDK image
- SDK contains compiler, NuGet, build tools
- Named this stage build
WORKDIR /app
-
Sets working directory inside container to
/app - All next commands run from here
COPY . .
-
Copies your entire project folder from local machine → container
/app - Includes
.csproj, source code, etc.
RUN dotnet publish -c Release -o out
This is the key line
RUN executes a command while building the image.
Think of it as:
“Open a temporary container, run this command, save the result as a new image layer.”
What happens internally
- Docker creates a temporary container from
sdk:8.0 - Runs:
- dotnet publish -c Release -o out
.NET does:
- Restore NuGet packages
- Compile code
- Optimize for Release
- Output DLLs + dependencies into
/app/out - Docker commits the result as a new image layer
- Temporary container is deleted
So RUN is build-time execution, not runtime.
Result now inside image:
/app/out/MyApp.dll/app/out/*.json/app/out/*.deps.json
Stage 2 – Runtime Stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
- Starts a fresh lightweight image
- No SDK, only runtime
- Much smaller
WORKDIR /app
Sets working directory again.
COPY --from=build /app/out .
- Copies only compiled output from build stage
- Not source code
- Not SDK
- Only
/app/out→/app
This is why image becomes small.
ENTRYPOINT ["dotnet", "MyApp.dll"]
This runs when container starts, not during build.
Difference:
| Instruction | When it runs |
|---|---|
RUN | During docker build |
ENTRYPOINT | During docker run |
Lifecycle Summary
When you run:
docker build -t myapp .
Docker executes:
- Pull SDK image
- Copy code
- RUN dotnet publish → compile app
- Start new runtime image
- Copy compiled files
- Create final image
When you run:
docker run myapp
Only this runs:
dotnet MyApp.dll
No compiling happens here.
Simple Analogy
- RUN = “Bake the cake in the kitchen”
- ENTRYPOINT = “Serve the cake to the customer”
RUN prepares the app.
ENTRYPOINT executes the app.
Why This Is Efficient
Without multi-stage:
- Image ~1–2 GB
- Includes compiler
With multi-stage:
- Image ~150–250 MB
- Only runtime files
- Faster deploys
- More secure
So RUN = build-time command that produces artifacts saved into the image layer.
No comments:
Post a Comment