5

I'm working on a Spring Boot application that should be packaged into a OCI container using Cloud Native Build Packs / Paketo.io. I build it with GitHub Actions, where my workflow build.yml looks like this:

name: build

on: [push]

jobs:
  build-with-paketo-push-2-dockerhub:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Login to DockerHub Container Registry
        run: echo $DOCKER_HUB_TOKEN | docker login -u jonashackt --password-stdin
        env:
          DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Install pack CLI via apt. See https://buildpacks.io/docs/tools/pack/#pack-cli
        run: |
          sudo add-apt-repository ppa:cncf-buildpacks/pack-cli
          sudo apt-get update
          sudo apt-get install pack-cli

      - name: Build app with pack CLI
        run: pack build spring-boot-buildpack --path . --builder paketobuildpacks/builder:base

      - name: Tag & publish to Docker Hub
        run: |
          docker tag spring-boot-buildpack jonashackt/spring-boot-buildpack:latest
          docker push jonashackt/spring-boot-buildpack:latest

Now the step Build app with pack CLI takes relatively long, since it always downloads the Paketo builder Docker image and then does a full fresh build. This means downloading the JDK and every single Maven dependency. Is there a way to cache a Paketo build on GitHub Actions?

4

1 回答 1

4

Caching the Docker images on GitHub Actions might be an option - which doesn't seem to be that easy. Another option would be to leverage the Docker official docker/build-push-action Action, which is able to cache the buildx-cache. But I didn't get the combination of pack CLI and buildx-caching to work (see this build for example).

Finally I stumbled upon the general Cloud Native Buildpacks approach on how to cache in the docs:

Cache Images are a way to preserve build optimizing layers across different host machines. These images can improve performance when using pack in ephemeral environments such as CI/CD pipelines.

I found this concept quite nice, since it uses a second cache image, which gets published on a container registry of your choice. And this image is simply used for all Paketo pack CLI builds on every machine you append the --cache-image parameter - be it your local desktop or any CI/CD platform (like GitHub Actions).

In order to use the --cache-image parameter, we also have to use the --publish flag (since the cache image needs to get published to your container registry!). This also means we need to log into the container registry before we're able to run our pack CLI command. Using Docker Hub this is something like:

echo $DOCKER_HUB_TOKEN | docker login -u YourUserNameHere --password-stdin

Also the Paketo builder image must be a trusted one. As the docs state:

By default, any builder suggested by pack builder suggest is considered trusted.

Since I use a suggested builder, I don't have to do anything here. If you want to use another builder that isn't trusted by default, you need to run a pack config trusted-builders add your/builder-to-trust:bionic command before the final pack CLI command.

Here's the pack CLI command, which is cache enabled in case you want to build a Spring Boot app and using Docker Hub as the container registry:

      pack build index.docker.io/yourApplicationImageNameHere:latest \
          --builder paketobuildpacks/builder:base \
          --path . \
          --cache-image index.docker.io/yourCacheImageNameHere:latest \
          --publish

Finally the GitHub Action workflow to build and publish the example Spring Boot app https://github.com/jonashackt/spring-boot-buildpack looks like this:

name: build

on: [push]

jobs:
  build-with-paketo-push-2-dockerhub:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Login to DockerHub Container Registry
        run: echo $DOCKER_HUB_TOKEN | docker login -u jonashackt --password-stdin
        env:
          DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Install pack CLI via the official buildpack Action https://github.com/buildpacks/github-actions#setup-pack-cli-action
        uses: buildpacks/github-actions/setup-pack@v4.1.0

      - name: Build app with pack CLI using Buildpack Cache image (see https://buildpacks.io/docs/app-developer-guide/using-cache-image/) & publish to Docker Hub
        run: |
          pack build index.docker.io/jonashackt/spring-boot-buildpack:latest \
              --builder paketobuildpacks/builder:base \
              --path . \
              --cache-image index.docker.io/jonashackt/spring-boot-buildpack-paketo-cache-image:latest \
              --publish

Note that with using the pack CLI's --publish flag, we also don't need an extra step Tag & publish to Docker Hub anymore. Since this is done by pack CLI for us already.

于 2021-03-12T11:02:36.870 回答