Asp.net Core 3.1 Hello World in Docker on Ubuntu 20.04

Focus

Today we’ll create an Asp.net core 3.1 hello world web application and host it inside a docker container on Ubuntu 20.04. The main intention of writing this blog is to focus on hosting web apps on minimum hardware resources. Appropriately, I have chosen Ubuntu Server and working only with the terminal window command to build your and host the application. I have tried using 512 MB RAM server, but it works extremely slow. Hence would not recommend it. You will need minimum 1 GB RAM machine. A 2 GB RAM machine will run very smoothly in this scenario.

You can try using SSD based machines with lower configuration for better performance but I haven’t tried it.

Install dotnet core sdk and runtime version

Ensure dot net core sdk and runtime are installed on your Ubuntu Server from terminal window:

Run this command in terminal:
dotnet --list-sdks

If it does not return the sdk version, then run the following commands in the terminal to install dotnet sdk on your Ubuntu Server 20.04. The instructions (microsoft docs) here do not work correctly for Ubuntu 20.04. Hence run these commands.

wget http://ftp.us.debian.org/debian/pool/main/i/icu/libicu57_57.1-6+deb9u4_amd64.deb
sudo dpkg -i libicu57_57.1-6+deb9u4_amd64.deb
sudo apt install dotnet-sdk-3.1

If Ubuntu is prompting you “permission denied” for most of your terminal commands and you want to skip typing sudo every time, give the following command

sudo chown <username> <directory>
OR
However, run the following only if you know what you are doing
sudo -s

Run this command again to verify if dotnet sdks are installed correctly: dotnet --list-sdks

Lets create the asp.net core hello world application

Run command: dotnet new webapp -o aspnetcoreapp --no-https --force

This creates the web app into aspnetcoreapp folder. Using the --no-https parameter forces dotnet to not use developmental SSL certificate while running the app. Right now, it would make things simpler to build the first hello world app.

Change the default Program.cs file. Run command nano Program.cs top open a text based editor in your terminal window. Replace the contents in that file with the one below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace aspnetcoreapp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<startup>().UseKestrel().UseUrls("http://0.0.0.0:5000");
                });
    }
}

I have used http://0.0.0.0:5000 . The “0.0.0.0” is used so that the site can easily be accessible from even outside the docker container

Press Ctrl-X, Yes, to save and close the nano editor.

Swtich to that folder and run command: dotnet watch run. This will run the site on port 5000.
You can run curl http://localhost:5000 in your terminal window and check the HTML output.

Very important point – Remember that the site runs on port 5000. However, when the same site is hosted inside the docker container, you need to keep in mind that the site is running on port 5000 even inside the container.

Install docker on the Ubuntu server

Install docker, run:
sudo apt install docker.io

Start docker service, run:
sudo systemctl start docker
sudo systemctl enable docker

Check if docker service is running, run:
sudo systemctl status docker

Create a docker base image

Assuming you are in aspnetcoreapp folder, create a Dockerfile in that folder. As a second hint, you should be in the folder where you .csproj file exists.

To create the Dockerfile, run nano Dockerfile and paste the following contents inside it.

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

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetcoreapp.dll"]

You need to run this command to build the docker image with your web app inside it. This instructs the docker process to generate your docker image.

sudo docker build -t counter-image -f Dockerfile .

This will also add donet SDK and asp.net core runtime inside the container. This can take a while depending on your internet connection speed. Secondly, this also publishes your web app into /app folder inside the container.

The output will be like the screen shot below:

DockerBuildImageOutput

To check what docker images are installed on the server, run:

docker images

DockerImagesOutput

Now you base image is ready with the name counter-image.

Run your asp.net core site inside the docker container

Create a docker container with your base image:

sudo docker run -d -p 8080:5000 --name myapp counter-image

Output – 8f18f4d4cde39820e2ad9a89c914b3a46ee71a238d8e62fd7f4af0b0f20b5909

You will see an output similar. to this This command means that you have created a docker container with base image of counter-image. Your container name is myapp.

Importantly, when you write 8080:5000, your site will be accessible on host Ubuntu machine from 8080 port. Further, on your host machine (Ubuntu server) you can type http://localhost:8080. This will redirect to your request to container’s site running on port 5000. Keep in mind that the site is running on port 5000 inside your container.

You don’t need any web server to be running on your Ubuntu Server (host machine).

Run command docker ps -a to check which containers are running: (output will be like)

DockerPSOutput

You will see that our container is in running state. Check the STATUS column which says “Up XX minutes”. If the status says exited, then your container isn’t running.

You are done! Check your site running status

If you want to run a command inside the container, run:

docker exec myapp curl http://localhost:5000

It if gives your page’s html output, that means your site is running successfully inside the container.

Now you can access the site from your host machine (Ubuntu server). Type:

curl http://localhost:8080 OR wget http://localhost:8080

If you see HTML output of your site, you can access your site from your host server. Additionally, if your host server has a public Static IP address assigned to it, then your site is live on the internet.

Additional tip

My setup: My super host machine is Windows 10. I installed VMWare Player and installed the Ubuntu Server as a guest machine. The docker container runs inside the Ubuntu Server. We’ll be doing port forwarding.

Now you want to check your site inside your browser on Windows 10 (super host :)). You will need to do the following, assuming that your Ubuntu Server is running with a NAT type of network connection on VMWare:

  1. My Ubuntu Server’s IP address is 192.168.26.150.
  2. You need to open and edit vmnetnat.conf inside your C:\ProgramFiles\VMWare folder. Use your favourite text editor (notepad++) in administrator mode.
  3. Jump to section [incomingtcp] and add this line 8888 = 192.168.26.150:8080. Save the file.
  4. Restart VMware NAT Service in your services console on Windows 10.
  5. Open TCP port 8888 on your Windows 10 Firewall.
  6. This means that any request coming on my super host machine (Windows 10) on port 8888 will be redirected to my Ubuntu Server on port 8080. From there on, the request will be redirected to the container site running on port 5000.
  7. Now to check the site from my Windows 10 browser, I now just need to type http://localhost:8888 on my browser and viola!, the site opens up on Windows 10.
 Windows10BrowserShot

Cleanup – docker container and image

Stop the container by running: docker stop myapp

Remove your container, run: docker rm myapp

Remove your docker base image, run: docker rmi counter-image:latest --force
Remember, if you remove the image counter-image, you have to re-build it with the docker build command above.

Conclusion

Even after running the docker container, the RAM usage remains around 430 MB. So an SSD based machine with 1 GB of RAM would also be sufficient to host your small static sites inside docker on Ubuntu machines.

I hope you enjoyed building and hosting your Asp.net core 3.1 hello world application inside a docker container on Ubuntu 20.04. Thank you for your time. Let me know your thoughts on how to make this article better.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *