From bb5e2df71be59e15550e43f5126a6608c39d7e00 Mon Sep 17 00:00:00 2001 From: Unikraft Bot Date: Fri, 15 May 2026 04:38:46 +0000 Subject: [PATCH 1/8] chore: Update guides from examples repository Signed-off-by: Unikraft Bot --- pages/guides/httpserver-go1.21.mdx | 2 +- pages/guides/httpserver-rust1.88-actix-web4.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/guides/httpserver-go1.21.mdx b/pages/guides/httpserver-go1.21.mdx index ce31310..ebccf2f 100644 --- a/pages/guides/httpserver-go1.21.mdx +++ b/pages/guides/httpserver-go1.21.mdx @@ -114,7 +114,7 @@ curl https://red-dew-jtk6yxk1.fra.unikraft.app ``` ```text -hello, world! +Hello, World! ``` You can list information about the instance by running: diff --git a/pages/guides/httpserver-rust1.88-actix-web4.mdx b/pages/guides/httpserver-rust1.88-actix-web4.mdx index 62082bc..7e50031 100644 --- a/pages/guides/httpserver-rust1.88-actix-web4.mdx +++ b/pages/guides/httpserver-rust1.88-actix-web4.mdx @@ -114,7 +114,7 @@ curl https://autumn-silence-wupu2nus.fra.unikraft.app/hey ``` ```text -Hello world! +Hello, World! Hey there! ``` From e445a4bf24f5d2689d5e9b4c122314a2f80cac2c Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Fri, 15 May 2026 09:57:47 +0100 Subject: [PATCH 2/8] ci: Trigger deploys on www when pushing to staging/stable Merging to prod-staging / prod-stable should trigger website deploys for www. Now, anytime we deploy docs to prod-stable, this will update the website. Signed-off-by: Justin Chadwell --- .github/actions/setup-www/action.yaml | 10 ++++++---- .github/workflows/pr-preview.yaml | 2 +- .github/workflows/prod-stable.yaml | 12 +++++++++++- .github/workflows/prod-staging.yaml | 12 +++++++++++- Dockerfile | 14 +++++++++----- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.github/actions/setup-www/action.yaml b/.github/actions/setup-www/action.yaml index 7afcc29..a716ce0 100644 --- a/.github/actions/setup-www/action.yaml +++ b/.github/actions/setup-www/action.yaml @@ -38,10 +38,12 @@ inputs: posthog-key: required: false description: The key to authenticate with PostHog. - docs-channel: + channel: required: false - default: prod-staging - description: The docs channel to use for the OpenAPI spec. + default: staging + description: | + The branch/channel of dependency repos (openapi, x) to pull when + building the site. One of `staging` or `stable`. outputs: domain: @@ -101,7 +103,7 @@ runs: --build-arg PUBLIC_STATUS_PAGE_SUMMARY_URL="https://status.unikraft.cloud/api/v1/summary" \ --build-arg PUBLIC_POSTHOG_HOST="${{ inputs.posthog-host }}" \ --build-arg PUBLIC_POSTHOG_KEY="${{ inputs.posthog-key }}" \ - --build-arg DOCS_CHANNEL="${{ inputs.docs-channel }}" \ + --build-arg CHANNEL="${{ inputs.channel }}" \ --memory "${{ inputs.memory }}" \ --service "${{ inputs.name }}" \ --image "${{ inputs.name }}" \ diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index ea7b74e..dfcd5bf 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -57,7 +57,7 @@ jobs: name: com-docs-pr-${{ github.event.number }} metro: ${{ vars.UKC_METRO }} log-level: trace - docs-channel: prod-staging + channel: staging - uses: chrnorm/deployment-action@v2 name: Create GitHub deployment diff --git a/.github/workflows/prod-stable.yaml b/.github/workflows/prod-stable.yaml index 67ba4a0..328d918 100644 --- a/.github/workflows/prod-stable.yaml +++ b/.github/workflows/prod-stable.yaml @@ -49,7 +49,7 @@ jobs: name: com-docs-stable metro: ${{ vars.UKC_METRO }} log-level: trace - docs-channel: prod-stable + channel: stable - uses: chrnorm/deployment-action@v2 name: Create GitHub deployment @@ -83,3 +83,13 @@ jobs: shell: bash run: | exit 1 + + - name: Trigger www prod-stable deploy + if: ${{ steps.www.outcome == 'success' }} + shell: bash + env: + GH_TOKEN: ${{ secrets.GH_PAT }} + run: | + gh workflow run prod-stable.yaml \ + --repo unikraft-cloud/www \ + --ref prod-stable diff --git a/.github/workflows/prod-staging.yaml b/.github/workflows/prod-staging.yaml index 49d353d..63901bd 100644 --- a/.github/workflows/prod-staging.yaml +++ b/.github/workflows/prod-staging.yaml @@ -49,7 +49,7 @@ jobs: name: com-docs-staging metro: ${{ vars.UKC_METRO }} log-level: trace - docs-channel: prod-staging + channel: staging - uses: chrnorm/deployment-action@v2 name: Create GitHub deployment @@ -83,3 +83,13 @@ jobs: shell: bash run: | exit 1 + + - name: Trigger www prod-staging deploy + if: ${{ steps.www.outcome == 'success' }} + shell: bash + env: + GH_TOKEN: ${{ secrets.GH_PAT }} + run: | + gh workflow run prod-staging.yaml \ + --repo unikraft-cloud/www \ + --ref prod-staging diff --git a/Dockerfile b/Dockerfile index 0af4827..26543e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,10 @@ ################################################################################ FROM golang:1.26 AS build-kraft-docs +ARG CHANNEL=staging + WORKDIR /kraftkit -ADD https://github.com/unikraft/kraftkit.git /kraftkit +ADD https://github.com/unikraft/kraftkit.git#${CHANNEL} /kraftkit RUN make docs @@ -15,8 +17,10 @@ RUN make docs ################################################################################ FROM golang:1.26 AS build-cli-docs +ARG CHANNEL=staging + WORKDIR /cli -ADD https://github.com/unikraft/cli.git /cli +ADD https://github.com/unikraft/cli.git#${CHANNEL} /cli RUN make docs @@ -49,11 +53,11 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ COPY . . # Grab the latest OpenAPI spec based on the desired channel. -ARG DOCS_CHANNEL=prod-staging -ADD https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/${DOCS_CHANNEL}/platform.yaml apis/platform.yaml +ARG CHANNEL=staging +ADD https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/prod-${CHANNEL}/platform.yaml apis/platform.yaml # Kraftfile v0.7 schema docs (from unikraft-cloud/x) -ADD https://raw.githubusercontent.com/unikraft-cloud/x/refs/heads/${DOCS_CHANNEL}/kraftfile/schema.md pages/kraftfile/v0.7.md +ADD https://raw.githubusercontent.com/unikraft-cloud/x/refs/heads/prod-${CHANNEL}/kraftfile/schema.md pages/kraftfile/v0.7.md # Kraft (old CLI) docs -> /cli/kraft/ COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud /docs/pages/cli/kraft From 0351fb05044c80eded4f3c0dfa76f2a885fcbbcc Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Fri, 15 May 2026 09:45:14 +0100 Subject: [PATCH 3/8] ci: Use upstream check-pr action Which uses our org-wide commitlint settings. Signed-off-by: Justin Chadwell --- .github/workflows/check-pr.yaml | 86 +++------------------------------ 1 file changed, 8 insertions(+), 78 deletions(-) diff --git a/.github/workflows/check-pr.yaml b/.github/workflows/check-pr.yaml index 799edb8..aff5b8b 100644 --- a/.github/workflows/check-pr.yaml +++ b/.github/workflows/check-pr.yaml @@ -2,89 +2,19 @@ name: check/pr on: pull_request: - types: - - opened - - synchronize - - reopened - branches: - - prod-staging - -permissions: - pull-requests: write - contents: read + types: [opened, synchronize, reopened, edited] + branches: [prod-staging] jobs: - commits: + check-pr: runs-on: ubuntu-latest steps: - - name: format - if: always() - uses: taskmedia/action-conventional-commits@v1.1.20 - with: - types: "build|ci|docs|feat|fix|perf|refactor|style|test|revert|chore" - token: ${{ secrets.GH_PAT }} - - - name: length - if: ${{ github.actor != 'dependabot' && github.actor != 'dependabot[bot]' }} - uses: gsactions/commit-message-checker@v2 - with: - pattern: '((^(?=(?:.|\n)*(?:^|\n)\[\d\]: .{69,}(?:$|\n)(?:.|\n)*)(?:.|\n)*$)|(^(?!(?:.|\n)*(?:^|\n).{74,}(?:$|\n)(?:.|\n)*)(?:.|\n)*$))' - flags: '' - error: 'The maximum line length of 74 characters is exceeded.' - excludeDescription: 'true' - excludeTitle: 'true' - checkAllCommitMessages: 'true' - accessToken: ${{ secrets.GH_PAT }} - - - name: signed-off-by - if: always() - uses: gsactions/commit-message-checker@v2 - with: - pattern: '^Signed-off-by: .+ \<.+\@.+\..+\>$' - error: 'Signed-off-by line is missing.' - excludeDescription: 'true' - excludeTitle: 'true' - checkAllCommitMessages: 'true' - accessToken: ${{ secrets.GH_PAT }} - - pr: - runs-on: ubuntu-latest - steps: - - name: title-format - if: always() - uses: gsactions/commit-message-checker@v2 - with: - pattern: '^(build|ci|docs|feat|fix|perf|refactor|style|test|revert|chore)(\([\w\-\_\d]+\))?!?: ' - error: 'The PR title must follow the conventional commits format.' - excludeDescription: 'true' - excludeTitle: 'false' - checkAllCommitMessages: 'false' - accessToken: ${{ secrets.GH_PAT }} - - - name: title-length - if: ${{ github.actor != 'dependabot' && github.actor != 'dependabot[bot]' }} - uses: gsactions/commit-message-checker@v2 - with: - pattern: '^(?!.{75,}).*' - flags: '' - error: 'The maximum line length of 75 characters is exceeded.' - excludeDescription: 'true' - excludeTitle: 'false' - checkAllCommitMessages: 'false' - accessToken: ${{ secrets.GH_PAT }} - - - name: description - if: ${{ github.actor != 'dependabot' && github.actor != 'dependabot[bot]' }} - uses: gsactions/commit-message-checker@v2 - with: - pattern: '^\S+( \S+)*$' - error: 'The PR description must not be empty.' - flags: 'gm' - excludeDescription: 'false' - excludeTitle: 'true' - checkAllCommitMessages: 'false' - accessToken: ${{ secrets.GH_PAT }} + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Run check-pr + uses: unikraft-cloud/x/.github/actions/check-pr@prod-staging lint: runs-on: ubuntu-latest From 3ca8977ce8fa12f6dd89394af088e804947e1fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Rasc=C3=B3n?= Date: Fri, 22 May 2026 12:41:07 +0200 Subject: [PATCH 4/8] fix(favicon): Set proper favicon route MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jesús Rascón --- zudoku.config.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 465dd2a..6650a40 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -3,7 +3,7 @@ import type { ZudokuConfig } from "zudoku"; const config: ZudokuConfig = { metadata: { title: "%s | Unikraft Cloud Docs", - favicon: "/favicon.ico", + favicon: "/docs/favicon.ico", }, basePath: "/docs", site: { From 6a318d8d41a916decf3e44c8ca6963aff39961fa Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 26 May 2026 14:23:17 +0300 Subject: [PATCH 5/8] fix: Switch to cli as CodeTabs sync key Signed-off-by: Alex-Andrei Cioc --- pages/cli/registries.mdx | 6 ++--- pages/features/autoscale.mdx | 6 ++--- pages/features/load-balancing.mdx | 6 ++--- pages/features/roms.mdx | 8 +++--- pages/features/scale-to-zero.mdx | 6 ++--- pages/features/snapshots.mdx | 2 +- pages/integrations/kubernetes.mdx | 10 +++---- pages/platform/certificates.mdx | 8 +++--- pages/platform/domains.mdx | 6 ++--- pages/platform/images.mdx | 12 ++++----- pages/platform/metros.mdx | 4 +-- pages/platform/services.mdx | 8 +++--- pages/platform/troubleshooting.mdx | 14 +++++----- pages/platform/volumes.mdx | 14 +++++----- pages/tutorials/docker-to-ukc.mdx | 12 ++++----- pages/tutorials/environment-variables.mdx | 2 +- pages/tutorials/instance-metrics.mdx | 2 +- pages/tutorials/rootfs-volumes-roms.mdx | 4 +-- pages/use-cases/api-gateways.mdx | 4 +-- pages/use-cases/build-test-environments.mdx | 30 ++++++++++----------- pages/use-cases/headless-browsers.mdx | 10 +++---- pages/use-cases/mcp-servers.mdx | 2 +- pages/use-cases/remote-desktops.mdx | 14 +++++----- pages/use-cases/remote-ides.mdx | 8 +++--- pages/use-cases/sandboxes.mdx | 14 +++++----- pages/use-cases/serverless-databases.mdx | 16 +++++------ pages/use-cases/serverless-functions.mdx | 22 +++++++-------- pages/use-cases/webhooks.mdx | 2 +- 28 files changed, 126 insertions(+), 126 deletions(-) diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index d18df6f..ea492f2 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -46,7 +46,7 @@ You can also refer to images by digest to pin to an exact version. Registry authentication uses the same API token as the rest of the platform. The new CLI uses profiles, while the legacy CLI reads `UKC_TOKEN` directly. - + ```bash title="unikraft" unikraft login @@ -134,7 +134,7 @@ For more control, for example when packaging [ROMs](/features/roms) or base imag ## Listing images - + ```bash title="unikraft" unikraft images list @@ -168,7 +168,7 @@ There may be a delay of a few minutes between pushing or removing an image and t ## Removing images - + ```bash title="unikraft" # Not supported yet for direct pushing to node registries. diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 3effb5e..2b8d2f5 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -36,7 +36,7 @@ Autoscale, as well as load balancing in general, currently supports only Interne First, create an instance, in this example using NGINX: - + ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples @@ -182,7 +182,7 @@ type: step You can further check that the master instance is on `standby` (scaled to zero), assuming your service hasn't received any traffic yet. You can get the UUID of your master instance from the legacy CLI scale get command above. - + ```bash title="unikraft" unikraft instances get f840ac12-f485-4f02-9f33-6a0a7de46f1f -o list @@ -222,7 +222,7 @@ curl https://small-leaf-rafirkw7.fra.unikraft.app You should get an immediate response, even though the instance was on `standby`. You can use a watch command to see if you catch the instance changing state from `standby` to `running`: - + ```bash title="unikraft" unikraft instances list --watch diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index 110a758..f81c5f6 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -35,7 +35,7 @@ In case there are no other instances available, the load balancer blocks excess To set load balancing up, first use the deploy or run flow with the publish flag to create the service as part of the instance creation. For example, use NGINX as the app: - + ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples @@ -72,7 +72,7 @@ This single command will (a) create a service via the `-p` flag and (b) start an With this in place, it's now time to start a second instance and attach it to the created service (in this case, named `wandering-shape-n6mhimgn`): - + ```bash title="unikraft" cd examples/nginx/ @@ -111,7 +111,7 @@ The command's output should look like this: Both the `url` and `service` fields in the 2 instances are the same. To check that it worked, run the following command: - + ```bash title="unikraft" unikraft services list diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 16761b4..0dbd50a 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -184,7 +184,7 @@ kraft pkg \ Wait a few seconds for propagation and check that the image is present: - + ```bash title="unikraft" unikraft images list @@ -258,7 +258,7 @@ kraft pkg \ Wait a few seconds for propagation and check that the ROMs are present: - + ```bash title="unikraft" unikraft images list @@ -356,7 +356,7 @@ curl -X POST \ Check that the instances are up: - + ```bash title="unikraft" unikraft instances get test-http-python-rom1 @@ -543,7 +543,7 @@ Hi from 2nd ROM! When done, remove the instances: - + ```bash title="unikraft" unikraft instances delete test-http-python-rom1 test-http-python-rom2 diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 3632cbc..3fb831f 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -211,7 +211,7 @@ You can disable scale-to-zero either by setting the label to `false`, or with th Since Unikraft Cloud has scale-to-zero on by default, all you need to do is to start an instance normally: - + ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples @@ -249,7 +249,7 @@ This command will create the NGINX instance with scale-to-zero enabled: Note that at first the system lists the status as `running` in the output of the deploy or run flow. Check the instance's status: - + ```bash title="unikraft" unikraft instances list @@ -310,7 +310,7 @@ curl https://twilight-gorilla-ui5b6kwt.fra.unikraft.app You should get an NGINX response with no noticeable delay. For fun, try to use the following command to see if you can catch the instance's `STATE` field changing from `standby` to `running`: - + ```bash title="unikraft" unikraft instances list --watch diff --git a/pages/features/snapshots.mdx b/pages/features/snapshots.mdx index 1e7256e..b4ffdfb 100644 --- a/pages/features/snapshots.mdx +++ b/pages/features/snapshots.mdx @@ -32,7 +32,7 @@ You can see an example of such a `Kraftfile` and label in the [Spring Boot examp Once deployed, you can check whether this mechanism works for your app via the CLI: - + ```bash title="unikraft" unikraft instances get diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index e1c9d13..6214cfd 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -129,7 +129,7 @@ Your app is now managed from the Kubernetes cluster, but is actually running on To check the instances, run: - + ```shell title="unikraft" $ unikraft instances list @@ -155,7 +155,7 @@ As you can see, all instances have the same FQDN. This is because Kraftlet created a corresponding Unikraft Cloud service for the Kubernetes service defined in YAML above. You can check the created service with the following command: - + ```shell title="unikraft" $ unikraft services list @@ -203,7 +203,7 @@ my-claim Bound pv-7ab06383-ac03-4a81-968a-1b0cff03c23a 10Mi RWO Also, you can check the volumes on the Unikraft Cloud: - + ```shell title="unikraft" $ unikraft volumes list @@ -249,7 +249,7 @@ spec: If you check the instances again, you will see a new instance created from the Pod: - + ```shell title="unikraft" $ unikraft instances list @@ -265,7 +265,7 @@ nginx-pod-nginx fragrant-breeze-llesxdta.fra.unikraft.app running since 1min And if you check the volume now, you will see it's attached and mounted by the created instance: - + ```shell title="unikraft" $ unikraft volumes list diff --git a/pages/platform/certificates.mdx b/pages/platform/certificates.mdx index 8ccf939..870a143 100644 --- a/pages/platform/certificates.mdx +++ b/pages/platform/certificates.mdx @@ -5,7 +5,7 @@ navigation_icon: shield-check To use a custom certificate instead of the automatically generated one from the default public certificate authority, create a certificate with the CLI: - + ```ansi title="unikraft" unikraft certificates create \ @@ -31,7 +31,7 @@ It can also be a wildcard domain. Use the CLI to view and manage certificates. For example, to list certificates: - + ```bash title="unikraft" unikraft certificates list @@ -53,7 +53,7 @@ mydomain-cert valid *.mydomain.com 2 days ago Retrieve full information about a certificate with: - + ```bash title="unikraft" unikraft certificates get mydomain.com-sa4x9 @@ -84,7 +84,7 @@ serial number: 0455BBAEC140EACBA5FEEAE6D817E73EF266 To remove a certificate, first remove any instances from the relevant service and then remove the service. Remove the certificate with: - + ```bash title="unikraft" unikraft certificates delete mydomain.com-sa4x9 diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index 875f718..6d82b6b 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -33,7 +33,7 @@ ALIAS (apex alias) and ANAME (authoritative alias) are DNS record types some pro :::tip You can find information about the Unikraft Cloud metros available to you, as well as their IP addresses, via the CLI. - + ```bash title="unikraft" unikraft metros list @@ -65,7 +65,7 @@ Log into Unikraft Cloud and select a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪). Set the following: - + ```bash title="unikraft" unikraft login @@ -85,7 +85,7 @@ The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the With this in place, use the CLI to create an instance of the web server and link it to a custom name. Unikraft Cloud does this through the domain flag: - + ```bash title="unikraft" unikraft build . --output /nginx:latest diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 4d2cdc8..126fdf0 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -122,7 +122,7 @@ This guide uses a Python [app](/guides/httpserver-python3.12) as an example to s Start with the simplest workflow: create an image from a Python app and start an instance from it: - + ```bash title="unikraft" unikraft build . --output /httpserver-python312:latest @@ -185,7 +185,7 @@ The controller fetches the image from the registry to start the instance. You can see your images by running the following command: - + ```bash title="unikraft" unikraft images list @@ -232,7 +232,7 @@ There may be a delay of a few minutes between removing an image from the registr For the next workflow, start many instances: - + ```bash title="unikraft" unikraft build . --output /httpserver-python312:latest @@ -245,7 +245,7 @@ kraft cloud deploy -p 443:8080 -M 512Mi --replicas 2 . - + ```ansi title="unikraft" metro: fra name: httpserver-python312-lscmn @@ -325,7 +325,7 @@ timestamps: Check that it worked by listing all instances with: - + ```bash title="unikraft" unikraft instances list @@ -360,7 +360,7 @@ Three instances run: the original plus two replicas. In this final workflow, take the existing image and start new instances from it: - + ```bash title="unikraft" unikraft run --metro=fra -p 443:8080/http+tls -m 512M --image /httpserver-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca diff --git a/pages/platform/metros.mdx b/pages/platform/metros.mdx index 7fe18e8..da5e68a 100644 --- a/pages/platform/metros.mdx +++ b/pages/platform/metros.mdx @@ -17,7 +17,7 @@ By default, at present, Unikraft Cloud supports the following metros: You can list the metros available to your account via the CLI. - + ```bash title="unikraft" unikraft metros list @@ -84,7 +84,7 @@ The legacy CLI also supports the `UKC_METRO` environment variable. Use the IATA code descriptor to target the specific metro. For example with `fra`: - + ```bash title="unikraft" unikraft run --metro=fra -p 443:8080/http+tls --image=nginx:latest ``` diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 57c241c..0373fd3 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -28,7 +28,7 @@ The rest of this guide shows how to create a service first, then use the CLI to First, create a new service with the CLI: - + ```bash title="unikraft" unikraft services create \ @@ -50,7 +50,7 @@ This example assumes that the app opens port 8080. Now use the CLI with the service flag to attach the instance to the `my-service` service. For example, from the [Go web server guide](/guides/go): - + ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples @@ -111,7 +111,7 @@ That's it. In the end, if you want to remove a service, use: - + ```bash title="unikraft" unikraft services delete my-service @@ -165,7 +165,7 @@ For example, the following creates the service `my-service` with three published - Port 80 with the `http` and `redirect` handlers (HTTP mode). - Port 10000 with only the `tls` handler (TCP mode). - + ```bash title="unikraft" unikraft services create \ diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 151094f..efe8c17 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -13,7 +13,7 @@ If you need help, reach out to Unikraft Cloud Support. An app may crash, freeze, or misbehave. To inspect it, try either: - + ```bash title="unikraft" unikraft instances logs @@ -122,7 +122,7 @@ rm -fr ~/.local/share/kraftkit The most common reason is that you deployed an app to one metro but listed a different one. Use the `--metro` flag per command, or use the legacy CLI environment variable for a session: - + ```bash title="unikraft" unikraft instances list --metro @@ -201,7 +201,7 @@ The legacy deploy command performs steps on your local device before actually de If any of these steps fail, enable legacy CLI debugging with the `--log-level` and `--log-type` flags: - + ```bash title="kraft" kraft cloud deploy --log-level debug --log-type basic [...] ``` @@ -236,7 +236,7 @@ If not, report it with the output on the [Discord server](/discord). The most direct way to debug an app is to use the app console output, which may include kernel output. To see it, after starting the Unikraft Cloud instance, use: - + ```bash title="unikraft" unikraft instances logs @@ -338,7 +338,7 @@ cmd: ["/server"] That is, change `base:latest` to `base:latest-dbg`. Now Unikraft Cloud is ready to re-deploy: - + ```bash title="unikraft" unikraft build . --output /http-go-strace:latest @@ -353,7 +353,7 @@ kraft cloud deploy --name http-go-strace -p 443:8080 . You can now inspect the logs as before and view system call tracing: - + ```bash title="unikraft" unikraft instances logs http-go-strace @@ -401,7 +401,7 @@ Contact Unikraft Cloud on the [Discord server](/discord) and include this output While you debug an issue you can mitigate crashes by setting a restart policy. For example, use the CLI to set `--restart on-failure` so the platform restarts the app if it crashes. - + ```bash title="unikraft" unikraft run --metro=fra --restart=on-failure --image=my-app:latest diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index e2b5071..80bfe62 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -21,7 +21,7 @@ In this case, the volume's lifetime is tied to the instance - when you delete th To start, create the volume with the CLI, with size in MBs and name `my-volume`: - + ```bash title="unikraft" unikraft volumes create \ @@ -41,7 +41,7 @@ kraft cloud volume create \ The command should return the volume's UUID, and you can check the operation worked via: - + ```bash title="unikraft" unikraft volumes list @@ -140,7 +140,7 @@ mounted persistent volume and print out the current contents of the file. Start the Flask web server, create a [service](/platform/services) for it via the publish flag, and mount the `my-volume` volume at `/mnt`: - + ```bash title="unikraft" unikraft build . --output /http-python312-flask30:latest @@ -173,7 +173,7 @@ You should see output like: To confirm that the platform attached the volume, run: - + ```bash title="unikraft" unikraft volumes get my-volume @@ -217,7 +217,7 @@ Log file created. To test data persistence, first stop the instance, detach the volume, and remove the instance: - + ```bash title="unikraft" unikraft instances stop http-python312-flask30-2h608 @@ -236,7 +236,7 @@ The explicit volume detach command is only available in the legacy CLI. Now start another instance and, like before, mount the same volume: - + ```bash title="unikraft" unikraft build . --output /http-python312-flask30:latest @@ -283,7 +283,7 @@ Log file created. To clean up, first detach the volume from all instances and then remove it: - + ```bash title="unikraft" unikraft volumes delete diff --git a/pages/tutorials/docker-to-ukc.mdx b/pages/tutorials/docker-to-ukc.mdx index accb312..3b7ccfa 100644 --- a/pages/tutorials/docker-to-ukc.mdx +++ b/pages/tutorials/docker-to-ukc.mdx @@ -18,7 +18,7 @@ You also need a container runtime such as Docker because the `Dockerfile` builds Set your Unikraft Cloud credentials and preferred metro before deploying: - + ```bash title="unikraft" unikraft login @@ -100,7 +100,7 @@ Also note that instances run as `root` unless you explicitly switch users at run Run an initial deployment before optimizing anything. This confirms that the runtime, filesystem, and command line are valid. - + ```bash title="unikraft" unikraft build . --output /docker-port:latest @@ -243,7 +243,7 @@ This is the same shape used by examples such as [`node21-nextjs`](https://github After reducing the filesystem, deploy it with [`EROFS`](/tutorials/rootfs-formats) when possible. This often gives better cold-boot behaviour and lower memory pressure than `CPIO` for larger images. - + ```bash title="unikraft" unikraft build . --output /docker-port:latest @@ -280,7 +280,7 @@ Before calling the image minimized, check the following: If the upstream image depends on environment variables, you can optionally carry them over explicitly. The most reliable method at deployment time is to pass them through the CLI with `--env` or `-e`. - + ```bash title="unikraft" unikraft build . --output /docker-port:latest @@ -339,7 +339,7 @@ It tests whether the app can suspend cleanly and resume on the next request. The simplest way to test scale-to-zero is to deploy with an explicit scale-to-zero policy and a short cooldown: - + ```bash title="unikraft" unikraft build . --output /docker-port:latest @@ -364,7 +364,7 @@ kraft cloud deploy \ After deployment, wait a few seconds and then list the instances: - + ```bash title="unikraft" unikraft instances list diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx index bdefc26..552d160 100644 --- a/pages/tutorials/environment-variables.mdx +++ b/pages/tutorials/environment-variables.mdx @@ -59,7 +59,7 @@ When deploying an instance, you can pass environment variables using the `--env` You can specify many environment variables by using the flag many times. The flag works similarly to the `docker run -e` flag. - + ```bash title="unikraft" unikraft run --metro=fra -e MY_ENV_VAR=my_value --image=my-app:latest diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index f553737..eb6b487 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -24,7 +24,7 @@ The following example creates an instance and retrieves its metrics using `curl` First, provision a new instance: - + ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx index f09a49b..8c56d35 100644 --- a/pages/tutorials/rootfs-volumes-roms.mdx +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -63,7 +63,7 @@ As such you can use them for persistent data, secrets, storage, logs, and more, To create and use a volume, you can use the CLI volume commands. For example, you need to first create a volume: - + ```bash title="unikraft" unikraft volumes create \ @@ -90,7 +90,7 @@ kraft cloud volume import --volume my-volume --source my-data/ Finally, when you deploy an instance you can attach the volume to it: - + ```bash title="unikraft" unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt --image=my-app:latest diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index 11a82ed..5bad763 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -71,7 +71,7 @@ cd examples/tyk/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="kraft" # Set Unikraft Cloud access token @@ -117,7 +117,7 @@ curl https:///hello | jq Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="kraft" kraft cloud --help diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx index 8c6357b..0c349a8 100644 --- a/pages/use-cases/build-test-environments.mdx +++ b/pages/use-cases/build-test-environments.mdx @@ -62,7 +62,7 @@ cd examples/build-environments/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -80,7 +80,7 @@ export UKC_METRO=fra Package and push the base Go runtime image (see `server.go` for the runtime implementation): - + ```bash title="unikraft" unikraft build . --output /go-build-env:latest @@ -105,7 +105,7 @@ The server in `server.go` loads `/rom/rom.go`, compiles it to `/run/rom.so` usin Create a short-lived instance from the base image (without ROM attached). The server writes to `/uk/libukp/template_instance` and turns the instance into a [template](/platform/instances#instance-templates) before serving requests: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -126,7 +126,7 @@ kraft cloud instance create \ The output shows the instance address and other details: - + ```ansi title="unikraft" metro: fra @@ -163,7 +163,7 @@ timestamps: This instance is short-lived, since right before the server starts, it triggers a conversion into a template. To check that the template is ready, run: - + ```bash title="unikraft" unikraft instances templates list @@ -177,7 +177,7 @@ kraft cloud instance template list
- + ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED @@ -195,7 +195,7 @@ go-build-env oci://unikraft.io//go-build-env@sha256:1cbd6474386c9df5468 Each ROM contains a Go function implementation. - + ```bash title="unikraft" unikraft build rom1/ --output /go-rom1:latest @@ -227,7 +227,7 @@ kraft pkg \ Create an instance with the first ROM: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -279,7 +279,7 @@ curl -X POST "$UKC_METRO/instances" \ The instance will compile the ROM into a plugin on first start, which may take a few seconds. To check the progress, you can view the instance logs: - + ```bash title="unikraft" unikraft instances logs go-build-env-rom1 -f @@ -293,7 +293,7 @@ kraft cloud instance logs go-build-env-rom1 -f Create another instance with the second ROM: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -345,7 +345,7 @@ curl -X POST "$UKC_METRO/instances" \ The instance will compile the ROM into a plugin on first start, which may take a few seconds. To check the progress, you can view the instance logs: - + ```bash title="unikraft" unikraft instances logs go-build-env-rom2 -f @@ -361,7 +361,7 @@ Both instances run the same base Go runtime, but execute different ROM payloads, List the instances and note their FQDN values: - + ```bash title="unikraft" unikraft instances list @@ -375,7 +375,7 @@ kraft cloud instance list
- + ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED @@ -420,7 +420,7 @@ A pre-initialized runtime used to speed up new instance startup. ## Cleanup - + ```bash title="unikraft" unikraft instances delete go-build-env-rom1 go-build-env-rom2 @@ -436,7 +436,7 @@ kraft cloud instance template remove go-build-env ## Learn more - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index e1b8a84..98a2856 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -63,7 +63,7 @@ cd examples/node-express-puppeteer/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -89,7 +89,7 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" unikraft build . --output /node-express-puppeteer:latest @@ -130,7 +130,7 @@ You can use the landing page to generate the PDF version of a remote page. At any time, you can list information about the instance: - + ```bash title="unikraft" unikraft instances list node-express-puppeteer-7afg3 @@ -149,7 +149,7 @@ node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app run When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete node-express-puppeteer-7afg3 @@ -171,7 +171,7 @@ You can update the service itself to provide a Representational State Transfer ( Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index e4db862..4d5903d 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -194,7 +194,7 @@ Unikraft Cloud's instant deployment and scale-to-zero model makes it ideal for h Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="kraft" kraft cloud --help diff --git a/pages/use-cases/remote-desktops.mdx b/pages/use-cases/remote-desktops.mdx index c263319..418bf6d 100644 --- a/pages/use-cases/remote-desktops.mdx +++ b/pages/use-cases/remote-desktops.mdx @@ -61,7 +61,7 @@ cd examples/novnc-browser/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -87,7 +87,7 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" unikraft build . --output /novnc-browser:latest @@ -109,7 +109,7 @@ kraft cloud deploy \ The output shows the instance address and other details: - + ```ansi title="unikraft" metro: fra @@ -157,7 +157,7 @@ From there, click **Connect** to open the remote desktop, which ships with Firef At any time, you can list information about the instance: - + ```bash title="unikraft" unikraft instances list @@ -169,7 +169,7 @@ kraft cloud instance list - + ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED @@ -185,7 +185,7 @@ vnc-browser weathered-fog-y5jjmwfd.fra.unikraft.app standby sta When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete vnc-browser @@ -209,7 +209,7 @@ You can also adjust the screen geometry through the `WIDTH`, `HEIGHT`, and `DISP Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index 9300ee9..5d31ee1 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -60,7 +60,7 @@ cd examples/code-server/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪). - + ```bash title="unikraft" unikraft login @@ -79,7 +79,7 @@ The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" unikraft volumes create \ @@ -119,7 +119,7 @@ This deployment creates a volume for data persistence: `code-workspace`. Upon deleting the instance, this volume will persist, allowing you to create another instance without losing data. To remove the volume, you can use: - + ```bash title="unikraft" unikraft volumes delete code-workspace @@ -135,7 +135,7 @@ kraft cloud volume rm code-workspace Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/sandboxes.mdx b/pages/use-cases/sandboxes.mdx index 8680a23..005f2ca 100644 --- a/pages/use-cases/sandboxes.mdx +++ b/pages/use-cases/sandboxes.mdx @@ -73,7 +73,7 @@ cd examples/openclaw/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -92,7 +92,7 @@ The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the When done, you may create the OpenClaw Unikraft Cloud image and deploy an instance from it like so: - + ```bash title="unikraft" unikraft build . --output /openclaw:latest @@ -116,7 +116,7 @@ Make sure to replace `` with your username / org-name and to set your SS The output shows the instance address and other details: - + ```ansi title="unikraft" metro: fra @@ -178,7 +178,7 @@ ssh -l root localhost -p 2222 You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -190,7 +190,7 @@ kraft cloud instance list - + ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED @@ -206,7 +206,7 @@ openclaw-8tosm demo/openclaw 20 seconds ago When done, you can remove the instance using: - + ```bash title="unikraft" unikraft instances delete openclaw-8tosm @@ -301,7 +301,7 @@ You now have full access to your own OpenClaw deployment on Unikraft Cloud! Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 74c0be5..12e3483 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -65,7 +65,7 @@ cd examples/postgres/ Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -146,7 +146,7 @@ You can do this by either changing the label in the `Kraftfile` or by using `--s At any time, you can list information about the instance: - + ```bash title="unikraft" unikraft instances list @@ -165,7 +165,7 @@ postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ag When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete postgres-saan9 @@ -183,7 +183,7 @@ You can use [volumes](/platform/volumes) for data persistence for your PostgreSQ For that you would first create a volume: - + ```console title="unikraft" unikraft volumes create \ @@ -200,7 +200,7 @@ kraft cloud volume create --name postgres --size 200 Then start the PostgreSQL instance and mount that volume: - + ```console title="unikraft" unikraft build . --output /postgres:latest @@ -232,7 +232,7 @@ The source instance keeps running unaffected. To create a branch, pass `--branch` with the source instance name to `unikraft run`: - + ```console title="unikraft" unikraft run --metro=fra -p 5432:5432/tls --branch ``` @@ -244,7 +244,7 @@ Whatever you do, the source instance remains unaffected. When you're done, remove the branch: - + ```console title="unikraft" unikraft instances delete ``` @@ -274,7 +274,7 @@ Support for scale-to-zero for internal instances is coming soon. Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx index 65fa470..76c07d6 100644 --- a/pages/use-cases/serverless-functions.mdx +++ b/pages/use-cases/serverless-functions.mdx @@ -60,7 +60,7 @@ cd examples/node-code-execution/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, 🇩🇪): - + ```bash title="unikraft" unikraft login @@ -80,7 +80,7 @@ export UKC_METRO=fra The base image contains a Node.js server (`server.ts`) that loads a function from the attached ROM and executes it on each HTTP request. Right before starting the server, it writes `1` to `/uk/libukp/template_instance`, which triggers Unikraft Cloud to convert the running instance into a [template](/platform/instances#instance-templates). - + ```bash title="unikraft" unikraft build . --output /node-code-exec:latest @@ -103,7 +103,7 @@ kraft pkg \ Boot a short-lived instance from the base image without any ROM attached. The instance self-converts into a template and exits: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -124,7 +124,7 @@ kraft cloud instance create \ The output shows the instance details: - + ```ansi title="unikraft" metro: fra @@ -161,7 +161,7 @@ timestamps: This instance is short-lived, since right before the server starts, it triggers a conversion into a template. To confirm the template is ready: - + ```bash title="unikraft" unikraft instances templates list @@ -175,7 +175,7 @@ kraft cloud instance template list
- + ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED @@ -195,7 +195,7 @@ node-exec oci://unikraft.io//node-code-exec@sha256:71487fd6196987cf65fb ROMs package only the function source files—no runtime needed. Package both example functions: - + ```bash title="unikraft" unikraft build rom1/ --output /node-rom1:latest @@ -230,7 +230,7 @@ New instances skip the cold-start initialization phase because they restore from Create the first instance with the JavaScript ROM attached: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -281,7 +281,7 @@ curl -X POST "$UKC_METRO/instances" \ Create the second instance with the TypeScript ROM attached: - + ```bash title="unikraft" unikraft run --metro fra \ @@ -392,7 +392,7 @@ The ROM deployment model has three layers: ## Cleanup - + ```bash title="unikraft" unikraft instances delete node-exec-rom1 node-exec-rom2 @@ -410,7 +410,7 @@ kraft cloud instance template remove node-exec Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 9223401..833c9b8 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -93,7 +93,7 @@ Also follow [Webhooks.fyi](https://webhooks.fyi/) for best practices. Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="kraft" kraft cloud --help From 54ebc1bf4db7086c100a1e8c875f8654a26fbb16 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 26 May 2026 14:04:02 +0300 Subject: [PATCH 6/8] feat(tutorials): Add kraftkit to unikraft Signed-off-by: Alex-Andrei Cioc --- pages/tutorials/kraftkit-to-unikraft.mdx | 388 +++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 389 insertions(+) create mode 100644 pages/tutorials/kraftkit-to-unikraft.mdx diff --git a/pages/tutorials/kraftkit-to-unikraft.mdx b/pages/tutorials/kraftkit-to-unikraft.mdx new file mode 100644 index 0000000..ce2c911 --- /dev/null +++ b/pages/tutorials/kraftkit-to-unikraft.mdx @@ -0,0 +1,388 @@ +--- +title: KraftKit To Unikraft +navigation_icon: book-open +--- + +This tutorial shows how to migrate from the legacy `kraft cloud` CLI to the new `unikraft` CLI for Unikraft Cloud. +It focuses on the differences that matter during day-to-day work: authentication, profiles, deployment flow, common commands, and flag behaviour. + +## Prerequisites + +Make sure you have the new CLI installed. +See the [unikraft CLI overview](/docs/cli/overview) for installation instructions. +If you still need the legacy syntax during the migration, keep the [legacy CLI overview](/docs/cli/legacy-overview) nearby for reference. + +## Main mental shift + +The biggest change is that the legacy CLI combines packaging and deployment into a single command, while the new CLI treats them as separate operations. + +In the legacy flow: + +```bash title="kraft" +kraft cloud deploy -p 443:8080/http+tls -M 512Mi --rootfs-type erofs . +``` + +the CLI reads the local project, builds the root filesystem and image if needed, pushes it, and starts an instance. + +In the new flow, the CLI splits the same work into two clearer stages: + +```bash title="unikraft" +unikraft build . --output /my-app:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512M --image=/my-app:latest +``` + +This split has two practical consequences: + +* `unikraft build` is where you package the image and store it in a registry. +* `unikraft run` is where you create an instance from an existing image and set runtime options such as ports, memory, scale-to-zero, volumes, and environment variables. + +That separation makes the deployment flow more explicit. +It also means you need to think about whether a flag belongs to image creation time or instance runtime. + +## Login and authentication + +### Public Unikraft Cloud + +For the public service, the new CLI uses an interactive login flow that opens a browser window to authenticate with the Unikraft Cloud dashboard. +The legacy CLI relies on environment variables to store the access token and metro selection. + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +The environment variables `UKC_TOKEN` and `UKC_METRO` are only supported by the legacy CLI. +They aren't the normal way to authenticate with the new CLI. + +### Profile management + +The new CLI uses profiles to manage authentication and configuration for different environments. +The `default` profile contains all the publicly available metros: + +```bash +unikraft profile list +``` +```ansi +NAME ACTIVE METROS +default true ["fra0", "dal0", "sin0", "was1", "fra", "dal", "sin", "was", "sfo"] +``` + +Thus, listing instances with `unikraft` is more convenient than with `kraft cloud`: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +export UKC_METRO=fra +kraft cloud instance list +#------------------------ +export UKC_METRO=was +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-go121-qdrlz stopped /httpserver-go121 256MiB 1 summer-star-huyfslqm.fra.unikraft.app 20 hours ago +fra httpserver-go121-bhjvm stopped /httpserver-go121 256MiB 1 restless-gorilla-dalzi9bs.fra.unikraft.app 20 hours ago +was httpserver-go121-xjsli standby /httpserver-go121 256MiB 1 bitter-bonobo-20plsjfu.was.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-go121-qdrlz summer-star-huyfslqm.fra.unikraft.app stopped /httpserver-go121@sha256:7785ebdf6c1ffaf05c3be... 256 MiB 1 90.20 ms +httpserver-go121-bhjvm restless-gorilla-dalzi9bs.fra.unikraft.app stopped /httpserver-go121@sha256:7785ebdf6c1ffaf05c3be... 256 MiB 1 89.33 ms +#------------------------- +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-go121-xjsli bitter-bonobo-20plsjfu.was.unikraft.app standby standby /httpserver-go121@sha256:7785ebdf6c1ffaf05c3be... 256 MiB 1 165.63 ms +``` + + + +Write operations require an explicit metro selection with `--metro`: + +```bash title="unikraft" +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --image=/my-app:latest +``` + +For custom or private metros, define a profile in `~/.config/unikraft/config.yaml`: + +```yaml title="config.yaml" +profiles: + : + type: cloud + token: + organization: + metros: + - name: + endpoint: https://api..unikraft.cloud + country: +``` + +Then select it explicitly: + +```bash title="unikraft" +unikraft profile use +unikraft profile list +``` + +:::tip +If you work against more than one metro or installation, create one profile per environment and switch with `unikraft profile use` instead of rewriting shell variables. +This has the advantage of persistence through configuration files. +::: + +## Translate the most common commands + +Use the following mappings as a quick migration reference. + +### Log in + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +export UKC_TOKEN= +export UKC_METRO= +``` + + + +### Select a configured environment + + + +```bash title="unikraft" +unikraft profile use +``` + +```bash title="kraft" +export UKC_TOKEN= +export UKC_METRO= +``` + + + +### Build and push an image + + + +```bash title="unikraft" +unikraft build . --output /my-app:latest +``` + +```bash title="kraft" +kraft pkg --push -p kraftcloud -m x86_64 --rootfs-type erofs --name /my-app:latest . +``` + + + +### Run an instance from an image + + + +```bash title="unikraft" +unikraft run --metro=fra -p 443:8080/http+tls -m 512M --image=/my-app:latest +``` + +```bash title="kraft" +kraft cloud vm create --start -p 443:8080/http+tls -M 512Mi /my-app:latest +``` + + + +### List instances + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +### Remove an instance + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + +### Create a volume + + + +```bash title="unikraft" +unikraft volume create --metro=fra --name=data --size=200M +``` + +```bash title="kraft" +kraft cloud volume create --name data --size 200Mi +``` + + + +## Flags differences + +### Memory units + +Memory units behave differently in the new CLI. + + + +```bash title="unikraft" +unikraft run --metro=fra -m 512M --image=/my-app:latest +``` + +```bash title="kraft" +kraft cloud deploy -M 512Mi . +``` + + + +`unikraft` only accepts units in the binary system, for example, `512M` or `512MiB` for Mebibytes. +The legacy `kraft cloud` works with the decimal system as well—so `512M` would mean 512 Megabytes, which is about 488 Mebibytes, while `512Mi` would mean 512 Mebibytes, which is about 536 Megabytes. + +### Scale-to-zero + +The new CLI folds three legacy switches into one structured flag: + + + +```bash title="unikraft" +unikraft run --metro=fra \ + --scale-to-zero policy=idle,cooldown-time=5000,stateful=true \ + --image=/my-app:latest +``` + +```bash title="kraft" +kraft cloud deploy \ + --scale-to-zero idle \ + --scale-to-zero-stateful \ + --scale-to-zero-cooldown 5s \ + . +``` + + + +Not specifying any scale-to-zero configuration means **don't scale-to-zero**. +Note that, besides `policy`, each of the options for scale-to-zero are optional. + +### Filtering and waiting + +The new CLI adds a rich filter language for many commands. +For example: + +```bash +unikraft instances list --filter 'state==running,metro==fra' +``` + +and: + +```bash +unikraft instance wait my-instance --until state==running +``` + +These `--filter` and `--until` expressions are features of the new CLI. +They aren't available in the legacy `kraft cloud` CLI. +See [Filters](/docs/cli/filters) for the full syntax. + +## A side-by-side migration example + +Suppose your old workflow looked like this: + +```bash title="kraft" +# do this once in every terminal session +export UKC_TOKEN=token +export UKC_METRO=fra + +kraft cloud deploy -n my-app -p 443:8080/http+tls -M 512Mi -e APP_ENV=production . +kraft cloud instance get my-app +kraft cloud instance logs my-app -f +kraft cloud instance remove my-app +``` + +The migrated workflow is: + +```bash title="unikraft" +unikraft build . --output /my-app:latest +unikraft run --metro=fra -n my-app -p 443:8080/http+tls -m 512M -e APP_ENV=production --image=/my-app:latest +unikraft instances get my-app +unikraft instance logs my-app -f +unikraft instances delete my-app +``` + +Note the absence of environment variable exports in the new CLI, which uses persistent profiles instead. + +## Migration checklist + +When moving an existing guide, script, or workshop from `kraft cloud` to `unikraft`, check the following: + +* Replace `kraft cloud deploy` with `unikraft build` plus `unikraft run`; +* Move the local path such as `.` to `unikraft build`; +* Add an explicit image reference with `--output` on `build` and `--image` on `run`; +* Replace legacy authentication environment variables with `unikraft login` or a configured profile; +* Move run-time flags such as memory, ports, env vars, volumes, and scale-to-zero settings to `unikraft run`; +* Translate legacy scale-to-zero flags into the structured `--scale-to-zero` syntax; +* Update instance management commands such as list and delete to the new command names; +* Take advantage of new `--filter` and `--until` flags where they simplify scripts. + +## When to keep using the legacy CLI + +The `unikraft` CLI is the recommended default for new workflows leveraging the latest features and improvements. +That said, the legacy CLI can still make sense if you depend on existing Compose-oriented flows (`kraft cloud compose`) or you need time to migrate automation gradually. + +Another reason to keep using `kraft` is for local development. +Through `kraft pkg` and `kraft run`, you can run Unikraft unikernels locally, and it remains the preferred CLI for that use case. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +For more details, check the following references: + +* The [unikraft CLI overview](/docs/cli/overview). +* The [legacy CLI overview](/docs/cli/legacy-overview). +* The [Filters](/docs/cli/filters) reference for the new filtering language. +* The [Environment Variables](/tutorials/environment-variables) tutorial for runtime configuration patterns. \ No newline at end of file diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 6650a40..52f08b8 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -220,6 +220,7 @@ const config: ZudokuConfig = { icon: "book", items: [ "/tutorials/docker-to-ukc", + "/tutorials/kraftkit-to-unikraft", "/tutorials/environment-variables", "/tutorials/rootfs-formats", "/tutorials/rootfs-compression", From 0b5754d8710f35616dc5a1b055c84e13c17042a2 Mon Sep 17 00:00:00 2001 From: Unikraft Bot Date: Wed, 27 May 2026 04:50:45 +0000 Subject: [PATCH 7/8] chore: Update guides from examples repository Signed-off-by: Unikraft Bot --- ...erver-node25.mdx => httpserver-node26.mdx} | 30 +++++++++---------- zudoku.config.tsx | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) rename pages/guides/{httpserver-node25.mdx => httpserver-node26.mdx} (89%) diff --git a/pages/guides/httpserver-node25.mdx b/pages/guides/httpserver-node26.mdx similarity index 89% rename from pages/guides/httpserver-node25.mdx rename to pages/guides/httpserver-node26.mdx index 8b2199f..f8b38a0 100644 --- a/pages/guides/httpserver-node25.mdx +++ b/pages/guides/httpserver-node26.mdx @@ -22,11 +22,11 @@ The unikraft CLI is the current standard, while kraft is the legacy version. Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. ::: -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node25` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node26` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-node25/ +cd examples/httpserver-node26/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -52,8 +52,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-node25:latest -unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-node25:latest +unikraft build . --output /httpserver-node26:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-node26:latest ``` ```bash title="kraft" @@ -68,10 +68,10 @@ The output shows the instance address and other details: ```ansi title="unikraft" metro: fra -name: httpserver-node25-v8mp4 +name: httpserver-node26-v8mp4 uuid: c3d4e5f6-a7b8-9012-cdef-123456789012 state: starting -image: /httpserver-node25 +image: /httpserver-node26 resources: memory: 512MiB vcpus: 1 @@ -91,21 +91,21 @@ timestamps: ```ansi title="kraft" [●] Deployed successfully! │ - ├───────── name: httpserver-node25-v8mp4 + ├───────── name: httpserver-node26-v8mp4 ├───────── uuid: c3d4e5f6-a7b8-9012-cdef-123456789012 ├──────── metro: https://api.fra.unikraft.cloud/v1 ├──────── state: starting ├─────── domain: https://bright-star-k3m7pqnx.fra.unikraft.app - ├──────── image: oci://unikraft.io//httpserver-node25@sha256:7b3e1f9d5a2c8e4b0f6d3a7c5e2b9f4d1a8c6e3b0f7d4a1c8e5b2f9d6a3c0 + ├──────── image: oci://unikraft.io//httpserver-node26@sha256:7b3e1f9d5a2c8e4b0f6d3a7c5e2b9f4d1a8c6e3b0f7d4a1c8e5b2f9d6a3c0 ├─────── memory: 512 MiB ├────── service: bright-star-k3m7pqnx - ├─ private fqdn: httpserver-node25-v8mp4.internal + ├─ private fqdn: httpserver-node26-v8mp4.internal └─── private ip: 10.0.3.6 ``` -In this case, the instance name is `httpserver-node25-v8mp4` and the address is `https://bright-star-k3m7pqnx.fra.unikraft.app`. +In this case, the instance name is `httpserver-node26-v8mp4` and the address is `https://bright-star-k3m7pqnx.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the Node.js HTTP server: @@ -136,12 +136,12 @@ kraft cloud instance list ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra httpserver-node25-v8mp4 running /httpserver-node25 512MiB 1 bright-star-k3m7pqnx.fra.unikraft.app 2 minutes ago +fra httpserver-node26-v8mp4 running /httpserver-node26 512MiB 1 bright-star-k3m7pqnx.fra.unikraft.app 2 minutes ago ``` ```ansi title="kraft" NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node25-v8mp4 bright-star-k3m7pqnx.fra.unikraft.app running since 3mins oci://unikraft.io//httpserver-node25@sha256:... 512 MiB 1 276.18 ms +httpserver-node26-v8mp4 bright-star-k3m7pqnx.fra.unikraft.app running since 3mins oci://unikraft.io//httpserver-node26@sha256:... 512 MiB 1 276.18 ms ``` @@ -151,11 +151,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-node25-v8mp4 +unikraft instances delete httpserver-node26-v8mp4 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-node25-v8mp4 +kraft cloud instance remove httpserver-node26-v8mp4 ``` @@ -182,7 +182,7 @@ Lines in the `Kraftfile` have the following roles: Lines in the `Dockerfile` have the following roles: -* `FROM node:25-alpine AS node`: Use the Node.js 25 Alpine image as the source for the `node` binary and libraries. +* `FROM node:26-alpine AS node`: Use the Node.js 26 Alpine image as the source for the `node` binary and libraries. * `FROM scratch`: Build the runtime filesystem from a minimal base image. diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 52f08b8..acb4fae 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -172,7 +172,7 @@ const config: ZudokuConfig = { "/guides/httpserver-node21-nextjs", // Next.js HTTP Server "/guides/nginx", // Nginx "/guides/node24-karaoke", // Node AllKaraoke - "/guides/httpserver-node25", // Node HTTP Server + "/guides/httpserver-node26", // Node HTTP Server "/guides/node21-websocket", // Node WebSocket Server "/guides/novnc-browser", // noVNC "/guides/opentelemetry-collector", // OpenTelemetry Collector From 98b89eb7d0f8a996ba454a028ab18711f095b257 Mon Sep 17 00:00:00 2001 From: Daniel Vallance Date: Wed, 27 May 2026 10:50:28 +0100 Subject: [PATCH 8/8] chore: Update overview to httpserver-node26 Signed-off-by: Daniel Vallance --- pages/guides/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/guides/overview.mdx b/pages/guides/overview.mdx index 795c6a5..178ac37 100644 --- a/pages/guides/overview.mdx +++ b/pages/guides/overview.mdx @@ -44,7 +44,7 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. ### JavaScript / TypeScript -- [Node HTTP Server](/guides/httpserver-node25) +- [Node HTTP Server](/guides/httpserver-node26) - [Bun HTTP Server](/guides/httpserver-bun) - [Express HTTP Server](/guides/httpserver-expressjs4.18-node21) - [Puppeteer HTTP Server](/guides/httpserver-node-express-puppeteer)