Brief
Kaniko is a tool to build and push Docker images from within a container or k8s cluster.
Importantly, this is done without a Docker daemon.
For CircleCI builds, Kaniko allows us to build and push Docker images without the Remote Docker engine.
In this how-to guide, we will take a look at how to push images, with Kaniko, to the following:
- AWS ECR
- Docker Hub
Before you start
I am using project environment variables (env vars) for storing credentials for Docker Hub and AWS ECR. Your team may choose to use org contexts instead.
Docker Layer Caching feature is not compatible for Kaniko builds (since there are no Docker daemons).
Consider using Kaniko’s caching feature instead.
Please also be aware of existing limitations with Kaniko.
AWS ECR
- Configure AWS credentials
- Ensure least-privilege permissions (to push image to AWS ECR) if possible.
- In this example, I’ve set up AWS credentials via project environment variables
- Define a CircleCI Docker executor job as shown below
jobs:
kaniko-build-push-aws-ecr:
# NOTE: Kaniko executor already comes with AWS ECR credential helper installed
# See https://github.com/GoogleContainerTools/kaniko#pushing-to-amazon-ecr
# What this means is that, we can just inject AWS credentials.
# In this example, we set credentials via AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY project env vars
environment:
# NOTE: Replace these values as required
AWS_DEFAULT_REGION: ap-northeast-1
AWS_REGION: ap-northeast-1
docker:
# we use the debug tag since it comes with sh
- image: gcr.io/kaniko-project/executor:debug
entrypoint: ""
steps:
- checkout
- run:
name: Build and Push image
command: |
# We pass in AWS credentials and configuration through the AWS_* env vars, via build-arg arguments.
# See https://github.com/GoogleContainerTools/kaniko/issues/713#issuecomment-557596725
# NOTE: please replace --destination to your AWS ECR image's URL accordingly
/kaniko/executor \
--context "$(pwd)" \
--dockerfile "$(pwd)/Dockerfile" \
--build-arg AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \
--build-arg AWS_REGION=$AWS_REGION \
--build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
--build-arg AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
--destination "public.ecr.aws/z1j6a2i1/kelvintaywl/fancy-nginx:${CIRCLE_SHA1}"
Docker Hub
- Set up Docker Hub credentials
- Create a config.json file with Docker Hub credentials which we will mount to the Kaniko container
- In this example, I have dynamically created a config.json by running a shell script injecting the env vars
- Define a CircleCI Docker executor job as shown below
jobs:
kaniko-build-push-docker-hub:
environment:
# NOTE: Replace these values as required
DOCKER_REGISTRY: docker.io
docker:
# we use the debug tag since it comes with sh
- image: gcr.io/kaniko-project/executor:debug
entrypoint: ""
steps:
- checkout
- run:
name: add Docker Hub credentials
command: |
# NOTE: Docker Hub credentials (DOCKER_LOGIN and DOCKER_PASSWORD env vars)
# are injected via project env vars
mkdir -p /kaniko/.docker
./config.sh
mv config.json /kaniko/.docker
- run:
name: Build and Push image
command: |
/kaniko/executor \
--context "$(pwd)" \
--dockerfile "$(pwd)/Dockerfile" \
--destination "${DOCKER_REGISTRY}/kelvintaywl/fancy-nginx:${CIRCLE_SHA1}"
Important
Note that the Kaniko executor image is only concerned with building and pushing images.
If your job is trying to do more than that, consider splitting the concerns to separate jobs (in the same workflow).
Follow-up
For a working example, do feel free to refer to a public project I have here:
- GitHub repo: GitHub - kelvintaywl-cci/whale-this-work: Exploring Docker building (and pushing) images with CircleCI
- CircleCI pipelines: https://app.circleci.com/pipelines/github/kelvintaywl-cci/whale-this-work (See the
kaniko
workflow)
In addition, GitLab also has a great document on using Kaniko on GitLab CI:
I hope this is useful and helpful for anyone trying to use Kaniko on CircleCI