Running ASP.NET Core Website in docker on a Raspberry Pi
In the current era, software has become incredibly powerful and cross-platform, on top of that even a developer DIY board Raspberry Pi has a lot to offer with the hardware becoming more powerful. Let us take a lot at how we can setup and run ASP.NET Core Web Application in docker on a Raspberry Pi.
Everything starts with an itch to learn something new. So I set out to run ASP.NET Core on docker and found that my desktop was running Windows 10 Home edition. Docker desktop was not an option since its still in preview for Windows 10 Home and also need the latest Windows 10 update. Well one choice was to wait for the update and the other to find alternative options to get the work done.
That’s when I realized I have a Raspberry Pi 3B lying around unused. Earlier I had run Windows 10 IoT on RPI for building a prototype focused on RFID. But this time, I thought of learning something new with the *nix platform.
Well here we are ready to run Raspberry Pi OS (previously called Raspbian) for my docker and ASP.NET Core adventure. Raspberry Pi OS is based on the well-known Debian GNU/Linux operating system and uses a modified LXDE desktop environment called PIXEL or simply the Raspberry Pi Desktop.
If you have not installed .NET Core on your RPI, read my earlier post How to install .NET Core on Raspberry Pi
What is .NET Core?
.NET Core is a free and open-source, managed computer software framework for Windows, Linux, and macOS operating systems. It is a cross-platform successor to.NET Framework. The project is primarily developed by Microsoft and released under the MIT License. .NET Platform source is available on Github.
What is ASP.NET Core?
ASP.NET Core is a free and open-source web framework, which has a better performance than ASP.NET developed by Microsoft and the community. It is a modular framework that runs on both the full .NET Framework for Windows and also on the cross-platform .NET Core.
What is Docker?
Docker is a tool designed to make it easier to create, deploy and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and deploy it as one package. By doing so, thanks to the container, the developer can rest assured that the application will run on any other Docker host (Linux or Windows) machine regardless of any customized settings that machine might have that could differ from the machine used for writing and testing the code.
In a way, Docker is a bit like a virtual machine. But unlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same Linux/Windows kernel as the system that they’re running on and only requires applications be shipped with things not already running on the host computer. This gives a significant performance boost and reduces the size of the application.
In short, Docker is all about Application Virtualization so that you can host your application on any Operating System which supports docker.
How to install Docker on Raspberry Pi?
The following command from local RPI terminal or SSH remote terminal will install docker on RPI
> curl -sSL https://get.docker.com | sh
How to create ASP.NET Core App from CLI?
We are going to create a Hello World ASP.NET App for our example to reduce all the complexity of the Application itself. Here are the steps outlined.
- Making sure we are in the home directory before starting
- Create a folder for our helloweb application
- Switch folder to newly created folder
- Generate our helloweb app
- Run the app to test it
> cd $HOME > mkdir helloweb > cd helloweb > dotnet new web The template "ASP.NET Core Empty" was created successfully. Processing post-creation actions... Running 'dotnet restore' on /home/pi/helloweb/helloweb.csproj... Determining projects to restore... Restored /home/pi/helloweb/helloweb.csproj (in 1.01 sec). Restore succeeded. > dotnew run info: Microsoft.Hosting.Lifetime Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime Hosting environment: Development info: Microsoft.Hosting.Lifetime Content root path: /home/pi/helloweb
Testing and making sure the ASP.NET Core App works
From the last command above you can see that your newly created Web App is listening on localhost. It also provides 2 different ports, one for HTTP (5000) and another for HTTPS (5001).
From RPI console (not SSH), using browser, open http://localhost:5000/ to test if the browser shows Hello World!
If the browser shows “Hello World!” our first stage is done and we are ready to jump to docker.
How to create a Docker Image?
In order to run the application inside docker container, we need to create a docker image with our application. And before creating the docker image, we need to prepare a package or folder to bring our compiled application, all the related libraries and dependencies together. In .NET Core its done using the publish command.
So here we are creating a release build and .NET Core creates a folder called ‘publish’ with all the files required to run the application.
> dotnet publish -c Release Microsoft (R) Build Engine version 16.6.0+5ff7b0c9e for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Determining projects to restore... All projects are up-to-date for restore. helloweb -> /home/pi/helloweb/bin/Release/netcoreapp3.1/helloweb.dll helloweb -> /home/pi/helloweb/bin/Release/netcoreapp3.1/publish/
Next task is to create the docker configuration file
Create a file called ‘Dockerfile’ in the project folder with the content given below.
From RPI terminal or SSH you can use the following command. Nano is a simple text editor. After typing the content, Hit CTRL+X to quit and it will prompt to save the file.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 COPY bin/Release/netcoreapp3.1/publish App/ WORKDIR /App ENTRYPOINT ["dotnet","helloweb.dll"]
Line 1: We are downloading a container base image from Microsoft Container Registry (mcr). Last portion means we are getting ASP.NET Core 3.1 specific base image for running our application.
Line 3: Here we are copying the files in the publish folder to a folder with the name ‘App’ inside the docker image we are creating.
Line 4: We are setting the working directory to the new folder called ‘App’
Line 5: This line specifies the entry point of the application and how to run it. You can see the dll name is the compiled application dll.
Following images can be used in the first line for different purposes as explained.
- Console and other applications where only runtime is required
- For development and compiling your app inside the docker image (larger image)
- For Production/Release for final hosting
Lets build the docker image
Let us build the docker image with our application inside it. Parameter -t denotes tag name for the image. Parameter -f points to the docker configuration file we created in the step above, and the dot is for current folder where the file resides. This step would take time depending on your internet speed since its downloading an image.
> sudo docker build -t hellowebsite-image -f Dockerfile . Sending build context to Docker daemon 1.144MB Step 1/4 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 3.1: Pulling from dotnet/core/aspnet 2dd003996c9a: Pull complete 52ae7ebf826a: Pull complete d1cb8ce1104e: Pull complete 4b57ddfbb902: Pull complete d216cb40879e: Pull complete Digest: sha256:060ebef0165a38e28279f7fd4f12e33d35af1de879442d75dabbcb4bc536e55c Status: Downloaded newer image for mcr.microsoft.com/dotnet/core/aspnet:3.1 ---> 80940ea236f7 Step 2/4 : COPY bin/Release/netcoreapp3.1/publish App/ ---> 3588a2675529 Step 3/4 : WORKDIR /App ---> Running in 6c6f6e58c662 Removing intermediate container 6c6f6e58c662 ---> 08c578f36eb0 Step 4/4 : ENTRYPOINT ["dotnet","helloweb.dll"] ---> Running in 4c085624d52c Removing intermediate container 4c085624d52c ---> 5e46cc24fdda Successfully built 5e46cc24fdda Successfully tagged hellowebsite-image:latest
Once docker image is successfully created we can use the following command to check the details. You can see the base image which got downloaded and then our image which has our application included named as ‘hellowebsite-image’.
> sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE hellowebsite-image latest 5e46cc24fdda 22 seconds ago 186MB mcr.microsoft.com/dotnet/core/aspnet 3.1 80940ea236f7 3 weeks ago 186MB
How to run the website inside docker container?
Below command runs our ‘helloweb’ App from the docker image we created called ‘hellowebsite-image’. Parameter -it is for interactive TTY, parameter –rm is to remove the container once the App stops and -name parameter is to give a name to the container we will be running this docker image inside ‘hello-core-website’.
> sudo docker run -it --rm -p 5000:80 --name hello-core-website hellowebsite-image info: Microsoft.Hosting.Lifetime Now listening on: http://[::]:80 info: Microsoft.Hosting.Lifetime Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime Hosting environment: Production info: Microsoft.Hosting.Lifetime Content root path: /App
How to check the list of containers running?
> sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5b261762e7b3 hellowebsite-image "dotnet helloweb.dll" 20 seconds ago Up 19 seconds 0.0.0.0:5000->80/tcp hello-core-website
Some useful docker commands
// Command to remove a docker image > sudo docker rm [IMAGE TAG] // Command to remove a docker container > sudo docker rmi [CONTAINER ID]
I hope this article helps to get you started with docker if you have an RPI in hand. I love the way .NET core is going with the cross-platform focus. Also very excited to see what .NET 5 and .NET 6 are going to bring to .NET developers.