dotnet-isolate
0.1.70
See the version list below for details.
dotnet tool install --global dotnet-isolate --version 0.1.70
dotnet new tool-manifest
dotnet tool install --local dotnet-isolate --version 0.1.70
#tool dotnet:?package=dotnet-isolate&version=0.1.70
nuke :add-package dotnet-isolate --version 0.1.70
dotnet-isolate
dotnet-isolate copies the minimal set of files needed to build a .NET project out of a larger
solution — the project, its transitive ProjectReference closure, and the files each needs — leaving
the original untouched. The result is a small Docker build context whose layer caches keep hitting.
Usage
dotnet isolate path/to/<Project>.csproj [more.csproj ...] [-o <dir>] [-s <path>] [--restore] [--clean]
- one or more entry projects; the output is the union of their closures
-o/--output-dir— where to write (default./<ProjectName>); required for multiple projects-s/--solution— the solution to scope against, overriding the walk-up search--restore— emit only the filesdotnet restorereads, for the split below--clean— delete the output directory first, instead of merging into it
Generated build artifacts are left behind: bin/ and obj/ next to a project file, node_modules/,
build logs and coverage reports, and anything under an ArtifactsPath. MSBuild resolves them as
ordinary items — a project whose directory contains other projects globs their output in, and a
hand-written <None Include="**/*"/> bypasses the SDK's exclusions entirely — but they are rewritten
on every local build, so shipping them would bust the layer cache the tool exists to protect.
Defaults, warnings and output-directory safety: REQUIREMENTS.md. File resolution and layout: DESIGN.md.
How this keeps a Docker build cached
COPY --from=<stage> is keyed on the checksum of the bytes copied out of the source stage — not
on that stage's layer history. So the isolate stage can rerun on every build, as it must, while every
layer below it cache-hits as long as the isolated output is byte-identical. That checksum is also
mtime-insensitive, which is load-bearing: the tool hardlinks, so output files inherit their source's
mtime, and a fresh CI clone stamps every file with a new one.
--restore splits the output where the cache should hold: the restore half has no sources in it, so
RUN dotnet restore survives ordinary source edits. An end-to-end test changes a file inside the
isolated closure and asserts dotnet restore is still CACHED while the build layer reruns.
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS isolate
RUN dotnet tool install -g dotnet-isolate
ENV PATH="$PATH:/root/.dotnet/tools"
RUN --mount=type=bind,target=/src,source=. \
dotnet isolate /src/Service1/Service1.csproj --restore -o /isolated/restore
RUN --mount=type=bind,target=/src,source=. \
dotnet isolate /src/Service1/Service1.csproj -o /isolated/full
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY --from=isolate /isolated/restore /src
RUN dotnet restore
COPY --from=isolate /isolated/full /src
RUN dotnet build -c Release --no-restore
RUN dotnet publish Service1/Service1.csproj -c Release --no-build -o /app
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS run
COPY --from=build /app /app
ENTRYPOINT ["dotnet", "/app/Service1.dll"]
Needs buildx (Docker's default builder); the classic builder has no bind mounts. The last stage is just your app's runtime image — pick the base it needs, nothing about the caching depends on it.
- The read-only bind mount replaces
COPY . /src, keeping the whole build context out of the isolate stage's layers — the cost the tool exists to avoid. - Hardlinking across the bind mount fails; one upfront probe detects that and copies instead.
- Add a
.dockerignoreforbin/andobj/. The tool already keeps build artifacts out of the isolated output, but BuildKit keys the bind mount off the whole mounted subtree, so a local build beforedocker buildstill reruns the isolate stage. The layers below it stay cached either way. - Paths are relative to the computed mirror root, not always the solution root — a file
referenced from outside the solution folder raises it. Look at the output before writing your
COPYandpublishpaths.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.80-gbc1d81d6a0 | 96 | 8/24/2026 |
| 0.1.70 | 112 | 8/18/2026 |
| 0.1.70-gc1b5dfd384 | 91 | 8/18/2026 |
| 0.1.54 | 104 | 8/12/2026 |
| 0.1.54-g2c979e5f64 | 97 | 8/11/2026 |
| 0.1.34 | 196 | 8/7/2026 |
| 0.1.34-g9fa9d5369c | 92 | 8/7/2026 |
| 0.1.28-gad21540fcf | 99 | 8/5/2026 |
| 0.1.20-g914371c535 | 95 | 8/5/2026 |