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 doctorkforge detect
Auto-detects framework by scanning source files. Resolves runtime version.
| Flag | Description | Default |
|---|---|---|
--json | Structured JSON output for CI scripts | — |
$ kforge detect$ kforge detect --json
kforge init
Generates Dockerfile, .dockerignore, and kforge.hcl.
| Flag | Description | Default |
|---|---|---|
--detect | Auto-detect framework first | — |
--framework <name> | Specify framework (flask, nextjs, …) | — |
--auto | Non-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.
| Flag | Description | Default |
|---|---|---|
--platform <list> | Comma-separated platforms | linux/amd64 |
--push | Push 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.
| Flag | Description | Default |
|---|---|---|
--file <path> | Bake config file | kforge.hcl |
--push | Push 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.
| Flag | Description | Default |
|---|---|---|
--target github | Output .github/workflows/ci.yml | — |
--target gitlab | Output .gitlab-ci.yml | — |
$ kforge ci init --target github$ kforge ci init --target gitlab
kforge deploy init
Generates deployment bootstrap configs.
| Flag | Description | Default |
|---|---|---|
--target compose | docker-compose.yml with health check | — |
--target render | render.yaml for Render.com | — |
--target fly | fly.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 setupUsage 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
| Framework | Detection | Port |
|---|---|---|
| Next.js | package.json (next) | 3000 |
| React | package.json (react) | 3000 |
| Vue | package.json (vue) | 5173 |
| NestJS | package.json (@nestjs/core) | 3000 |
| Node.js | package.json (generic) | 3000 |
Version resolved from: .nvmrc → .node-version → package.json engines.node
Python
| Framework | Detection | Port |
|---|---|---|
| FastAPI | main.py / app.py (fastapi dep) | 8000 |
| Flask | app.py / main.py (flask dep) | 5000 |
| Django | manage.py | 8000 |
Version resolved from: pyproject.toml → .python-version → runtime.txt
Java / Spring Boot
| Framework | Detection | Port |
|---|---|---|
| Spring Boot (Maven) | pom.xml | 8080 |
| Spring Boot (Gradle) | build.gradle | 8080 |
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.
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.
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
| Flag | Description | Default |
|---|---|---|
type=local,src=.cache | Filesystem cache | — |
type=s3,bucket=my-bucket,region=us-east-1 | Amazon S3 | — |
type=azblob,account_name=...,name=... | Azure Blob Storage | — |
type=gha | GitHub 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/ ├── .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.
cobra-based commands, flag parsing, stdin/stdout
framework + runtime version resolver
Dockerfile, CI YAML, deploy configs — new in v1.1.1
parallel multi-platform build, cache, secret injection
multi-arch manifest push + cache export