Thomas Bandt

Hands-on: Running ASP.NET Core With HTTPS In A Docker Container

This article provides a hands-on beginners guide on how to run an ASP.NET Core website within a docker container, securing all traffic with an SSL certificate, and installing all this within minutes on Ubuntu Linux.

Published on Saturday, 15 December 2018

Prerequisites

  • You already know how to build a web application with ASP.NET Core. If not, I encourage you to take a look.
  • You know about how Docker works, at least in theory. You've got it installed and running on your developer machine. If not, go and get the installer and set it up.
  • My hosting cloud provider of choice is Digital Ocean. It allows you to create a virtual machine running Ubuntu Linux and having Docker preinstalled within seconds. But this will of course also work with other providers.
  • While free certificates are possible for a while now with Let's Encrypt, you can also just buy one for your domain for a couple of bucks, e.g. at namescheap.

On Your Development Machine

Step 1: Creating A Dockerfile For Your App

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app

EXPOSE 80
EXPOSE 443

COPY src/Blog/Blog.sln .
COPY src/Blog/Blog.csproj .
RUN dotnet restore

COPY src/Blog/. ./publish/
WORKDIR /app/publish
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app
COPY --from=build /app/publish/out ./
ENTRYPOINT ["dotnet", "Blog.dll"]

This file assumes your ASP.NET application is located in a directory called ./src/Blog relative to it, your solution's name is Blog.sln, your project's name is Blog.csproj, and the assembly that all this is being compiled into is named Blog.dll. Change this accordingly to your own project.

It will first restore all dependencies, then build the application and create the docker image. So there are no further manual steps (like publishing the app) required.

Your image will be dependent on the official images for .NET Core and ASP.NET Core provided by Microsoft on Docker Hub. While it's most likely for them to be outdated at the time you are reading this, just replace them by their successors (at the two lines starting with FROM).

Step 2: Build And Publish

First you have to build your image:

docker build -t {YOUR_DOCKER_ID}/{YOUR_IMAGE_NAME} .

After that you can publish it to Docker Hub:

docker push {YOUR_DOCKER_ID}/{YOUR_IMAGE_NAME}

Make sure you're logged in with your Docker ID, not your email address associated with that account. Otherwise the push operation will fail.

By the way: Docker Hub let's you host one repository in private for free. If you don't want others to be able to download and install it, you should head over to your account and mark it as private.

On Your Server

Step 3: Set Up A Linux Machine Running Docker

There are most likely thousands of different options how to do this. I decided to go along with Digital Ocean, which offers a fantastic range of services, while having a great user experience on their management website, and a fair pricing model. This website you're just reading for example is running there on the cheapest possible VM for 5$ a month at the time of this writing.

They also offer something they call "One-click install and deploy Docker to an SSD cloud server in 55 seconds". That's the easiest way I know to get to a running Linux machine with Docker installed on it.

After the VM + Docker are being set up, use SSH to log in to it:

ssh root@{YOUR_IP_ADDRESS}

Step 4: Setting Up The SSL (TLS) Certificate

As mentioned at the beginning, I assume you already got your certificate ready. What you will need now is a *.pfx file.

That file needs to be transferred to your server first. As ASP.NET Core will expect it at a specific location, ~/.aspnet/https/, you may need to create that directory first. Second, copy your certificate over there:

scp {YOUR_CERT.pfx} root@{YOUR_IP_ADDRESS}:/root/.aspnet/https/

Step 5: Log In To Docker

Remember to use your Docker ID, not your email address:

docker login

That's all you need to do, Docker is now ready to use (assuming you went with the Docker One-click app at Digital Ocean).

Step 6: Install Your Image

Now you need to download your image from the Docker Hub to your server, which is as easy as uploading it has been before:

docker pull {YOUR_DOCKER_ID}/{YOUR_IMAGE_NAME}

Step 7: Run!

sudo docker run -it -p 80:80 -p 443:443
-e ASPNETCORE_URLS="https://+443;http://+80"
-e ASPNETCORE_HTTPS_PORT=443
-e ASPNETCORE_Kestrel__Certificates__Default__Password="{YOUR_CERTS_PASSWORD}"
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/{YOUR_CERT}.pfx
-v ${HOME}/.aspnet/https:/https/
--restart=always
-d {YOUR_DOCKER_ID}/{YOUR_IMAGE_NAME}

Important: Make sure to remove all line breaks and execute this as a one-liner!

Along with some docker-specific parameters, which for example enable automatic restarts after a crash or a reboot (!) of the VM, we are also setting some environment variables needed by ASP.NET Core.

Kestrel, the .NET Core webserver, will by default use port 80 for HTTP and port 443 for HTTPS when running in production.

So when calling {YOUR_IP_ADDRESS} you should now be able to see your web application.

Probably your browser will warn you because of an invalid certificate – because this is only valid when using the custom domain name you bound it to. Just ignore it, and enjoy the moment.

Now configure your DNS to map your domain to the IP address, and you're good to go.

Congratulations, you did it! 🥳

Update 29 April 2020: The sample docker file now uses .NET Core 3.1.

What do you think? Drop me a line and let me know!