agentsclimarketplace

Unikraft

Skill guillempuche/ai-standards/skills/unikraft

Open-source AI coding skills for Claude Code, Cursor, Copilot, and AI agents

Install
npx -y skills add guillempuche/ai-standards --skill unikraft

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Unikraft CLI (`unikraft`) commands for building and deploying to Unikraft Cloud. Use when working with Kraftfiles, deploying unikernels, or managing Unikraft Cloud instances/services/images. Covers the new `unikraft` CLI that replaces the legacy kraftkit `kraft`.

SKILL.md

13.9 KB, as published. Nobody here has run it

Unikraft CLI Reference

Build and deploy unikernels with the unikraft CLI.

Targets the new unikraft CLI 0.4.x (verified against 0.4.1) and the Unikraft Cloud REST API v1. Run unikraft version to check; if the major or minor differs, re-verify flags/commands against --help before following this skill.

New CLI vs legacy kraftkit — they are different tools

The binary is unikraft (from unikraft-cloud/cli). It replaces the legacy kraftkit kraft (v0.12.x). They are separate programs with:

  • a different command tree (unikraft run / unikraft build / unikraft instances …, not kraft cloud deploy),
  • a separate auth store — a kraft login / UKC_TOKEN env from kraftkit does not authenticate unikraft; you must run unikraft login (see below). The new CLI writes its own profile under ~/.config/unikraft, kraftkit uses ~/.config/kraftkit,
  • packaging split from deployunikraft build --output <ref> publishes an image, then unikraft run --image <ref> deploys it (kraftkit did both in one kraft cloud deploy).

If you see kraft, UKC_TOKEN, kraft cloud, or --rollout in a config or runbook, it is the legacy CLI — translate it to the new commands here.

Important: running commands

When working with unikraft commands:

  1. Show the command first — display it in a copy-paste code block before running it.
  2. Authenticated (cloud) commands need a login — anything hitting Unikraft Cloud (run, instances, services, images, metros, api, a publishing build) fails with profile not setup until unikraft login has run in that environment. The AI's shell may not be logged in; if a command returns profile not setup, hand it to the developer to run.
  3. Let the developer run it when a login or a real deploy is involved.

Installation

  • CI (GitHub Actions): unikraft/setup-action@v1 — installs the CLI and logs in headlessly. Inputs: version (latest/stable, dev/staging, or a release tag), token (login token), organization. It downloads the release asset unikraft-cli_<version>_<os>_<arch>.tar.gz from unikraft-cloud/cli.

    - uses: unikraft/setup-action@v1
      with:
        version: 0.4.1
        token: ${{ secrets.KRAFTCLOUD_TOKEN }}
        organization: my-org
    
  • Local: unikraft upgrade self-updates an installed CLI. Otherwise pull the tarball for your platform from https://github.com/unikraft-cloud/cli/releases (it holds the unikraft binary at its root).

  • Nix: the CLI is not in nixpkgs (only the legacy kraft is), but the Unikraft team maintains a NUR flake at github:unikraft/nur exposing packages.<system>.{unikraft-cli, unikraft-cli-staging, kraftkit} (+ an overlay). Add it as a flake input and take unikraft-cli — or unikraft-cli-staging while the stable attr is being fixed upstream.

Authentication

The new CLI reads the token from a file or stdin, not an env var, and associates the session with an organization.

# From a file:
unikraft login --token /path/to/token --organization my-org

# From stdin (no token on disk / no token in argv):
printf '%s' "$UKC_TOKEN" | unikraft login --token - --organization my-org

--organization is resolved from the control plane if omitted. A successful login stores a profile (named after the organization) under ~/.config/unikraft. Manage profiles with:

unikraft profile list          # profiles + their metros + which is active
unikraft profile use <name>    # switch active profile

Global flags / env available on every command: --profile ($UNIKRAFT_PROFILE), --config ($UNIKRAFT_CONFIG), --timeout ($UNIKRAFT_TIMEOUT), --log-level ($UNIKRAFT_LOG_LEVEL), --log-type, --[no-]telemetry.

Metros

Most write operations take --metro <m>. List them with unikraft metros list:

Use (current)Endpoint
fra, dal, sin, was, sfohttps://api.<metro>.unikraft.cloud

unikraft metros list also shows legacy metros fra0, dal0, sin0, was1 on api.<metro>.kraft.cloud — these are the old kraft.cloud endpoints. Use the suffix-less names only; treat any <metro>0 as legacy.

[!IMPORTANT] Only the create verbs take --metrounikraft run and unikraft services create. The read/manage verbs (instances list/get/delete/logs, images list, services get) reject --metro with unknown flag --metro; they take a bare name (the logged-in profile spans metros) or a --filter 'metro==<m>'. This bites in CI: piping a failed instances delete <name> --metro fra through || true silently skips the delete, and the next run then fails with "instance already exists".

Command tree

Commands
  unikraft run                 # Run an image as an instance (deploy)
  unikraft build               # Build a Unikraft project into a container image
  unikraft tui                 # Browse resources in a TUI

Resources
  unikraft metros              # List/inspect cloud metros
  unikraft quotas              # Show quota usage
  unikraft instances           # Manage instances  (aliases: instance, vm, vms)
  unikraft services            # Manage service groups (svc, svcs)
  unikraft volumes             # Manage persistent volumes (vol, vols)
  unikraft certificates        # Manage TLS certificates (cert, certs)
  unikraft images              # Manage images (image, img, imgs)

Utilities
  unikraft api <endpoint>      # Authenticated raw REST call (e.g. /v1/instances)
  unikraft version             # Version info
  unikraft upgrade             # Self-update the CLI
  unikraft completion          # Shell completions

Config
  unikraft login / logout      # Authentication
  unikraft profile             # get / list / use
  unikraft config              # Manage CLI configuration

Build (package an image)

# Build the project in the current directory and PUBLISH to the registry.
# The <org> prefix is your organization (see `unikraft profile list`).
unikraft build . --output <org>/my-app:latest

# Build and save to a LOCAL OCI archive (no publish):
unikraft build . --output ./dist/my-app.oci.tar

# Build-time inputs and secrets:
unikraft build . --build-arg VERSION=1.2.3 --secret id=npm,src=$HOME/.npmrc

Flags: -o/--output, --build-arg, --no-cache, --secret, --ssh, --insecure, plus the global --timeout=<duration>. The input path defaults to ..

Run (deploy an instance)

# Deploy a new instance exposing an HTTPS service:
unikraft run --metro fra --image <org>/my-app:latest \
  -p 443:8080/http+tls -p 80:443/http+redirect \
  -m 2048M --restart on-failure -e NODE_ENV=production

# Preview without deploying:
unikraft run --metro fra --image <org>/my-app:latest --dry-run

Common flags: --metro, --image, -n/--name, -e/--env, -m/--memory (binary units, e.g. 2048M), --vcpus, -p/--publish (<src>:<dest>[/<handlers>]), --domain, --service (attach to an existing service group), --restart (on-failure …), --scale-to-zero, -v/--volume, --replicas, --rm, --follow, --dry-run.

Memory units changed from legacy kraftkit: -M 2048 (MiB) → -m 2048M.

Instances, services, images

unikraft instances list                    # or: ls
unikraft instances get <name>              # inspect
unikraft instances logs <name>             # console output
unikraft instances wait <filter>           # block until instances match (readiness gate)
unikraft instances delete <name>           # remove
unikraft instances start|stop|suspend|restart <name>

unikraft services list                     # service groups (load balancers)
unikraft services get <name>
unikraft services create …                 # create a named service group
unikraft services edit <name>              # change its config / instance set

unikraft images list                       # image refs + digests (--filter 'ref~="my-app"')
unikraft images build                      # same engine as `unikraft build`
unikraft images delete <ref>

volumes (create/attach/detach/clone/import/…) and certificates (create/get/wait/…) follow the same verb pattern.

[!WARNING] Reading an instance dumps its secrets. instances list -o json/-o yaml and instances get (without -f) return the instance's full runtime.env — including secret values such as DATABASE_URL — in cleartext. When you only need identifiers, field-limit the output: unikraft instances list -f name -o quiet (names only, no env). Never pipe an un-limited instance read into shared logs, CI output, or an issue.

Rolling updates (zero-downtime)

The new CLI has no single --rollout flag (kraftkit's kraft cloud deploy --rollout remove_sequential). A zero-downtime swap of an instance behind an existing service group is composed from primitives:

  1. unikraft run --service=<group> --image <new-ref> … — start a new instance and attach it to the service group that owns the domain/ports (do not re-pass -p/--domain; the group owns those). Omit --name so the new instance gets a unique name and can run alongside the old one.
  2. unikraft instances wait <filter> — wait until the new instance is ready.
  3. unikraft instances delete <old-name> — remove the previous instance.

Confirm the exact recommended sequence (and whether a built-in rollout exists in your CLI version) with unikraft run --help / the Unikraft team before relying on it for a production deploy.

[!IMPORTANT] Check quota headroom before a rolling update. The overlap briefly runs two instances, so it needs ~2× the instance's memory + vCPUs at once. Run unikraft quotas [--metro <m>] first (optional --metro, no subcommand): if adding a second instance would exceed the memory or instance cap, fall back to delete-then-recreate (accepting a brief gap) or request a quota bump. Near the cap, a rolling run fails with a quota error mid-deploy.

Kraftfile (spec v0.7)

Keep the Kraftfile (and the Dockerfile it references) at the build context root — the rootfs path can't reach parent directories, and the Docker build needs the repo root as context to COPY sibling folders.

spec: v0.7
name: my-server
# base-compat runs the node binary bundled in the image.
runtime: base-compat:latest

labels:
  cloud.unikraft.v1.instances/scale_to_zero.policy: "off"

rootfs:
  source: ./Dockerfile
  format: erofs
cmd: ["/usr/local/bin/node", "/app/dist/main.mjs"]

Deployment example (build once, deploy the image)

# 1) Log in (once per environment).
printf '%s' "$UKC_TOKEN" | unikraft login --token - --organization my-org

# 2) Build + publish a versioned image.
unikraft build . --output my-org/my-app:2026.7.9 --timeout 10m

# 3) First deploy — create the service group, then run into it.
unikraft services create --name my-app \
  --domain my-app.example.com 443:8080/http+tls 80:443/http+redirect
unikraft run --metro fra --service my-app --image my-org/my-app:2026.7.9 \
  -m 2048M --restart on-failure -e NODE_ENV=production

# 4) Subsequent deploys — see "Rolling updates" above.

# Verify:
unikraft instances list
curl -sf https://my-app.example.com/health
unikraft instances logs my-app-<suffix>

Troubleshooting

SymptomCause / fix
profile not setupNot logged in — run unikraft login (kraftkit's login/UKC_TOKEN doesn't count).
unknown flag --metro on */listList/get subcommands scope by profile/--filter, not --metro.
Image builds but instance won't bootCheck runtime, the cmd path, and that env vars the app needs are passed with -e.
504 Gateway TimeoutScale-to-zero cold start — set the scale-to-zero policy off for latency-sensitive services.
rootfs / COPY build failuresKeep the Kraftfile + Dockerfile at the build-context root; no ../ in the rootfs path.
Legacy fra0/kraft.cloud host in a refReplace with the suffix-less metro (fra, api.fra.unikraft.cloud).

Unikraft Cloud REST API (v1)

The CLI wraps a REST API. Reach for it via unikraft api <endpoint> (uses the logged-in profile), or call it directly with a bearer token for automation.

unikraft api /v1/instances                       # via the CLI (logged-in profile)

curl https://api.fra.unikraft.cloud/v1/instances \
  -H "Authorization: Bearer $UKC_TOKEN"          # raw, any HTTP client
  • Base URLs are metro-scoped: https://api.<metro>.unikraft.cloud/v1 for fra, dal, sin, was, sfo. Never use a <metro>0 legacy host.
  • Every response uses the {status, message, data, errors, op_time_us} envelope; bulk endpoints return per-item status.

Full endpoint tables, curl examples, and gotchas: references/api-v1.md.


Examples repository

Reference examples (Kraftfiles + Dockerfiles for many runtimes): https://github.com/unikraft-cloud/examples.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.