Skip to content

GitHub Actions

In this short guide we’ll cover how to use Github Actions to easily build and deploy services onto Unikraft Cloud (UKC).

Basic Usage

In the following example, we assume that you have a repository that has a Kraftfile with a target of kraftcloud/x86_64, like any of the sub-directories in the examples repo. This example will make sure that the repo will be built every time a PR is opened, synchronized or re-opened:

name: example1
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
steps:
- uses: actions/checkout@v3
- uses: unikraft/kraftkit@stable
with:
workdir: .
kraftfile: Kraftfile
arch: x86_64
plat: kraftcloud
push: true
output: oci://index.unikraft.io/${{ secrets.UKC_USER }}/app:latest

Packaging and Publishing Images

The GitHub action, packages the resulting image in OCI Image format. This allows you to distribute the image using conventional OCI Image Registries, such as the one provided by GitHub (GHCR). This image format is also recognized by kraft. To publish and deploy your image, you must first login to the registry and then specify the canonical name via output: oci://... and indicate that you wish to push the image. Finally, execute kraft cloud subcommands using the after directive:

name: example3
on:
pull_request:
types: [opened, synchronize, reopened]
env:
UKC_TOKEN: ${{ secrets.UKC_TOKEN }}
UKC_METRO: dal0
jobs:
build:
steps:
- uses: actions/checkout@v4
- uses: unikraft/kraftkit@stable
with:
workdir: .
kraftfile: Kraftfile
arch: x86_64
plat: kraftcloud
output: oci://index.unikraft.io/${{ secrets.UKC_USER }}/app:latest
push: true
after: |
kraft cloud deploy -p 443:8080 ${{ secrets.UKC_USER }}/app:latest

Rolling Out New Images

You may want to redeploy a new version of your app to the same service, but with a different tag. To do this you need to use the --rollout flag with the remove option and also specify a service. You will also need to ensure that the service exists beforehand. For more information on performing rollouts please refer to this guide.

name: example4
on:
pull_request:
types: [opened, synchronize, reopened]
env:
UKC_TOKEN: ${{ secrets.UKC_TOKEN }}
UKC_METRO: dal0
jobs:
build:
steps:
- uses: actions/checkout@v4
- uses: unikraft/kraftkit@stable
with:
workdir: .
kraftfile: Kraftfile
arch: x86_64
plat: kraftcloud
output: oci://index.unikraft.io/${{ secrets.UKC_USER }}/app:latest
push: true
after: |
kraft cloud service create --domain ${{ secrets.MY_DOMAIN }} --name app-group 443:8080/http+tls || true;
kraft cloud deploy --rollout remove --service app-group ${{ secrets.UKC_USER }}/app:latest

Tracking Deployment Status

You can track the status of the deployment with the chrnorm/deployment-status action. You will have to first instantiate the action and then update the status after the deployment is complete:

name: example4
on:
pull_request:
types: [opened, synchronize, reopened]
env:
UKC_TOKEN: ${{ secrets.UKC_TOKEN }}
UKC_METRO: dal0
jobs:
build:
steps:
- uses: actions/checkout@v4
- uses: chrnorm/deployment-action@v2
name: Create GitHub deployment
id: deploy-github
with:
token: '${{ github.token }}'
environment-url: 'https://example.com'
environment: 'production'
- uses: unikraft/kraftkit@stable
id: deploy-my-app
with:
workdir: .
kraftfile: Kraftfile
arch: x86_64
plat: kraftcloud
output: oci://index.unikraft.io/${{ secrets.UKC_USER }}/app:latest
push: true
after: |
kraft cloud service create --domain ${{ secrets.MY_DOMAIN }} --name app-group 443:8080/http+tls || true;
kraft cloud deploy --rollout remove --service app-group ${{ secrets.UKC_USER }}/app:latest
- name: Update deployment status (success)
if: ${{ steps.deploy-my-app.outcome == 'success' }}
uses: chrnorm/deployment-status@v2
with:
token: '${{ github.token }}'
environment-url: 'https://example.com'
deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}'
state: 'success'
- name: Update deployment status (failure)
if: ${{ steps.deploy-my-app.outcome == 'failure' }}
uses: chrnorm/deployment-status@v2
with:
token: '${{ github.token }}'
environment-url: 'https://example.com'
deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}'
state: 'failure'

That’s all. With this in place you should be able to automatically go from changes to a repo to building new images and deploying them on Unikraft Cloud, all via Github Actions.