Building and publishing Docker containers from Circle CI (to ECR)
Want to build and publish a Docker container from CircleCI? Here’s how MailSlurp does it.
Background
MailSlurp is an API for testing email interaction with real, ephemeral email addresses. We write services in Kotlin and deploy them using Docker, ECR (as our Docker repository) and Kubernetes (EKS).
Setup a CircleCI config
First thing’s first. In your project create a .circleci
folder and inside that create a config.yml
file. We’ll use this to define a workflow with two jobs: Test and Deploy.
Test will checkout the project inside an openjdk image and run the test-suite. If this passes the Deploy job will begin. Deploy runs inside a Docker container (docker-ception?) and installs the AWS CLI (for ECR) and then runs a packaging script. “What’s inside this packaging script?” you ask? Let’s have a look.
version: 2
jobs:
test:
docker:
- image: openjdk:8
steps:
- checkout
- run: ./gradlew clean test --stacktrace --info
deploy:
docker:
- image: docker:18.06.1-ce-git
steps:
- checkout
- setup_remote_docker
- run:
name: Install dependencies
command: |
apk add py-pip
pip install awscli
- run:
name: Build image and push
command: ./package.sh
workflows:
version: 2
build_and_deploy:
jobs:
- test
- deploy:
requires:
- test
filters:
branches:
only: master
Packaging
package.sh
is a shell script that will build, tag, and push our Docker image to a Docker repository: in our case ECR. Notice how we use a datetime as a unique build version. You could also use the built-in $CIRCLE_BUILD_NUM
variable if your prefer. We also tag the image with the latest
tag for easier deploys. The AWS CLI is used to authenticate Docker with our ECR repository.
#!/usr/bin/env sh
set -e
REGION="YOU_AWS_REGION"
ECR_URL="YOUR_ECR_URL"
BUILD_NUMBER="${BUILD_NUMBER:-$(date +%s)}"
JAR_PATH="PATH_TO_YOUR_JAR"
echo "Building $BUILD_NUMBER"
# log docker into eks using aws cli
$(aws ecr get-login --no-include-email --region $REGION)# build a docker image with a unique build number
docker build -t $ECR_URL:$BUILD_NUMBER \
--build-arg JAR_PATH="$JAR_PATH" \
--build-arg VERSION="$BUILD_NUMBER" \
.
# push to ecr
docker push $ECR_URL:$BUILD_NUMBER
#tag for "latest" and also push that
docker tag $ECR_URL:$BUILD_NUMBER $ECR_URL:latest
docker push $ECR_URL:latest
Running your workflow
You can now import your project into CircleCI. It will detect the .circleci/config.yml
file and try to run your workflow. It will likely fail though as the AWS CLI will not have credentials to access your ECR repository.
For this create an IAM user with a ECR access and export the access key id and secret access key variables. Add these as environment variables in the CircleCI project settings page.
AWS_ACCESS_KEY_ID=your_ecr_users_access_key
AWS_SECRET_ACCESS_KEY=your_ecr_users_secret
Success
You should now see a your workflow execute in CircleCI each time you push to master. Two tagged images will be pushed to the repository your specified, one with a unique timestamp of the build and another with the latest
tag.
Deploying these images to production via ECS or EKS (Kubernetes) is a different story but for now we hope this helps.
If you’re interested in testing user sign-up, transactional mail, and more using real email addresses, checkout https://www.mailslurp.com
Thanks!