Services Team Case Studies Blog
Let's Talk
  • Services
  • Contact
  • Team
  • Case Studies
  • Blog
Hire us

All posts

Tutorials

Building Images with Kanniko and Deploying to Heroku

author avatar Aaron F. - 2023-04-20

Kaniko is a wonderful tool to build container images from a Dockerfile without needing access to the Docker Daemon since it is not accessible in the Kubernetes Cluster. This is great and quite straightforward if that container is also going to be deployed into a Kubernetes Cluster since CI/CD can easily integrate with a Kubernetes cluster.

However, things become quite tricky if that image needs to be deployed on Heroku since many of the Heroku CLI commands are actually running tasks that interact with the Docker Daemon under the hood.

In this post, I will discuss how to use Kaniko to build an image in a CI/CD pipeline and then deploy that image on Heroku.

Prerequisites

  • Familiarity with CI/CD pipelines (this blog will focus on Gitlab, but should translate well to other platforms)
  • Familiarity with heroku-cli
  • Basic understanding of Kaniko

Build the Container Image

Start by verifying that the HEROKU_API_KEY environment variable is set in the CI/CD environment variables. If it is not there, generate an API key with the Heroku CLI and add that value to the HEROKU_API_KEY CI/CD variable.

Next, create a phase in the CI pipeline that contains the logic to build the container from a Dockerfile using Kaniko:

build:      stage: build 
    image:
        name: gcr.io/kaniko-project/executor:v1.9.0-debug
        entrypoint: [""]
        varables:
            - HEROKU_API_KEY=$HEROKU_API_KEY
            - HEROKU_IMAGE_TAG: registry.heroku.com/<app-name>/<process-type>
        script:
            - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"},\"registry.heroku.com\":{\"username\":\"_\",\"password\":\"$HEROKU_API_KEY\"}}}" > /kaniko/.docker/config.json`
            - /kaniko/executor
              --context "${CI_PROJECT_DIR}"
              --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
              --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
              --destination "${HEROKU_IMAGE_TAG}"
        rules: - if: $CI_COMMIT_TAG

In the script above, the echo command is going to write the credentials to the config.json for Docker so Kaniko can authenticate to both the Gitlab container registry and the Heroku container registry.

A variable named HEROKU_IMAGE_TAG has also been defined and that is being used as the destination for the Heroku container registry. This will ensure that the build version of the container is pushed to the correct application. Heroku does not work with tagging, so applying a tag will cause Heroku to not deploy the newly built container.

Release the Container Image

Once the container has been built and pushed to the Heroku container registry, the only thing left is to release that container via the Heroku CLI. Add another stage to the CI/CD pipeline:

release:    stage: release
  image: "buddy/heroku-cli"
  cache: {}
  variables:
    HEROKU_API_KEY: $HEROKU_API_KEY
  script:
    - heroku container:release -a <app-name>
  needs:
    - build

This stage will use the heroku-cli container image, and it will issue only the heroku container:release command to release the container. This will tell Heroku to deploy the container that was pushed to its registry in the previous step, and the changes should be deployed.

Why Not Use Heroku Container:Push?

In the Heroku Container Registry Docs they discuss the heroku container:push command as being a way to build and push a container to the Heroku registry. However, since this command is actually relying on the Docker Daemon (presumeably it’s just an alias for docker build and docker push with some tagging involved) to be available on the machine running the command, this command will fail when the CI/CD pipeline is being run on Kubernetes since the Docker Daemon is not available.

I hope this was helpful! Feel free to check out my Github or my LinkedIn.

NEWSLETTER

Go Deeper than Development

The Daring Bits newsletter cuts through the noise to bring you hardwon wisdom about fintech, insurance, and of course software development.

Have a project in mind?

Get started with a free consultation

Check Availability

Company

  • Jobs
  • Blog
  • Team
  • Services
  • Technology

Work

  • Truth Social
  • JailCore
  • TrustCare
  • BCharitable
  • Agency Rocket

120 19th Street North

Suite 2005

Birmingham, AL 35203 usa flag

(877) 919-4322

All rights reserved.