Continuous deployment of a Dockerized .NET Core app to AWS ECR
Fullstack Developer and Tech Author
This tutorial covers:
- Creating a container image for a cloned .Net Core demo application, building and running the container locally
- Deploying the Docker image to AWS ECR
- Writing a configuration file to automate building and deploying your container image using CircleCI
Containers are a useful tool for deploying applications because they allow for the packaging of an application’s code, libraries, and dependencies into a single, isolated unit. This makes it easy to deploy and run the application on any computer or server that has the necessary container software installed.
AWS Elastic Container Registry (ECR) is a managed container registry service used to store, manage, and deploy container images. It is fully integrated with other AWS services and provides a scalable and secure way to manage your container images. ECR allows you to store and retrieve images using the Docker CLI, and also integrates with other Docker tools like Docker Compose and Docker Swarm. With ECR, you can easily store and manage your Docker images in a central location and access them from anywhere in your AWS account.
In this tutorial, you will build an ASP.NET Core container with Docker and push the container image to Amazon Elastic Container Registry (Amazon ECR). When you complete the project, every new container image built as a result of changes made to your codebase will be pushed and stored on the AWS container registry.
Prerequisites
You will need the following for this tutorial:
- Basic knowledge of building applications with ASP.NET Core framework.
- Docker Desktop installed on your local machine. You can follow Docker’s tutorial for Windows or macOS.
- A CircleCI account.
- An AWS account.
- A GitHub account.
Our tutorials are platform-agnostic, but use CircleCI as an example. If you don’t have a CircleCI account, sign up for a free one here.
Cloning the demo project
To begin, issue this command from the terminal to clone the demo project from GitHub using Git:
git clone https://github.com/CIRCLECI-GWP/docker-dotnet-api-ecr
This will clone the project into a docker-dotnet-api-ecr
folder in your development folder (or whenever you ran the command from).
Building the Docker image locally
To build a custom Docker image for this project, you need to create a special type of file named Dockerfile
.
Dockerfile
is a text file that contains a set of instructions for building a Docker image. It is a simple, yet powerful tool that allows developers to define the environment and dependencies needed to run their applications in a consistent and reliable manner.
In this tutorial, you will use the Dockerfile included in the downloaded demo project to build the custom container image. The Dockerfile
has the commands needed to install all the project’s dependencies, build the project, and run it.
Go to the root directory of the application, open the Dockerfile
, and make sure it has this content:
# Build Stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o output
# Serve Stage
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
WORKDIR /app
COPY --from=build /app/output .
ENTRYPOINT [ "dotnet", "docker-dotnet-api.dll" ]
There are two different stages specified in this file:
Build
uses the .NET SDKto install any required dependencies before building the project and publishing it to a folder namedout
.Serve
uses the ASP.NET Core runtime image to run the application from the specified working directory, which isapp
in this case.
This is sometimes called a multi-stage Dockerfile. It combines development and production instructions into a single Dockerfile and reduces complexity in the process.
Next, issue this command to build the Docker image:
docker build -t dotnet-api:latest .
Based on the content of the application and the Dockerfile, this command will build the container image. You can confirm that the image was created using the command below to print out list of container images:
docker images
You will see a list of images, including dotnet-api
.
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-api latest b7b390e1661b 43 seconds ago 215MB
Running the Docker image locally
With the local version of the container image successfully built, run it with this command:
docker run -dit -p 5001:80 dotnet-api:latest
This command runs the container in the background, prints the container ID to the terminal, and runs the app on port 5001
. Visit http://localhost:5001/api/weather
to review it.
Deploying the Docker image to Amazon ECR
In this section, you will create a user that will programmatically have access to push container images to the Amazon registry. To do that, navigate to AWS management console and select IAM. This service lets you manage access to AWS resources.
Create a user with a unique name. I called mine dotnet-user
. Make sure you tick option Access key - Programmatic access.
Next, set permissions for the user. Click Attach existing policies directly. Search for and choose these policies:
AmazonEC2ContainerRegistryFullAccess
: This policy allows user to have full access to the container registry and its APIs.AmazonEC2ContainerRegistryPowerUser
: This grants user the administrative right to read and write to repositories.
From here, click Next twice, then click the Create User button in the Review Page.
You will be presented a success message along with your user credentials. This page is displayed only once, so make a note of the Access Key ID and the Secret access key. If you prefer, you can download a .csv file that contains the same credentials.
Automating container image deployment
Next, you will use CircleCI to automate the deployment of your Docker image to Amazon ECR. To easily do this, you will leverage the Circle Orb name circleci/aws-ecr specifically created with commands to automatically:
- Build a Docker image
- Login to Amazon container registry
- Create an Amazon ECR repo, if one doesn’t exist and
- Push the image to Amazon ECR
The downloaded project already contains a .circleci
folder with a config.yml
file in it. Open the config.yml
file and make sure it has this content:
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@8.1.3
workflows:
build_and_push_image:
jobs:
- aws-ecr/build-and-push-image:
context: dev
create-repo: true
dockerfile: Dockerfile
path: .
repo: dotnet-ecr
tag: "$CIRCLE_SHA1"
This configuration file uses the Amazon Elastic Container Registry orb to build and deploy the Docker image. The dockerfile:
command specifies the path to your Dockerfile.
The repo
command specified the ECR repository as dotnet-ecr
. This will be created if it doesn’t exist as stated by the create-repo
flag. Also, to successfully deploy images to Amazon ECR, it is required that you supply your Amazon credentials. For that, you should use contexts in CircleCI.
Adding Context for Amazon ECR credentials
From your CircleCI dashboard, go to the Organization Settings page by clicking on the link in the sidebar.
Then, select Contexts, click the Create Context button, and add a unique name for your Context. The Context appears in a list with security set to All members
. This means that anyone in your organization can access this Context at runtime. As specified in the .circleci/config.yml
configuration for this tutorial, the Context name should be dev
.
Next, select the dev
context, click Add Environment Variable and enter these variables:
AWS_ACCESS_KEY_ID
- The AWS access key id for thedotnet-user
IAM role you had created earlier.AWS_SECRET_ACCESS_KEY
- AWS secret key fordotnet-user
IAM role that you had created earlier.AWS_ECR_REGISTRY_ID
- The 12 digit AWS id associated with the ECR account. This is also known as account ID. You can find this from the AWS Support Page.AWS_REGION
- AWS region where your ECR resources will be located.
Connecting the application to CircleCI
Now you can change your remote repository URL if you cloned the repo for this tutorial and push your project to GitHub.
Log in to your CircleCI account. If you signed up with your GitHub account, all your repositories will be available on your project’s dashboard. Locate the dotnet-ecr
project and click Set Up Project.
Enter the name of the branch where your code is housed on GitHub and click Set Up Project.
Your first workflow will start running and complete successfully.
To view the repository information, go to your AWS management Console.
Conclusion
With CircleCI deployment properly configured, you can easily make changes to your codebase, deploy to GitHub and be assured that your Docker image on Amazon container registry will always be updated with a new version without any manual effort from you.
I hope that you found this tutorial helpful. Happy coding!