Custom Kaniko image (from Google’s debug variant) for Forgejo Actions: build & push container images in CI/CD by just setting env vars—no Docker daemon needed. https://git.van-hemmen.com/actions/kaniko
  • Shell 70.7%
  • Dockerfile 29.3%
Find a file
Claude 85c944bf27
All checks were successful
/ docker-tag (push) Successful in 19s
#7 - Add REGISTRY_INSECURE to push to an in-cluster registry over plain HTTP (#8)
## What

Adds a **`REGISTRY_INSECURE`** setting to `build.sh` (default `false`). When set to `true`, the wrapper passes Kaniko's `--insecure-registry=${REGISTRY_HOST}`, so a pipeline can push to Forgejo's in-cluster Service over plain HTTP instead of through the public ingress.

## Why

See #7. The runners and Forgejo run on the same node, but pushes to `git.van-hemmen.com` go out through Traefik and back. Traefik's ~60 s per-request timeout cuts large layer uploads, and `actions/sindri`'s `coder-xfce-vnc` builds fail at the push with `PATCH …/blobs/uploads/…: 502 Bad Gateway`. Forgejo logs `unexpected EOF` on uploads lasting 60.0–60.7 s.

## Changes

- **`build.sh`**
  - New `REGISTRY_INSECURE` setting: `true`/`TRUE`/`True`/`1`/`yes` enables it; `false`/`0`/`no`/empty leaves it off. It's checked right after the defaults are set, so an invalid value stops the job before any build work.
  - When enabled, `--insecure-registry=${REGISTRY_HOST}` is added to the Kaniko call. That flag covers only the named registry, so pulls from Docker Hub and other registries keep using TLS.
  - `REGISTRY_INSECURE` is shown in the settings summary printed before the build.
  - With the setting unset or `false`, the Kaniko command is byte-for-byte the same as today.
- **`README.md`**: new row in the settings table, plus a "Pushing to an in-cluster registry" section with example settings. It notes that `REGISTRY_HOST` must match the destination host (port included), that pulls stay `git.van-hemmen.com/…`, and that Forgejo's login request still goes to its public URL.

## Verification

- The Kaniko executor inside `actions/kaniko:26.7.0` supports `--insecure-registry` ("Insecure registry using plain HTTP to push and pull"), checked with `/kaniko/executor --help` in a pod.
- I ran the modified `build.sh` in that image's `/busybox/sh`, with the `exec /kaniko/executor` line replaced by `echo`:

| Case | Result |
|---|---|
| Unset | `… --dockerfile=./Dockerfile --no-push` (unchanged) |
| `REGISTRY_INSECURE=false` | unchanged |
| `true` + `REGISTRY_HOST=app-http-service.forgejo.svc.cluster.local:3000` + destination | `… --target=ci --insecure-registry=app-http-service.forgejo.svc.cluster.local:3000 --destination=app-http-service.forgejo.svc.cluster.local:3000/actions/sindri:ci-abc`; `config.json` keyed on that host:port |
| `REGISTRY_INSECURE=ture` | `Error: REGISTRY_INSECURE must be true or false (got 'ture').`, exit 1 |

- `sh -n` passes. `shellcheck -s sh` reports nothing new: a warning on the existing `eval` on line 10, and SC2086 infos on the intentionally unquoted `$…_FLAG` arguments, which follow the existing `$TARGET_FLAG`/`$DEST_FLAGS` pattern.

**Not yet verified:** an actual push through the internal Service. Pushing this branch makes `docker-dev` publish `git.van-hemmen.com/actions/kaniko:<sha>`. A companion `actions/sindri` branch uses that image with `REGISTRY_INSECURE=true` as the end-to-end test, and I'll report the result on this PR.

## After merge

Tag a release so `actions/sindri`'s workflows can pin the new version.

Closes #7

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01XPajGyTH2js52mY5WSJoNA
Reviewed-on: #8
Reviewed-by: Guillaume "B.B." Van Hemmen <guillaumehemmen@noreply.git.van-hemmen.com>
2026-09-10 11:51:17 +00:00
.forgejo/workflows #0000 - Add custom Kaniko builder and CI workflows (#1) 2025-05-19 09:48:07 +00:00
build.sh #7 - Add REGISTRY_INSECURE to push to an in-cluster registry over plain HTTP (#8) 2026-09-10 11:51:17 +00:00
CODE_OF_CONDUCT.md #0000 - Add custom Kaniko builder and CI workflows (#1) 2025-05-19 09:48:07 +00:00
CONTRIBUTING.md #0000 - Add custom Kaniko builder and CI workflows (#1) 2025-05-19 09:48:07 +00:00
Dockerfile #4 - CI pipeline & Dockerfile hardening: env var rename, extended logging, POSIX shell, privilege drop (#5) 2025-05-19 11:31:45 +00:00
LICENSE #0000 - Add custom Kaniko builder and CI workflows (#1) 2025-05-19 09:48:07 +00:00
README.md #7 - Add REGISTRY_INSECURE to push to an in-cluster registry over plain HTTP (#8) 2026-09-10 11:51:17 +00:00

kaniko (action)

Custom Kaniko image (forked from Googles gcr.io/kaniko-project/executor:debug) for Forgejo Actions.
Build & push OCI-compatible container images in your pipelines without a Docker daemon. Just set a few environment variables.


Highlights

Feature Benefit
Daemon-less builds Works in completely rootless, container-only environments
Debug base Includes /shell & common tools for troubleshooting
Registry-agnostic Push to Docker Hub, GHCR, Harbor, Quay, Google Artifact Registry, etc.
Small wrapper script Autodetects credentials and common env-var combos

Image tags

Tag Base Intended use
latest Google debug executor General CI pipelines

Quick start

# .forgejo/workflows/build.yaml
name: Build & push image

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: docker
    container:
      image: git.van-hemmen.com/actions/kaniko:latest
    steps:
      - name: Build & push with Kaniko
        run: /bin/build.sh
        env:
          # --- mandatory --------------------------------------------------------
          KANIKO_CONTEXT: git://git.van-hemmen.com/actions/kaniko.git
          GIT_REF_NAME: ${{ github.ref_name }}
          GIT_USERNAME: ${{ secrets.docker_username }}
          GIT_PASSWORD: ${{ secrets.access_token }}

          # --- optional (only needed when you plan to push) ---------------------
          REGISTRY_HOST: ghcr.io
          REGISTRY_USER: ${{ secrets.docker_username }}
          REGISTRY_PASS: ${{ secrets.access_token }}
          KANIKO_DESTINATION: git.van-hemmen.com/myorg/myapp:${GITHUB_SHA}

          # --- fine-tuning ------------------------------------------------------
          KANIKO_DOCKERFILE: ./Dockerfile
          KANIKO_VERBOSITY: info
          KANIKO_TARGET: production

Environment variables

Variable Required Purpose Example value
KANIKO_CONTEXT Yes Build context (git://). git://git.van-hemmen.com/actions/kaniko.git
GIT_REF_NAME Yes Branch or tag that is being built. ${{ github.ref_name }}
GIT_USERNAME Yes Username with access to KANIKO_CONTEXT when it is private. ${{ secrets.GIT_USERNAME }}
GIT_PASSWORD Yes Token/password paired with GIT_USERNAME. ${{ secrets.GIT_PASSWORD }}
REGISTRY_HOST No (default git.van-hemmen.com) Target registry hostname. ghcr.io
REGISTRY_USER No* Registry username. Enables push only if both REGISTRY_USER and REGISTRY_PASS are set. ${{ secrets.REGISTRY_USER }}
REGISTRY_PASS No* Registry password/token. ${{ secrets.REGISTRY_PASS }}
REGISTRY_INSECURE No (default false) true uses plain HTTP for REGISTRY_HOST only (Kaniko --insecure-registry). See below. true
KANIKO_DESTINATION No Comma-separated list of image references to push (variables like ${{ github.sha }} are expanded). ghcr.io/myorg/app:${{ github.sha }},ghcr.io/myorg/app:latest
KANIKO_DOCKERFILE No (default ./Dockerfile) Path to the Dockerfile relative to the context. ./docker/Dockerfile.alpine
KANIKO_VERBOSITY No (default info) Log level (trace, debug, info, warn, error, fatal, panic). debug
KANIKO_TARGET No Target build stage for multi-stage Dockerfiles. If not set, all stages are built. production

* REGISTRY_USER / REGISTRY_PASS are only needed when the registry requires authentication.

Pushing to an in-cluster registry

When the runner and Forgejo run in the same Kubernetes cluster, pushing to the public hostname sends every layer out through the ingress and back in. That is slower, and the ingress's request timeout can cut large layer uploads. Push to Forgejo's Service over plain HTTP instead:

env:
  REGISTRY_HOST: app-http-service.forgejo.svc.cluster.local:3000
  REGISTRY_INSECURE: 'true'
  REGISTRY_USER: ${{ secrets.docker_username }}
  REGISTRY_PASS: ${{ secrets.access_token }}
  KANIKO_DESTINATION: app-http-service.forgejo.svc.cluster.local:3000/myorg/myapp:${GITHUB_SHA}
  • REGISTRY_HOST must match the host in KANIKO_DESTINATION exactly, port included. Credentials are stored under that key, and only that host switches to HTTP; base-image pulls from other registries keep using TLS.
  • Forgejo stores images by owner and name, not by hostname, so the image is still pulled as git.van-hemmen.com/myorg/myapp:<tag>.
  • Forgejo's token endpoint stays on its public ROOT_URL (https://git.van-hemmen.com/v2/token). That is one small HTTPS request per push; the layer data goes to the Service.
  • Only use this where the path to the Service is already private. On this cluster the Service is internal, and node-to-node traffic goes through WireGuard.