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 Sat, December 15, 2018
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
).
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.
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}
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/
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).
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}
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.