kforge

An end-to-end Docker build, verify, CI, and deploy-bootstrap CLI powered by BuildKit. Works as a standalone binary or as a Docker CLI plugin (docker kforge build).

v1.1.1

Version

Go 1.24

Runtime

MIT

License

Prerequisites

  • Docker Engine ≥ 24 or Docker Desktop
  • Docker Buildx plugin
  • QEMU (optional)
  • Go 1.21+

Installation

macOS (Apple Silicon)

$ curl -Lo kforge.tar.gz https://github.com/MuyleangIng/kforge/releases/download/v1.1.1/kforge_1.1.1_darwin_arm64.tar.gz$ tar -xzf kforge.tar.gz && sudo mv kforge /usr/local/bin/# Remove Gatekeeper quarantine (run once after install)$ sudo xattr -d com.apple.quarantine /usr/local/bin/kforge$ kforge version

macOS (Intel)

$ curl -Lo kforge.tar.gz https://github.com/MuyleangIng/kforge/releases/download/v1.1.1/kforge_1.1.1_darwin_amd64.tar.gz$ tar -xzf kforge.tar.gz && sudo mv kforge /usr/local/bin/$ sudo xattr -d com.apple.quarantine /usr/local/bin/kforge

Linux (Debian/Ubuntu)

$ curl -Lo kforge.deb https://github.com/MuyleangIng/kforge/releases/download/v1.1.1/kforge_1.1.1_linux_amd64.deb$ sudo dpkg -i kforge.deb && kforge version

Docker CLI Plugin

$ mkdir -p ~/.docker/cli-plugins$ git clone https://github.com/MuyleangIng/kforge$ cd kforge && go build -o ~/.docker/cli-plugins/docker-kforge ./cmd/$ chmod +x ~/.docker/cli-plugins/docker-kforge# Use as: docker kforge build ...

Quick Start

From zero to a verified, CI-ready Dockerized project in six commands.

$ kforge doctor               # 1. check environment$ kforge detect               # 2. detect your framework$ kforge init --detect        # 3. generate Dockerfile + .dockerignore + kforge.hcl$ kforge verify               # 4. build & health-check locally$ kforge ci init --target github   # 5. generate GitHub Actions pipeline$ kforge deploy init --target compose  # 6. generate docker-compose.yml

Commands

kforge doctor

Checks Docker daemon, Buildx, QEMU, and active builder health.

$ kforge doctor

kforge detect

Auto-detects framework by scanning source files. Resolves runtime version.

FlagDescription
--jsonStructured JSON output for CI scripts
$ kforge detect$ kforge detect --json

kforge init

Generates Dockerfile, .dockerignore, and kforge.hcl.

FlagDescription
--detectAuto-detect framework first
--framework <name>Specify framework (flask, nextjs, …)
--autoNon-interactive, use detected defaults
$ kforge init --detect$ kforge init --framework flask --auto

kforge verify

Builds image, runs container, waits for health endpoint, reports pass/fail.

$ kforge verify$ kforge verify .

kforge build

Multi-platform BuildKit build. Accepts all docker buildx build flags.

FlagDescription
--platform <list>Comma-separated platforms
--pushPush after build
-t, --tag <ref>Image tag
--cache-from <spec>Cache source (registry/local/s3/azure/gha)
--cache-to <spec>Cache export target
--build-arg <k=v>Pass build argument
--secret <spec>Mount secret without baking into layer
--target <stage>Build specific Dockerfile stage
$ kforge build -t myapp:latest .$ kforge build --platform linux/amd64,linux/arm64 --push -t myapp:latest .$ docker kforge build -t myapp:latest .

kforge bake

Declarative multi-target build from kforge.hcl or kforge.json.

FlagDescription
--file <path>Bake config file
--pushPush all targets
--set <k=v>Override a variable
$ kforge bake$ kforge bake --file kforge.hcl --push$ kforge bake --set TAG=1.2.3

kforge ci init

Generates a CI pipeline that installs kforge, verifies, and pushes.

FlagDescription
--target githubOutput .github/workflows/ci.yml
--target gitlabOutput .gitlab-ci.yml
$ kforge ci init --target github$ kforge ci init --target gitlab

kforge deploy init

Generates deployment bootstrap configs.

FlagDescription
--target composedocker-compose.yml with health check
--target renderrender.yaml for Render.com
--target flyfly.toml for Fly.io
$ kforge deploy init --target compose$ kforge deploy init --target render$ kforge deploy init --target fly

kforge builder

Manage BuildKit builder instances. Config in ~/.kforge/.

$ kforge builder create --name mybuilder$ kforge builder ls$ kforge builder use mybuilder$ kforge builder rm mybuilder

kforge setup

Interactive wizard for QEMU or multi-node builder configuration.

$ kforge setup

Usage Examples

New Project Onboarding

From zero to a verified, CI-ready Dockerized project.

# 1. Check environment$ kforge doctor# 2. Detect your framework$ kforge detect# 3. Generate Dockerfile, .dockerignore, kforge.hcl$ kforge init --detect# 4. Verify container locally$ kforge verify

Generate CI/CD & Deploy

Output GitHub Actions, GitLab CI, and deploy configs.

# GitHub Actions workflow$ kforge ci init --target github# GitLab CI pipeline$ kforge ci init --target gitlab# Deploy configs$ kforge deploy init --target compose$ kforge deploy init --target render$ kforge deploy init --target fly

Quick Push

Build and push a multi-platform image in one command.

$ kforge push muyleangin/myapp .$ kforge push ghcr.io/muyleangin/myapp .$ docker kforge push muyleangin/myapp .

Build & Load

Build an image and load it into local Docker.

$ kforge build -t muyleangin/myapp:latest .# Docker plugin mode (same as docker buildx!)$ docker kforge build -t muyleangin/myapp:latest .

Multi-Platform Push

Build for multiple architectures and push to registry.

$ kforge build \  --platform linux/amd64,linux/arm64 \  --push \  -t muyleangin/myapp:latest .

Registry Cache

Use registry cache for faster subsequent builds.

$ kforge build \  --cache-from type=registry,ref=muyleangin/myapp:cache \  --cache-to   type=registry,ref=muyleangin/myapp:cache,mode=max \  --push -t muyleangin/myapp:latest .

Build Args & Secrets

Pass build arguments, target stages, and secrets.

# Build args + target stage$ kforge build --build-arg VERSION=1.2.3 --target release -t myapp:1.2.3 .# Secrets (never baked into the image)$ kforge build --secret id=mysecret,src=./token.txt -t myapp .

Bake (Declarative)

Use HCL or JSON config files for repeatable builds.

variable "TAG" { default = "latest" }target "app" {  context    = "."  dockerfile = "Dockerfile"  platforms  = ["linux/amd64", "linux/arm64"]  tags       = ["muyleangin/app:${TAG}"]  push       = true}group "default" {  targets = ["app"]}

Configuration

kforge.hcl

Primary declarative build config (HCL syntax). Generated by kforge init.

variable "TAG"      { default = "latest"        }variable "REGISTRY" { default = "docker.io/myorg" }target "app" {  context    = "."  dockerfile = "Dockerfile"  platforms  = ["linux/amd64", "linux/arm64"]  tags       = ["${REGISTRY}/app:${TAG}"]  cache-from = ["type=registry,ref=${REGISTRY}/app:cache"]  cache-to   = ["type=registry,ref=${REGISTRY}/app:cache,mode=max"]  push       = true}group "default" {  targets = ["app"]}

.kforge.yml

Per-project overrides. Takes precedence over auto-detection results.

framework:    nextjsport:         3000node_version: "20"health_path:  /api/health

Frameworks

Node.js

FrameworkDetectionPort
Next.jspackage.json (next)3000
Reactpackage.json (react)3000
Vuepackage.json (vue)5173
NestJSpackage.json (@nestjs/core)3000
Node.jspackage.json (generic)3000

Version resolved from: .nvmrc.node-versionpackage.json engines.node

Python

FrameworkDetectionPort
FastAPImain.py / app.py (fastapi dep)8000
Flaskapp.py / main.py (flask dep)5000
Djangomanage.py8000

Version resolved from: pyproject.toml.python-versionruntime.txt

Java / Spring Boot

FrameworkDetectionPort
Spring Boot (Maven)pom.xml8080
Spring Boot (Gradle)build.gradle8080

CI/CD Integration

Both pipelines follow the same two-stage pattern: check runs on every PR and push (detect + verify), and publish builds and pushes to the registry only on main / tags.

GitHub Actions

Generated by kforge ci init --target github. Uses GHCR by default — no extra secrets needed, the built-in GITHUB_TOKEN handles login.

checkPR + push
publishpush only
.github/workflows/kforge-ci.yml
name: kforge-cion:  pull_request:  push:    branches:      - "main"    tags:      - "v*"  workflow_dispatch:concurrency:  group: kforge-${{ github.workflow }}-${{ github.ref }}  cancel-in-progress: trueenv:  KFORGE_CONTEXT: "."  KFORGE_DEPLOY_PATH: "/srv/flask-ci-demo"  KFORGE_IMAGE_NAME: "flask-ci-demo"  KFORGE_MAIN_BRANCH: "main"  KFORGE_PLATFORMS: "linux/amd64"  KFORGE_REGISTRY: "ghcr.io"  KFORGE_VERIFY_PATH: "/health"  KFORGE_VERSION: "v1.1.1"jobs:  # ── Check: detect + verify on every PR and push ────────────────────  check:    runs-on: ubuntu-latest    permissions:      contents: read      packages: write    steps:      - uses: actions/checkout@v4      - uses: docker/setup-qemu-action@v3      - uses: docker/setup-buildx-action@v3      - name: Install kforge        shell: bash        run: |          mkdir -p "$HOME/.local/bin"          curl -fsSL -o /tmp/kforge.tar.gz \            "https://github.com/MuyleangIng/kforge/releases/download/${KFORGE_VERSION}/kforge_${KFORGE_VERSION#v}_linux_amd64.tar.gz"          tar -xzf /tmp/kforge.tar.gz -C /tmp          cp /tmp/kforge "$HOME/.local/bin/kforge"          chmod +x "$HOME/.local/bin/kforge"          echo "$HOME/.local/bin" >> "$GITHUB_PATH"          kforge version      - name: Resolve image name        shell: bash        run: |          OWNER_LOWER="$(printf '%s' "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')"          IMAGE="ghcr.io/${OWNER_LOWER}/${KFORGE_IMAGE_NAME}"          echo "KFORGE_IMAGE=$IMAGE" >> "$GITHUB_ENV"          echo "Resolved image: $IMAGE"      - name: Inspect project        run: kforge detect "$KFORGE_CONTEXT"      - name: Verify app        run: kforge verify --progress plain "$KFORGE_CONTEXT"  # ── Publish: build + push on push to main or tag ───────────────────  publish:    if: github.event_name == 'push'    needs: check    runs-on: ubuntu-latest    permissions:      contents: read      packages: write    steps:      - uses: actions/checkout@v4      - uses: docker/setup-qemu-action@v3      - uses: docker/setup-buildx-action@v3      - name: Install kforge        shell: bash        run: |          mkdir -p "$HOME/.local/bin"          curl -fsSL -o /tmp/kforge.tar.gz \            "https://github.com/MuyleangIng/kforge/releases/download/${KFORGE_VERSION}/kforge_${KFORGE_VERSION#v}_linux_amd64.tar.gz"          tar -xzf /tmp/kforge.tar.gz -C /tmp          cp /tmp/kforge "$HOME/.local/bin/kforge"          chmod +x "$HOME/.local/bin/kforge"          echo "$HOME/.local/bin" >> "$GITHUB_PATH"          kforge version      - name: Resolve image name        shell: bash        run: |          OWNER_LOWER="$(printf '%s' "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')"          IMAGE="ghcr.io/${OWNER_LOWER}/${KFORGE_IMAGE_NAME}"          echo "KFORGE_IMAGE=$IMAGE" >> "$GITHUB_ENV"      - name: Log in to GHCR        uses: docker/login-action@v3        with:          registry: ghcr.io          username: ${{ github.actor }}          password: ${{ secrets.GITHUB_TOKEN }}      - name: Push image        shell: bash        run: |          TAGS=(-t "${KFORGE_IMAGE}:${GITHUB_SHA:0:7}")          if [ "${GITHUB_REF}" = "refs/heads/${KFORGE_MAIN_BRANCH}" ]; then            TAGS+=(-t "${KFORGE_IMAGE}:latest")          fi          if [[ "${GITHUB_REF}" == refs/tags/* ]]; then            TAGS+=(-t "${KFORGE_IMAGE}:${GITHUB_REF#refs/tags/}")          fi          kforge build --progress plain --platform "$KFORGE_PLATFORMS" --push "${TAGS[@]}" "$KFORGE_CONTEXT"

Live run result — MuyleangIng/kforge-ci-cd · Mar 13 2026

  • Runner: ubuntu-24.04 · Docker 28.0.4 · Buildx v0.31.1
  • kforge detect → Flask · Python 3.12 · pip
  • kforge verify → image built in 12.3 s, health check passed
  • Image pushed → ghcr.io/muyleanging/flask-ci-demo:latest

GitLab CI

Generated by kforge ci init --target gitlab. Uses a shared YAML anchor &install_kforge to avoid duplicating the install step across jobs.

checkall branches
publishmain + tags
.gitlab-ci.yml
variables:  KFORGE_VERSION:    "v1.1.1"  KFORGE_IMAGE_NAME: "flask-ci-demo"  KFORGE_REGISTRY:   "$CI_REGISTRY"  KFORGE_PLATFORMS:  "linux/amd64"  KFORGE_VERIFY_PATH: "/health"stages:  - check  - publish# ── Shared install snippet ───────────────────────────────────────────.install_kforge: &install_kforge  before_script:    - mkdir -p "$HOME/.local/bin"    - |      curl -fsSL -o /tmp/kforge.tar.gz \        "https://github.com/MuyleangIng/kforge/releases/download/${KFORGE_VERSION}/kforge_${KFORGE_VERSION#v}_linux_amd64.tar.gz"    - tar -xzf /tmp/kforge.tar.gz -C /tmp    - cp /tmp/kforge "$HOME/.local/bin/kforge"    - chmod +x "$HOME/.local/bin/kforge"    - export PATH="$HOME/.local/bin:$PATH"    - kforge version# ── detect + verify (every branch / MR) ─────────────────────────────check:  stage: check  image: docker:28  services: [docker:dind]  <<: *install_kforge  script:    - kforge detect .    - kforge verify --progress plain .# ── build + push (main branch and tags only) ─────────────────────────publish:  stage: publish  image: docker:28  services: [docker:dind]  only:    - main    - tags  <<: *install_kforge  script:    - docker buildx create --use    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"    - |      IMAGE="$CI_REGISTRY_IMAGE/$KFORGE_IMAGE_NAME"      TAGS=(-t "$IMAGE:$CI_COMMIT_SHORT_SHA")      if [ "$CI_COMMIT_BRANCH" = "main" ]; then TAGS+=(-t "$IMAGE:latest"); fi      if [ -n "$CI_COMMIT_TAG" ];          then TAGS+=(-t "$IMAGE:$CI_COMMIT_TAG"); fi      kforge build --progress plain --platform "$KFORGE_PLATFORMS" --push "${TAGS[@]}" .

Caching

Registry Cache

$ kforge build \  --cache-from type=registry,ref=myapp:cache \  --cache-to   type=registry,ref=myapp:cache,mode=max \  --push -t myapp:latest .

S3 / Azure / Local / GitHub Actions

FlagDescription
type=local,src=.cacheFilesystem cache
type=s3,bucket=my-bucket,region=us-east-1Amazon S3
type=azblob,account_name=...,name=...Azure Blob Storage
type=ghaGitHub Actions cache (CI)
$ kforge build --cache-from type=local,src=.cache --cache-to type=local,dest=.cache,mode=max .$ kforge build \  --cache-from type=s3,region=us-east-1,bucket=my-cache \  --cache-to   type=s3,region=us-east-1,bucket=my-cache,mode=max \  --push -t myapp:latest .

Project Structure

File Tree

~/kforge — Go 1.24.0 · MIT
kforge/  ├── .github/workflows/  │   ├── ci.yml  # test + build on PR / push  │   └── release.yml  # GoReleaser + macOS DMG on v*  ├── cmd/main.go  # entry point (standalone + Docker plugin)  ├── commands/  │   ├── build.go  # kforge build  │   ├── bake.go  # kforge bake  │   ├── builder.go  # kforge builder create/ls/use/rm  │   ├── ci.go  # kforge ci init ← new v1.1.1  │   ├── detect.go  # kforge detect  │   ├── deploy.go  # kforge deploy init ← new v1.1.1  │   ├── doctor.go  # kforge doctor ← new v1.1.1  │   ├── init.go  # kforge init  │   ├── verify.go  # kforge verify  │   └── version.go  # kforge version  ├── internal/  │   ├── project/  # framework detection + templates  │   └── meta/meta.go  # shared version metadata  ├── builder/builder.go  # BuildKit builder store (~/.kforge/)  ├── bake/bake.go  # HCL + JSON config parser  ├── util/progress/progress.go  # 5 progress renderers  ├── .goreleaser.yml  # cross-platform release  ├── docker-kforge  # Docker CLI plugin shim  └── go.mod  # Go 1.24.0

Architecture

kforge is structured in five layers from CLI input to registry output.

CLIcmd/ + commands/

cobra-based commands, flag parsing, stdin/stdout

Detectioninternal/project/

framework + runtime version resolver

Generationcommands/{ci,deploy,init}.gonew v1.1.1

Dockerfile, CI YAML, deploy configs — new in v1.1.1

Build EngineBuildKit / Buildx

parallel multi-platform build, cache, secret injection

Registrydocker.io · ghcr.io · any OCI

multi-arch manifest push + cache export