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.
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 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:
Builduses the .NET SDKto install any required dependencies before building the project and publishing it to a folder named
Serveuses the ASP.NET Core runtime image to run the application from the specified working directory, which is
appin 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:
You will see a list of images, including
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
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: email@example.com 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.
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
Next, select the
dev context, click Add Environment Variable and enter these variables:
AWS_ACCESS_KEY_ID- The AWS access key id for the
dotnet-userIAM role you had created earlier.
AWS_SECRET_ACCESS_KEY- AWS secret key for
dotnet-userIAM 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.
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!
Oluyemi is a tech enthusiast with a background in Telecommunication Engineering. With a keen interest in solving day-to-day problems encountered by users, he ventured into programming and has since directed his problem solving skills at building software for both web and mobile. A full stack software engineer with a passion for sharing knowledge, Oluyemi has published a good number of technical articles and blog posts on several blogs around the world. Being tech savvy, his hobbies include trying out new programming languages and frameworks.