Getting Started with JD.MSBuild.Containers

This guide will walk you through installing and configuring JD.MSBuild.Containers for your first .NET project.

Prerequisites

Before you begin, ensure you have:

  • .NET SDK 8.0 or later - Download here
  • Docker Desktop or compatible Docker runtime - Download here
  • Basic .NET knowledge - Familiarity with dotnet CLI and .csproj files

Verify Prerequisites

# Check .NET SDK version
dotnet --version
# Should output 8.0.0 or higher

# Check Docker is running
docker --version
# Should output Docker version

# Verify Docker is running
docker ps
# Should show running containers (or empty list if none running)

Installation

Step 1: Add Package Reference

Add JD.MSBuild.Containers to your project using the .NET CLI:

dotnet add package JD.MSBuild.Containers

Or add it directly to your .csproj file:

<ItemGroup>
  <PackageReference Include="JD.MSBuild.Containers" Version="*" />
</ItemGroup>

Note: Using Version="*" will always use the latest version. For production, pin to a specific version.

Step 2: Enable Docker Integration

Add Docker properties to your .csproj file:

<PropertyGroup>
  <!-- Enable Docker integration -->
  <DockerEnabled>true</DockerEnabled>
  
  <!-- Configure image name -->
  <DockerImageName>my-first-app</DockerImageName>
  
  <!-- Configure image tag -->
  <DockerImageTag>latest</DockerImageTag>
</PropertyGroup>

Step 3: Build Your Project

Build your project to generate the Dockerfile:

dotnet build

You should see output indicating the Dockerfile was generated:

Resolving Docker inputs...
Generating Dockerfile at /path/to/your/project/Dockerfile
Dockerfile generated successfully

Step 4: Review Generated Dockerfile

Examine the generated Dockerfile in your project root:

# This file was auto-generated by JD.MSBuild.Containers
# DO NOT EDIT MANUALLY - Changes will be overwritten

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "./"]
RUN dotnet restore "./MyApp.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "MyApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]

Step 5: Build Docker Image (Optional)

To build the Docker image automatically, enable image building:

<PropertyGroup>
  <DockerEnabled>true</DockerEnabled>
  <DockerImageName>my-first-app</DockerImageName>
  <DockerImageTag>latest</DockerImageTag>
  
  <!-- Enable image building -->
  <DockerBuildImage>true</DockerBuildImage>
  <DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>

Now publish your project:

dotnet publish

The Docker image will be built automatically:

Generating Dockerfile...
Building Docker image: my-first-app:latest
docker build -t my-first-app:latest .
[+] Building 45.2s (17/17) FINISHED
Image built successfully: my-first-app:latest

Step 6: Run Your Container

Run the built container:

docker run -p 8080:8080 my-first-app:latest

Access your application at http://localhost:8080.

Quick Start Example Projects

ASP.NET Core Web API

Create a new Web API project with containerization:

# Create new Web API
dotnet new webapi -n MyApi
cd MyApi

# Add JD.MSBuild.Containers
dotnet add package JD.MSBuild.Containers

Edit MyApi.csproj to add:

<PropertyGroup>
  <DockerEnabled>true</DockerEnabled>
  <DockerImageName>myapi</DockerImageName>
  <DockerImageTag>dev</DockerImageTag>
  <DockerBuildImage>true</DockerBuildImage>
  <DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>

Build and run:

dotnet publish
docker run -p 8080:8080 myapi:dev
curl http://localhost:8080/weatherforecast

Console Application

Create a console app with containerization:

# Create new console app
dotnet new console -n MyConsoleApp
cd MyConsoleApp

# Add JD.MSBuild.Containers
dotnet add package JD.MSBuild.Containers

Edit MyConsoleApp.csproj:

<PropertyGroup>
  <DockerEnabled>true</DockerEnabled>
  <DockerImageName>myconsoleapp</DockerImageName>
  <DockerImageTag>latest</DockerImageTag>
  <DockerBuildImage>true</DockerBuildImage>
  <DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>

Build and run:

dotnet publish
docker run myconsoleapp:latest

Worker Service

Create a background worker with containerization:

# Create new worker service
dotnet new worker -n MyWorker
cd MyWorker

# Add JD.MSBuild.Containers
dotnet add package JD.MSBuild.Containers

Edit MyWorker.csproj:

<PropertyGroup>
  <DockerEnabled>true</DockerEnabled>
  <DockerImageName>myworker</DockerImageName>
  <DockerImageTag>latest</DockerImageTag>
  <DockerBuildImage>true</DockerBuildImage>
  <DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>

Build and run:

dotnet publish
docker run myworker:latest

Local Development Workflow

Here's a typical development workflow:

1. Initial Setup

# Clone repository
git clone https://github.com/yourusername/yourproject.git
cd yourproject

# Restore dependencies
dotnet restore

# Build (generates Dockerfile)
dotnet build

2. Iterative Development

# Make code changes
# ...

# Build (regenerates Dockerfile if needed)
dotnet build

# Publish and build image
dotnet publish

# Run container
docker run -p 8080:8080 yourapp:latest

3. Testing Changes

# Run tests
dotnet test

# Build and run in container
dotnet publish
docker run -p 8080:8080 yourapp:latest

# Test the running container
curl http://localhost:8080/health

Configuration Options

Basic Configuration

<PropertyGroup>
  <!-- Master switch -->
  <DockerEnabled>true</DockerEnabled>
  
  <!-- Image identification -->
  <DockerImageName>myapp</DockerImageName>
  <DockerImageTag>latest</DockerImageTag>
  
  <!-- What to do -->
  <DockerGenerateDockerfile>true</DockerGenerateDockerfile>
  <DockerBuildImage>true</DockerBuildImage>
  
  <!-- When to do it -->
  <DockerBuildOnPublish>true</DockerBuildOnPublish>
</PropertyGroup>

Customizing Base Images

<PropertyGroup>
  <!-- Use specific base images -->
  <DockerBaseImageRuntime>mcr.microsoft.com/dotnet/aspnet</DockerBaseImageRuntime>
  <DockerBaseImageSdk>mcr.microsoft.com/dotnet/sdk</DockerBaseImageSdk>
  <DockerBaseImageVersion>8.0</DockerBaseImageVersion>
</PropertyGroup>

Configuring Ports

<PropertyGroup>
  <!-- For ASP.NET Core apps -->
  <DockerExposePort>8080</DockerExposePort>
  
  <!-- Run with custom port mapping -->
  <!-- Use: docker run -p 3000:8080 myapp:latest -->
</PropertyGroup>

Setting Registry

<PropertyGroup>
  <!-- For pushing to a registry -->
  <DockerRegistry>myregistry.azurecr.io</DockerRegistry>
  <DockerImageName>myapp</DockerImageName>
  <DockerImageTag>1.0.0</DockerImageTag>
  
  <!-- Resulting image: myregistry.azurecr.io/myapp:1.0.0 -->
</PropertyGroup>

Troubleshooting

Dockerfile Not Generated

Problem: Running dotnet build doesn't generate a Dockerfile.

Solution: Ensure DockerEnabled is set to true:

<DockerEnabled>true</DockerEnabled>

Docker Build Fails

Problem: Image build fails with errors.

Solution:

  1. Verify Docker is running: docker ps
  2. Check Docker build context: Ensure no large files in project directory
  3. Increase Docker build verbosity:
    <DockerLogVerbosity>detailed</DockerLogVerbosity>
    

Container Won't Start

Problem: Container exits immediately after starting.

Solution:

  1. Check container logs: docker logs <container-id>
  2. Verify entrypoint is correct
  3. For console apps, ensure they don't exit immediately

Wrong .NET Version in Container

Problem: Generated Dockerfile uses wrong .NET version.

Solution: Explicitly set the version:

<DockerBaseImageVersion>8.0</DockerBaseImageVersion>

Next Steps

Now that you have JD.MSBuild.Containers running, explore:

Support

Need help? Check: