How to build a Docker image out of the ASP.NET Core application and host its container on AWS EC2 instance

Marius Gaigalas
8 min readJan 21, 2021

Table of contents:

  1. Create .NET Core application
  2. Building the Docker image
  3. Host the container on AWS EC2

In this article, I am going to show how to build a Docker image out of the ASP.NET Core Web API application and host its container in AWS EC2 instance. For this tutorial you are going to need the following requirements:

  • Visual Studio Code
  • .NET Core SDK (I am using version .NET 5.0)
  • Docker Desktop
  • Docker Hub account
  • AWS account
Photo by Jerry Zhang on Unsplash

Create .NET Core application

First things first open your VS Code editor. Toggle your terminal with ‘Ctrl+`'. Check if you have .NET Core SDK and Docker on your computer by running the following commands:

dotnet --versiondocker --version

The terminal should display SDK and Docker versions like in the picture below. If the terminal does not display versions, go ahead and install .NET Core SDK and Docker.

version check
.NET SDK and Docker is present

Next, run the following command to create an ASP.NET Core Web API project:

dotnet new webapi -n BasicAPI

After creation, run the command below to open your project in the new VS Code window:

code .\BasicAPI\

Open the Startup.cs file that is in the main directory of your project. For the sake of simplicity let’s clean up the Configure() method. We will only leave app.UseRouting() and app.UseEndpoints() methods. The Configure() method should look like this:

public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Configure method
Simplified Configure method

Save the Startup.cs file, make sure the current terminal directory has BasicAPI.csproj file, and run the command that will run your app in the browser:

dotnet run
The app is running on localhost
Application is successfully running on localhost’s 5000 port

In the browser open the HTTP localhost port your application is running on and add ‘/WeatherForecast’ to the URL. In my case, my URL is like this:

http://localhost:5000/WeatherForecast

You should see the Weather API data:

Weather API data

We are seeing the example API of the ASP.NET Core Web API project. In the project, there is WeatherForecastController which displays weather data by HTTP GET request method. The controller is using Route(“[controller]”) in order to be accessed via a browser. By convention, the value of “[controller]” is the Controller’s class name without the word Controller in it:

WeatherForecastController - Controller = WeatherForecast

Therefore, we add ‘/WeatherForecast’ to the URL.

Weather controller
Weather API controller

Building the Docker image

In the main directory of our application let’s create a new file called Dockerfile. The file does not have an extension. Add the following code to the Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-image
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
EXPOSE 80
COPY --from=build-image /src/out ./
ENTRYPOINT ["dotnet", "BasicAPI.dll"]
Dockerfile commands

Dockerfile explanation:

Line 1: sets the Base image to our build process and names it ‘build-image’. Using this image we will build our ASP.NET Core project.

Line 2: sets the working directory for COPY and RUN commands.

Line 4: copies .csproj file from our local machine to the Docker working directory /app.

Line 5: restores the dependencies required by the .csproj file by using our base image specified in line 1.

Line 7: copies the rest of the files from our local machine to the Docker working directory /app.

Line 8: builds the ASP.NET Core project which is in the Docker /app directory and places build files into the Docker /app/out directory.

Line 10: initializes the run stage of the image. We will run our application using aspnet:5.0 image instead of sdk:5.0 because the aspnet:5.0 image is much lighter.

Line 11: sets working directory for aspnet:5.0 image which is going to use COPY and RUN commands.

Line 12: then the image is run in the container it opens port 80 of the container and the container, therefore, can be accessed via port 80.

Line 13: copies the build files from sdk:5.0’s /app/out directory to aspnet:5.0 working directory.

Line 14: tells how to run the container.

For a more detailed explanation of what each Dockerfile command does you can check out this official Dockerfile reference.

.dockerignore

To keep the image as light as possible we are not going to copy /bin and /obj folders while building the project (line 7 and line 8 in Dockerfile). These folders are going to be created anyway because of “dotnet restore” and “dotnet publish” commands.

To ignore /bin and /obj folders let’s create .dockerignore file. Add these two lines to the file:

bin\
obj\

The file should look like this:

.dockerignore file
.dockerignore file

Build the image

Let’s build the image out of our ASP.NET Core project. Run the following command:

docker build -t <your_docker_hub_ID>/basicapi .

Flag -t names the image. Image naming convention is:

<your docker hub ID>/<project name>:<version>

For example:

fedora/httpd:version1.0

If the build passes without errors you can run the command below and view your images:

docker images

Let’s test the image and run the image container on our computer. Run the following:

docker run -p 80:80 <your_docker_hub_ID>/basicapi

Let’s open the http://localhost/WeatherForecast :

Weather data
Weather data from our container

We built the Docker image and run it in the container locally. Now let’s host this image container on AWS EC2 instance.

Push the image to the Docker Hub

First, log in to your Docker Hub account via the terminal in VS Code. Run the command:

docker login --username=<yourhubusername>

After this command, Docker will ask for your password. Fill in your password and press enter. You should be successfully logged in.

To push your image into the Docker Hub, run the following:

docker push <your_docker_hub_ID>/basicapi

After the push, check your Docker Hub. In the section My Profile there should be your new image.

By pulling the image from Docker Hub we will be able to host the image’s container on AWS.

Host the container on AWS EC2

First of all, login into your AWS account console. In the search field type “EC2”. Click the “EC2” selection.

EC2 search in AWS
Searching for EC2

Click on “Instances” on the left side and then click “Launch Instance”:

Select Amazon Linux 2 AMI (HVM), SSD Volume Type:

Linux 2 instance
Amazon Linux 2 AMI

Select the instance that says “Free tier eligible”. Click “Review and Launch”.

Pick the “Free” instance
Free tier eligible instance

We need to allow the internet world to access our server’s port 80. This way everybody will see our Weather data. Let’s add an HTTP security rule. Click the “Edit security groups”.

Edit Security Group

Click “Add rule” and select HTTP as the Type of the rule. Check if the following values are correct in your setup:

Add security rule
Add new security rule

If everything is correct click “Review and Launch” and then click “Launch”.

In the pop-up asking about key pair select “Create a new key pair” if you are planning to access your instance via SSH. I am going to access my instance via a browser (EC2 Instance Connect) so I will choose “Proceed without a key pair”. Launch the instance.

After the successful launch again open up EC2 Instances and wait till your Instance State says “running”. Select your instance and click Connect.

Connect to the instance
The instance is running, let’s connect.

In the pop-up select EC2 Instance Connect. We will connect via a browser. Click Connect:

The new browser window with a console will pop. Run the following command in the console:

sudo yum update -y
Update command
Update command

Then run the command that installs Docker:

sudo amazon-linux-extras install docker

The server will ask if it is ok with you if he installs the Docker. Type in “y” and press Enter:

Accept
Type “y” and click Enter

Start the Docker with the command:

sudo service docker start

Finally, run our container from Docker Hub and bind the server’s port 80 to the container’s port 80. Execute the command:

sudo docker run -p 80:80 <your docker hub ID>/basicapi
Successfully running container
Successfully running container

If you see the green info text and no errors this means that the container with our image is now running. Let’s check it!

In the EC2 Instances select your instance and look for the Public DNS(IPV4) value. Copy the URL, add the “/WeatherForecast” to it and open the URL in the browser. In my case its:

http://ec2-54-174-163-85.compute-1.amazonaws.com/WeatherForecast
Instance Public Domain Name
Locate your instance Public DNS (IPv4)

Let’s check the URL:

Container running on AWS
Our ASP.NET Core app is running in the container on AWS

It works!!! ✨ ✨ ✨

Now let’s terminate the instance so that we don’t use the AWS resources.

In the EC2 Instances, right-click your instance (or select the instance and click “Actions”). Navigate to Instance State and then click Terminate. Confirm it by clicking Yes, Terminate in the pop-up.

Terminate the instance
Terminate the instance

The Instance State will change to terminated. After a few hours, your instance will disappear from the instance list.

Wrapping up

Congrats 👏👏👏 on this tutorial:

  • We created the ASP.NET Core Web API project.
  • We built the Docker image out of our ASP.NET Core project.
  • We run the container with our image locally.
  • We deployed the container with our image on the AWS EC2 instance.

Please leave a comment if you have suggestions or in case something was not clear. Your feedback is greatly appreciated! 😊

Till the next time!

--

--