JD.MSBuild.Containers
0.1.0
See the version list below for details.
dotnet add package JD.MSBuild.Containers --version 0.1.0
NuGet\Install-Package JD.MSBuild.Containers -Version 0.1.0
<PackageReference Include="JD.MSBuild.Containers" Version="0.1.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="JD.MSBuild.Containers" Version="0.1.0" />
<PackageReference Include="JD.MSBuild.Containers"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add JD.MSBuild.Containers --version 0.1.0
#r "nuget: JD.MSBuild.Containers, 0.1.0"
#:package JD.MSBuild.Containers@0.1.0
#addin nuget:?package=JD.MSBuild.Containers&version=0.1.0
#tool nuget:?package=JD.MSBuild.Containers&version=0.1.0
JD.MSBuild.Containers
MSBuild tasks, targets, and props to integrate OCI containers with your .NET projects
Automate Docker containerization during dotnet build. Zero manual steps, full CI/CD support, reproducible container builds with granular control over every step of the process.
Quick Start
Installation
dotnet add package JD.MSBuild.Containers
Basic Usage - Generate Dockerfile Only
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JD.MSBuild.Containers" Version="*" />
</ItemGroup>
</Project>
Run dotnet build and a Dockerfile will be generated in your project directory.
Full Automation - Generate and Build
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>
Run dotnet publish to generate the Dockerfile and build the Docker image.
Build-Only Mode - Use Existing Dockerfile
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>false</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnPublish>true</DockerBuildOnPublish>
<DockerfileSource>$(MSBuildProjectDirectory)\custom.Dockerfile</DockerfileSource>
</PropertyGroup>
Key Features
Granular Control
JD.MSBuild.Containers is designed as a configurable OCI MSBuild shim integration. Every feature can be independently enabled or disabled:
- ✅ Generate Dockerfile - Auto-generate optimized multi-stage Dockerfiles
- ✅ Build Images - Execute
docker buildduring MSBuild - ✅ Run Containers - Start containers after build (opt-in)
- ✅ Push to Registry - Automatically push to container registries
- ✅ Pre/Post Scripts - Execute custom scripts at any stage
- ✅ Incremental Builds - Skip regeneration when nothing changes
- ✅ MSBuild Hooks - Integrate with Build, Clean, Publish, Run targets
Configuration Modes
| Mode | Generate | Build | Use Case |
|---|---|---|---|
| Generate-Only | ✅ | ❌ | Review/commit Dockerfiles, manual builds |
| Build-Only | ❌ | ✅ | Use existing Dockerfiles, custom templates |
| Full Automation | ✅ | ✅ | Complete CI/CD, zero manual steps |
| Custom Hooks | ➖ | ➖ | Execute scripts only, manual everything else |
Configuration Reference
Core Enablement
| Property | Default | Description |
|---|---|---|
DockerEnabled |
false |
Master switch for Docker integration |
DockerGenerateDockerfile |
true (when enabled) |
Controls Dockerfile generation |
DockerBuildImage |
false |
Controls Docker image building |
DockerRunContainer |
false |
Controls container execution |
DockerPushImage |
false |
Controls pushing to registry |
Hook Integration
| Property | Default | Description |
|---|---|---|
DockerGenerateOnBuild |
true |
Generate Dockerfile during Build |
DockerBuildOnBuild |
false |
Build image during Build |
DockerBuildOnPublish |
true |
Build image during Publish |
DockerRunOnBuild |
false |
Run container after Build |
DockerPushOnPublish |
true |
Push image after Publish |
Script Execution
| Property | Default | Description |
|---|---|---|
DockerPreBuildScript |
- | Path to pre-build script |
DockerPostBuildScript |
- | Path to post-build script |
DockerPrePublishScript |
- | Path to pre-publish script |
DockerPostPublishScript |
- | Path to post-publish script |
DockerExecutePreBuildScript |
true (if script set) |
Enable pre-build script |
DockerExecutePostBuildScript |
true (if script set) |
Enable post-build script |
DockerExecutePrePublishScript |
true (if script set) |
Enable pre-publish script |
DockerExecutePostPublishScript |
true (if script set) |
Enable post-publish script |
Image Configuration
| Property | Default | Description |
|---|---|---|
DockerImageName |
$(AssemblyName).ToLower() |
Docker image name |
DockerImageTag |
latest |
Docker image tag |
DockerRegistry |
- | Container registry URL |
DockerBaseImageRuntime |
mcr.microsoft.com/dotnet/aspnet |
Runtime base image |
DockerBaseImageSdk |
mcr.microsoft.com/dotnet/sdk |
SDK base image |
DockerBaseImageVersion |
Auto-detected | Base image version |
Build Options
| Property | Default | Description |
|---|---|---|
DockerBuildContext |
$(MSBuildProjectDirectory) |
Docker build context |
DockerBuildArgs |
- | Additional build arguments |
DockerBuildPlatform |
- | Target platform (e.g., linux/amd64) |
DockerBuildTarget |
- | Target stage in multi-stage builds |
DockerUseMultiStage |
true |
Use multi-stage Dockerfiles |
DockerOptimizeLayers |
true |
Optimize Docker layers |
File Paths
| Property | Default | Description |
|---|---|---|
DockerfileOutput |
$(MSBuildProjectDirectory)\Dockerfile |
Generated Dockerfile path |
DockerfileSource |
$(MSBuildProjectDirectory)\Dockerfile |
Existing Dockerfile path |
DockerOutput |
$(BaseIntermediateOutputPath)docker\ |
Build output directory |
DockerTemplateFile |
- | Custom Dockerfile template |
Advanced Options
| Property | Default | Description |
|---|---|---|
DockerUseFingerprinting |
true |
Enable incremental builds |
DockerLogVerbosity |
minimal |
Logging level (quiet/minimal/normal/detailed/diagnostic) |
DockerCommand |
docker |
Docker CLI command |
DockerProjectType |
Auto-detected | Project type (console/library) |
DockerExposePort |
8080 (ASP.NET) |
Exposed port |
DockerUser |
app |
Container user |
DockerCreateUser |
true |
Create non-root user |
Usage Examples
Example 1: Generate-Only Mode (Default)
Perfect for committing Dockerfiles to version control and reviewing before build:
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
</PropertyGroup>
dotnet build
# Dockerfile generated at ./Dockerfile
# No Docker image built
Example 2: Build-Only Mode
Use your own hand-crafted Dockerfile:
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>false</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnPublish>true</DockerBuildOnPublish>
<DockerfileSource>$(MSBuildProjectDirectory)\deploy\Dockerfile</DockerfileSource>
</PropertyGroup>
dotnet publish
# Uses existing Dockerfile at ./deploy/Dockerfile
# Builds Docker image
Example 3: Full Automation
Generate and build automatically:
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnPublish>true</DockerBuildOnPublish>
<DockerImageName>myapp</DockerImageName>
<DockerImageTag>$(Version)</DockerImageTag>
<DockerRegistry>myregistry.azurecr.io</DockerRegistry>
</PropertyGroup>
dotnet publish
# Generates Dockerfile
# Builds image: myregistry.azurecr.io/myapp:1.0.0
Example 4: CI/CD with Scripts and Push
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnPublish>true</DockerBuildOnPublish>
<DockerPushImage>true</DockerPushImage>
<DockerPushOnPublish>true</DockerPushOnPublish>
<DockerPreBuildScript>$(MSBuildProjectDirectory)\scripts\pre-build.sh</DockerPreBuildScript>
<DockerPostPublishScript>$(MSBuildProjectDirectory)\scripts\deploy.ps1</DockerPostPublishScript>
<DockerRegistry>myregistry.azurecr.io</DockerRegistry>
<DockerImageName>myapp</DockerImageName>
<DockerImageTag>$(GitVersion_SemVer)</DockerImageTag>
</PropertyGroup>
Example 5: Development Workflow with Auto-Run
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
<DockerBuildImage>true</DockerBuildImage>
<DockerBuildOnBuild>true</DockerBuildOnBuild>
<DockerRunContainer>true</DockerRunContainer>
<DockerRunOnBuild>true</DockerRunOnBuild>
<DockerPortMappings>8080:8080</DockerPortMappings>
<DockerEnvironmentVariables>ASPNETCORE_ENVIRONMENT=Development</DockerEnvironmentVariables>
<DockerVolumeMappings>$(MSBuildProjectDirectory)/data:/app/data</DockerVolumeMappings>
</PropertyGroup>
dotnet build
# Generates Dockerfile
# Builds image
# Starts container with port mappings
Example 6: Selective Script Execution
Execute only specific scripts:
<PropertyGroup>
<DockerEnabled>true</DockerEnabled>
<DockerGenerateDockerfile>true</DockerGenerateDockerfile>
<DockerPreBuildScript>$(MSBuildProjectDirectory)\scripts\setup.sh</DockerPreBuildScript>
<DockerPostBuildScript>$(MSBuildProjectDirectory)\scripts\cleanup.sh</DockerPostBuildScript>
<DockerExecutePreBuildScript>true</DockerExecutePreBuildScript>
<DockerExecutePostBuildScript>false</DockerExecutePostBuildScript>
</PropertyGroup>
Lifecycle Hooks
JD.MSBuild.Containers provides extensibility points at every stage:
Build:
├─ BeforeDockerGeneration
├─ DockerResolveInputs
├─ DockerComputeFingerprint
├─ DockerGenerateDockerfile
├─ AfterDockerGeneration
├─ DockerExecutePreBuildScript
├─ BeforeDockerBuild
├─ DockerBuild
├─ AfterDockerBuild
├─ DockerExecutePostBuildScript
├─ BeforeDockerRun
├─ DockerRun
└─ AfterDockerRun
Publish:
├─ DockerExecutePrePublishScript
├─ DockerPublish (generates + builds)
├─ DockerExecutePostPublishScript
└─ DockerPushImage (if enabled)
Clean:
└─ DockerClean (removes generated files)
You can define custom targets that depend on or extend these hooks:
<Target Name="MyCustomPreBuild" BeforeTargets="DockerBuild">
<Message Text="Running custom logic before Docker build" Importance="high" />
</Target>
<Target Name="MyCustomPostBuild" AfterTargets="AfterDockerBuild">
<Message Text="Running custom logic after Docker build" Importance="high" />
</Target>
Requirements
- .NET SDK 8.0+
- Docker (when building images)
Comparison with Alternatives
| Feature | JD.MSBuild.Containers | Built-in SDK | Docker Desktop |
|---|---|---|---|
| Auto-generate Dockerfiles | ✅ | ❌ | ❌ |
| Granular control | ✅ | ❌ | ❌ |
| Build-only mode | ✅ | ❌ | N/A |
| Generate-only mode | ✅ | N/A | N/A |
| Pre/Post scripts | ✅ | ❌ | ❌ |
| MSBuild integration | ✅ | Limited | ❌ |
| Incremental builds | ✅ | ❌ | ❌ |
| Custom templates | ✅ | ❌ | N/A |
| Multi-stage support | ✅ | ❌ | ✅ |
Contributing
Contributions are welcome! Please open an issue first to discuss changes.
License
This project is licensed under the MIT License. See LICENSE for details.
Acknowledgments
- Architecture inspired by JD.Efcpt.Build
- Docker for container runtime
- Microsoft for .NET SDK and MSBuild
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.