Request icon
OutputValues icon
Get icon
If icon
WorkingDirectory icon
Clone icon
Build icon
SlackIncomingWebhook icon
Set icon
Schedule icon

Rebuild and Push Your Docker Image When Its Base Image Is Republished

Detect when a Docker Hub base image tag such as node:22-alpine is republished, then rebuild your image from Git, push it and notify Slack.

Categories
CloudInfrastructure

Tags like node:22-alpine or python:3.12-slim are rebuilt by their maintainers every time the underlying OS packages get security fixes, but your own image only picks those fixes up when it is rebuilt. Images of quiet services can sit on a months-old base. This blueprint watches the digest behind your base tag on Docker Hub and, when the tag is republished, rebuilds your image from Git with a fresh pull of the base, pushes it and posts to Slack.

How it works

  1. registry_token gets an anonymous pull token from Docker Hub (no account needed).
  2. base_manifest sends a HEAD request for the tag's manifest and reads the Docker-Content-Digest header (current keeps it, plus a 12-character short form). HEAD requests do not count against Docker Hub's pull rate limit.
  3. load_digest reads the base digest of the last build from the Kestra KV store.
  4. if_base_changed continues only when a digest was stored and the tag now points to a different one. The first run only records the current digest.
  5. rebuild (WorkingDirectory) clones the repository with clone and runs build_and_push, which builds with pull: true so the new base is used, adds the OCI org.opencontainers.image.base.digest label and pushes latest plus a base-<digest> tag.
  6. notify_rebuilt posts the old and new digests and the pushed tags to Slack.
  7. remember_digest stores the new digest, after the push.

If the build or push fails, the digest is not stored, the errors branch posts to Slack and the next run tries again.

Prerequisites

  • Docker available to the Kestra worker (the Docker socket mounted, as in the standard Kestra docker compose file), because io.kestra.plugin.docker.cli.Build talks to the Docker daemon.
  • A container registry you can push to (GHCR, Docker Hub, ECR, a self-hosted registry).
  • A Slack Incoming Webhook.

Secrets

  • REGISTRY_HOST: registry to push to, for example ghcr.io or https://index.docker.io/v1/.
  • REGISTRY_USERNAME and REGISTRY_PASSWORD: push credentials. For GHCR, a GitHub token with the write:packages scope.
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for rebuild notices and failures.

In the open-source edition, secrets are environment variables on the Kestra container, prefixed with SECRET_ and base64-encoded. See how to manage secrets.

Inputs

  • base_repository (STRING, default library/node) and base_tag (STRING, default 22-alpine): the base image exactly as it appears in your FROM line. Official images use library/.
  • git_url, git_branch (STRING): where the Dockerfile lives. Public by default; add username/password to clone for a private repository.
  • dockerfile_path (STRING, default Dockerfile): relative to the repository root, which is the build context.
  • image (STRING): the image to push, without a tag.

The defaults build Docker's public welcome-to-docker sample, which uses node:22-alpine.

Quick start

  1. Add the secrets and set image to a repository you can push to.
  2. Execute the flow: the current base digest is recorded and nothing is built.
  3. Execute it again: still nothing to do until the maintainers republish the tag.
  4. Enable every_six_hours. To force a rebuild, set the KV entry base_image_digest_<image> to any other value and execute the flow.

One flow checks one image. To watch several, add one Schedule trigger per image with its own inputs, or call this flow from a Loop with a Subflow task.

Outputs

  • {{ outputs.current.values.digest }}: the current base digest.
  • {{ outputs.build_and_push.imageId }}: id of the rebuilt image.
  • KV entry base_image_digest_<image>: the base digest of the last successful build.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.