Skip to content

docker_setting_asp_net_core

Docker - Setting Up ASP.NET Core Applications

Section titled “Docker - Setting Up ASP.NET Core Applications”

ASP.NET Core is Microsoft’s modern, open-source, cross-platform framework for building web applications and services. It’s a redesign of the earlier Windows-only ASP.NET framework. Docker containers provide an excellent way to package, deploy, and run ASP.NET Core applications consistently across different environments, from development to production.

This tutorial guides you through containerizing a simple ASP.NET Core application using Docker, focusing on current best practices.

Before you begin, ensure you have the following installed on your system:

  • Docker Desktop: The easiest way to get Docker running on Windows or macOS. Download it from the official Docker website. During installation on Windows, ensure you enable the WSL 2 (Windows Subsystem for Linux) backend, which is the recommended and default option for running Linux containers (most common for ASP.NET Core). For Linux distributions, follow the official Docker Engine installation guide for your specific OS.
  • .NET SDK: You need the .NET Software Development Kit (SDK) to create and build ASP.NET Core applications. Download the latest Long-Term Support (LTS) version or a newer stable version from the official .NET website.

Verify your installations by opening a terminal or command prompt and running:

docker --version
dotnet --version

These commands should output the installed versions of Docker and the .NET SDK, respectively.

Note: While this guide focuses on modern ASP.NET Core with Linux containers, Docker can also run older ASP.NET Framework applications using Windows Containers. This requires Windows 10/11 Pro/Enterprise or Windows Server, enabling the ‘Containers’ Windows feature, and switching Docker Desktop to use Windows Containers. Images for .NET Framework (like mcr.microsoft.com/dotnet/framework/aspnet) are different from .NET Core images.

Step 1: Create a Simple ASP.NET Core Application

Section titled “Step 1: Create a Simple ASP.NET Core Application”

Let’s start by creating a basic ASP.NET Core web application using the .NET CLI. Open your terminal or command prompt, navigate to a directory where you want to create your project, and run the following commands:

# Create a new directory for your project
mkdir MyAspCoreApp
cd MyAspCoreApp
# Create a new ASP.NET Core Web App (e.g., Razor Pages)
dotnet new webapp -n MyWebApp
# Navigate into the created web app directory
cd MyWebApp

This creates a simple web application named ‘MyWebApp’ in the current directory. You can test it locally by running dotnet run and navigating to the specified URL (usually https://localhost:port or http://localhost:port) in your web browser.

A Dockerfile is a text file containing instructions Docker uses to build a container image. Create a file named Dockerfile (no extension) in the MyWebApp project directory (the same directory containing the .csproj file) with the following content:

# Use the official .NET SDK image as the build environment
# Using 'latest' or specific version like '8.0'
# Choose the SDK version matching your project's target framework
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
# Copy the project file and restore dependencies
COPY *.csproj ./
RUN dotnet restore
# Copy the rest of the application code
COPY . .
# Publish the application
# This compiles the application and prepares it for deployment
RUN dotnet publish -c Release -o /app/publish
# Use the official ASP.NET Core runtime image for the final stage
# This results in a smaller final image size
# Choose the runtime version matching your project's target framework
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
# Copy the published output from the build stage
COPY --from=build-env /app/publish .
# Expose port 8080 for the application
# ASP.NET Core apps often run on port 8080 or 80 within the container
# Check Properties/launchSettings.json for the port your app uses (or configure it)
EXPOSE 8080
# Define the entry point for the container
# This command runs when the container starts
ENTRYPOINT ["dotnet", "MyWebApp.dll"]

Explanation of the Dockerfile:

  • FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env: Starts a build stage using the .NET SDK image (change 8.0 to match your project’s .NET version). This image contains all tools needed to build your app.
  • WORKDIR /app: Sets the working directory inside the container.
  • COPY *.csproj ./: Copies the project file.
  • RUN dotnet restore: Downloads the project dependencies.
  • COPY . .: Copies the rest of your application’s source code.
  • RUN dotnet publish ...: Compiles the application in Release mode and outputs the result to /app/publish.
  • FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime: Starts a new, leaner stage using the ASP.NET Core runtime image. This image only contains the necessary components to run the app, making the final image smaller.
  • WORKDIR /app: Sets the working directory for the runtime stage.
  • COPY --from=build-env /app/publish .: Copies the compiled application from the build stage (build-env) into the runtime stage.
  • EXPOSE 8080: Informs Docker that the container will listen on port 8080. Important: ASP.NET Core Kestrel server defaults might be port 80 or 8080 internally. Check your app’s configuration (Properties/launchSettings.json or Program.cs) or configure it explicitly (e.g., using ASPNETCORE_URLS environment variable) to listen on the exposed port (8080 in this example).
  • ENTRYPOINT ["dotnet", "MyWebApp.dll"]: Specifies the command to run when the container starts, executing your compiled application.

This multi-stage build pattern is a best practice. It keeps your final image small by excluding the build tools and source code, only including the necessary runtime and compiled application.

Now, navigate back to the directory containing your Dockerfile (the MyWebApp directory) in your terminal and run the docker build command:

# Build the image and tag it as 'mywebapp-image'
# The '.' indicates the build context is the current directory
docker build -t mywebapp-image .

Docker will execute the instructions in your Dockerfile, downloading base images (if needed) and creating your application image. This might take a few minutes the first time. The -t flag tags the image with a memorable name (mywebapp-image).

Once the image is built, you can run it as a container:

# Run the container
# -d: Run in detached mode (in the background)
# -p 8081:8080: Map port 8081 on the host to port 8080 in the container
# --name my-running-app: Assign a name to the container
# mywebapp-image: The image to use
docker run -d -p 8081:8080 --name my-running-app mywebapp-image

Explanation:

  • -d: Runs the container in the background.
  • -p 8081:8080: Maps port 8081 on your local machine (the host) to port 8080 inside the container (the port we exposed and expect the app to listen on). You can choose a different host port if 8081 is busy (e.g., -p 5000:8080).
  • --name my-running-app: Gives your container a recognizable name.
  • mywebapp-image: Specifies the image you built in the previous step.

You can check if your container is running using:

docker ps

This command lists all running containers.

Open your web browser and navigate to http://localhost:8081 (using the host port you specified in the docker run command). You should see your running ASP.NET Core web application!

If it doesn’t load, check the container logs for errors:

docker logs my-running-app

Common issues include the application inside the container not listening on the expected port (e.g., 8080 in our example). Ensure the EXPOSE instruction in the Dockerfile and the port mapping (-p host:container) match how your application is configured to run.

To stop and remove the container:

# Stop the container
docker stop my-running-app
# Remove the container
docker rm my-running-app

To remove the Docker image:

docker rmi mywebapp-image
  • Docker Compose: For applications involving multiple containers (e.g., a web app and a database), Docker Compose simplifies defining and running them together. Learn more at the official Docker Compose documentation.
  • Volume Mounting: To persist data or reflect code changes during development without rebuilding the image, mount host directories into the container using volumes (-v flag in docker run or volume definitions in Docker Compose).
  • .dockerignore file: Create a .dockerignore file (similar syntax to .gitignore) in your project directory to exclude unnecessary files/folders (like bin, obj, .git) from the Docker build context, speeding up builds and reducing image size.
  • Container Registries: Push your built images to a registry (like Docker Hub, Azure Container Registry, AWS ECR, Google Container Registry) to share them and use them in deployment pipelines.
  • Security: Always use official base images. Keep base images and dependencies updated. Configure your application securely (e.g., don’t run as root user inside the container if possible - advanced topic).
  • Official Documentation: Refer to the official Docker documentation (docs.docker.com) and ASP.NET Core documentation (docs.microsoft.com/aspnet/core) for more in-depth information.