Building Docker Images in AWS CodeBuild and Storing them in ECR using CodePipeline
Introduction
As cloud-native applications become the standard, serverless and containerized solutions have surged in popularity. For developers working with AWS, using Docker and AWS CodePipeline provides a streamlined way to create, test, and deploy applications. In this blog, we’ll discuss how to automate Docker image builds in AWS CodeBuild, set up a CI/CD pipeline using AWS CodePipeline, and push the final image to Amazon Elastic Container Registry (ECR) for storage.
This guide is suitable for AWS intermediate users who are new to Docker and are interested in building robust CI/CD pipelines.
Step 1: Setting Up an Amazon ECR Repository
Amazon Elastic Container Registry (ECR) is a fully managed Docker container registry that helps you securely store, manage, and deploy Docker container images.
Let’s start by creating an ECR repository
- Log in to the AWS Management Console.
- Navigate to Amazon ECR and click Create repository.
- Provide a name for your repository, e.g.,
my-docker-application-repo
. - Configure any additional settings as needed.
- Click Create repository.
Once created, ECR will provide you with a repository URL that will be used to push and pull Docker images.
Step 2: Preparing Your Docker Application
You should have a Dockerfile prepared for your application. The Dockerfile is a script with instructions on how to build your Docker image. Here’s an example of a simple Dockerfile:
# Use an official node image as the base FROM node:14 # Create and set the working directory WORKDIR /usr/src/app # Copy application code COPY . . # Install dependencies RUN npm install # Expose the application port EXPOSE 8080 # Run the application CMD ["npm", "start"]
Place this Dockerfile in the root directory of your project.
Step 3: Creating the CodeBuild Project for Docker Image Creation
AWS CodeBuild will be responsible for building the Docker image and pushing it to ECR. Here’s how to set it up:
Create a CodeBuild Project
- In the AWS Management Console, navigate to AWS CodeBuild.
- Click Create build project.
- Name your project, e.g., Build-Docker-Image.
- Under Source, select your source repository, such as GitHub or CodeCommit, and provide the repository details.
- Under Environment, select the following:
- Environment image: Choose Managed image.
- Operating system: Amazon Linux 2
- Runtime: Standard
- Image: Select a Docker-enabled image, such as aws/codebuild/amazonlinux2-x86_64-standard:3.0
- Privileged: Enable privileged mode to allow Docker commands in the build.
- Under Buildspec, you can either define the commands directly or use a buildspec.yml file in your source code repository. For this example, we’ll use a buildspec.yml.
Creating the buildspec.yml
File
buildspec.yml
file with the following contents: version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region | docker login --username AWS --password-stdin
build:
commands:
- echo Building the Docker image...
- docker build -t my-application .
- docker tag my-application:latest :latest
post_build:
commands:
- echo Pushing the Docker image to ECR...
- docker push :latest
artifacts:
files:
- '**/*'
<your-region>
and <your-ecr-repo-url>
with the actual values for your AWS region and ECR repository URL.Step 4: Setting Up AWS CodePipeline
Now that CodeBuild is ready to build and push your Docker image, we’ll set up AWS CodePipeline to automate the build process.
Create a CodePipeline
- Go to AWS CodePipeline and click Create pipeline.
- Name the pipeline, e.g., Docker-Build-Pipeline.
- Choose a new or existing S3 bucket for pipeline artifacts.
- In Service role, select "Create a new service role."
- Click Next.
Define Source Stage
- For Source provider, select your code repository (e.g., GitHub).
- Connect your repository and select the branch containing the Dockerfile and buildspec.yml.
- Click Next.
Add Build Stage
- In the Build provider section, select AWS CodeBuild.
- Choose the CodeBuild project you created earlier, Build-Docker-Image.
- Click Next.
Review and Create Pipeline
Review your settings, and then click Create pipeline. Your pipeline is now set up to build the Docker image and push it to ECR whenever changes are detected in the source repository.
Step 5: Setting Up IAM Permissions
For security purposes, AWS IAM policies need to be configured correctly to enable CodeBuild and CodePipeline to access ECR. Here’s how to configure permissions:
- CodeBuild Service Role: Ensure the role used by CodeBuild has permissions for ECR.
- CodePipeline Service Role: The CodePipeline service role should have the necessary permissions to trigger CodeBuild and access the repository.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:PutImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:ListBucket" ], "Resource": "*" } ] }
Step 6: Testing the Pipeline
With everything in place, push some changes to your source repository. CodePipeline should automatically detect the changes, trigger CodeBuild, and build and push the Docker image to ECR.
You can verify this by checking the CodePipeline console to see each stage’s status. If everything succeeds, your Docker image will be available in Amazon ECR!
Conclusion
In this blog, we explored how to build a Docker image in AWS CodeBuild and push it to Amazon ECR, all within an automated pipeline set up using AWS CodePipeline. By using these services together, you can create a scalable, efficient, and reliable CI/CD pipeline for containerized applications, without the need for managing server infrastructure.
This approach leverages the benefits of serverless infrastructure and allows you to focus more on building and deploying applications rather than managing build servers.