How to build a Docker image out of the ASP.NET Core application and host its container on AWS EC2 instance
Table of contents:
- Create .NET Core application
- Building the Docker image
- 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
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.
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();
});
}
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
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:
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.
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 /srcCOPY *.csproj ./
RUN dotnet restoreCOPY . ./
RUN dotnet publish -c Release -o outFROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
EXPOSE 80
COPY --from=build-image /src/out ./
ENTRYPOINT ["dotnet", "BasicAPI.dll"]
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:
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 :
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.
Click on “Instances” on the left side and then click “Launch Instance”:
Select Amazon Linux 2 AMI (HVM), SSD Volume Type:
Select the instance that says “Free tier eligible”. Click “Review and Launch”.
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”.
Click “Add rule” and select HTTP as the Type of the rule. Check if the following values are correct in your setup:
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.
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
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:
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
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
Let’s check the URL:
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.
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!