Using Docker with ASP.NET Core: A Practical Example

Introduction

Hey there, fellow developers! If you’re like me, juggling multiple projects and environments, you know how frustrating it can be to ensure your ASP.NET Core app runs smoothly across different machines. One day, everything works perfectly on your local setup, and the next, you’re stuck debugging weird dependency issues. That’s where Docker comes in to save the day!

In this guide, I’ll walk you through how I containerized an ASP.NET Core application for one of my recent project. We’ll cover setting up a Dockerfile, configuring Docker Compose, and making sure our containerized app works seamlessly with PostgreSQL.

By the end, you’ll have a running ASP.NET Core app inside a Docker container, fully isolated, reproducible, and easy to deploy.

Why Use Docker for ASP.NET Core?

Before we start coding, let’s quickly go over why Docker is a game-changer:

  • Consistency – No more “works on my machine” issues. The app runs the same way across all environments.
  • Isolation – Keeps dependencies and configurations separated from your host machine.
  • Scalability – Works seamlessly with Kubernetes for scaling applications.
  • Easier Deployment – Deploy to any cloud provider or server without headaches.

I’ve personally use Docker in my Personal Project, where I needed an environment that could run ASP.NET Core, PostgreSQL, and some background services without dealing with mismatched dependencies across different setups.


Here are the steps you need to run an ASP.NET Core application in a Docker container. Steps 5, 6 and 8 provide a quick preview of how to add a database to your application and push your Docker image to Docker Hub for deployment to production which is a more real-world scenario.

Step 1: Setting Up the ASP.NET Core Application

Let’s start by creating a simple ASP.NET Core Web API

Bash
mkdir DockerAspNetCoreApp
cd DockerAspNetCoreApp
dotnet new webapi -n MyDockerApp
cd MyDockerApp

This will create a new ASP.NET Core Web API project inside MyDockerApp.

Now, run it locally to make sure everything works:

Bash
dotnet run

You should see output similar to this:

Bash
Now listening on: https://localhost:5001
Now listening on: http://localhost:5000

Open https://localhost:5001/swagger in your browser, and you should see the Swagger UI with the default weather forecast endpoint.

Step 2: Writing the Dockerfile

Now that we have our ASP.NET Core API, let’s containerize it using a Dockerfile. Inside your project directory, create a file named Dockerfile (without an extension) and add the following:

Dockerfile
# Use the official .NET SDK as the base image for building
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o out

# Use the ASP.NET runtime image to run the application
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyDockerApp.dll"]

This does the following:

  1. Uses the .NET SDK image to build the application
  2. Restores dependencies and publishes the app
  3. Copies the compiled output to a lightweight runtime container
  4. Runs the app using dotnet MyDockerApp.dll
Step 3: Building and Running the Docker Container

To keep our image clean, let’s create a .dockerignore file in the root of our project:

Bash
bin/
obj/
.vscode/
.git/

This prevents unnecessary files from being copied into the container.

Step 4: Building and Running the Docker Container

Now’ let’s build and run our containerized app

Build the Docker Image

Bash
docker build -t mydockerapp .

Run the Container

Bash
docker run -d -p 8080:8080 mydockerapp

Now, open http://localhost:8080 in your browser, and you should see your API running inside Docker!

Step 5: Adding PostgreSQL with Docker Compose

Now, let’s take it a step further and add a PostgreSQL database using Docker Compose:

Create a docker-compose.yml file

YAML
version: '3.8'

services:
  api:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydatabase
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

This creates:

  • A PostgreSQL database container with credentials
  • A Docker Volume to persist database data
  • A dependency between API and database so that the API starts only after the database is ready.

Run Everything with Docker Compose

Bash
docker-compose up -d

Your ASP.NET Core app will now run inside a containerized environment along with a PostgreSQL database

Step 6: Connecting ASP.NET Core to PostgreSQL

Modify your appsettings.json file to use PostgreSQL:

JSON
"ConnectionStrings": {
  "DefaultConnection": "Host=db;Port=5432;Username=[USERNAME HERE];Password=[PASSWORD HERE];Database=[DATABASE NAME HERE]"
}
Step 7: Debugging Dockerized ASP.NET Core Apps

if something isn’t working, you can check the logs:

Bash
docker logs <container_id>

To get inside a running container:

Bash
docker exec -it <container_id> /bin/bash
Step 8: Deploying to Docker Hub

Once your app works locally, you can push it to Docker Hub:

Bash
docker tag mydockerapp mydockerhubusername/mydockerapp
docker push mydockerhubusername/mydockerapp

On your production server, pull and run:

Bash
docker pull mydockerhubusername/mydockerapp
docker run -d -p 8080:8080 mydockerhubusername/mydockerapp

Using Docker with ASP.NET Core simplifies deployment, ensures consistency and makes scaling easier. If you’re not using Docker yet, I highly recommend giving it a try.


Sources and References:

Assi Arai
Assi Arai
Articles: 31