Continuous deployment #
On Kuzzle PaaS, you release and deploy a project from the console, in the view of an environment. The console orchestrates and observes; your GitHub repository keeps building:
- Release. The console runs the
release.ymlworkflow of your repository on the environment's release branch.semantic-releasecomputes the version, tags it and creates the GitHub Release. Nothing is built at this stage. - Deploy. You pick a release and an environment. The console runs your
build.ymlworkflow with that version and environment: it builds one image per application, with the configuration of that environment, and pushes it to the project registry (Harbor), tagged with the version. - Apply and observe. When the build has succeeded, the console applies the images through ArgoCD — the Kuzzle backend first, then the other applications — and follows the rollout until the environment is healthy, or reports what failed. A deployment can be rolled back to the images it replaced.
Your workflows no longer deploy anything, and no deployment credential is stored in your repository: the build only pushes images.
You keep full control of your build, of your application configuration and of your application secrets, per environment, in your repository. The console only provides the platform settings it is the authority on (registry, backend address, platform credentials).
This guide describes what a project needs for this flow. The API behind it is documented in Releases and Deployments.
Who can release and deploy #
Any member of the organization attached to the project can cut a release, deploy it and roll it back; owners and admins can on every project of the organization. An external collaborator sees releases and deployments but cannot start one. See Authorization.
What protects production is the repository: when an environment has the prod tier, the console protects its release branch so that changes only reach it through a pull request.
Set up a project #
These steps are done once, by an organization owner or admin, from the console or through the API.
- Connect the project to its GitHub repository, created from a template or attached —
organization:connectGithubRepository. The console sets the repository variablesKUZZLE_PAAS_REGISTRY(registry host) andKUZZLE_PAAS_PROJECT(registry project). - For each environment:
- Map its release branch —
org-environment:provisionReleaseBranch. The branch must be a release branch of yoursemantic-releaseconfiguration; one branch can serve several environments. - Set its tier (
uat,stagingorprod) —org-environment:setTier. - Configure its GitHub Environment —
org-environment:configureGithubEnvironment. It is named after the console environment. - Generate its deployment credentials —
org-environment:generateGithubDeploymentCredentials. Run it again at any time to rotate them.
- Map its release branch —
- Check that every application to deploy is deployable: Kuzzle backends and web applications always are; a
customapplication only when it is marked as deployable.
What the console sets on your repository #
| Name | Kind | Scope | Set by | Use |
|---|---|---|---|---|
KUZZLE_PAAS_REGISTRY | variable | repository | repository connection | Registry host to push images to. |
KUZZLE_PAAS_PROJECT | variable | repository | repository connection | Registry project to push images to. |
KUZZLE_PAAS_ENVIRONMENT | variable | environment | GitHub Environment configuration | The console environment name. |
PAAS_REGISTRY_USERNAME, PAAS_REGISTRY_PASSWORD | secrets | environment | deployment credentials | Registry robot account of the environment, to push images. |
PAAS_ROBOT_USERNAME, PAAS_ROBOT_APIKEY | secrets | repository | deployment credentials | Scoped API key, to install private Kuzzle npm packages. |
VUE_APP_BACKEND_HOST, VUE_APP_BACKEND_PROTO, VUE_APP_BACKEND_PORT, VUE_APP_BACKEND_SSL | variables | environment | every deployment | Address of the environment's Kuzzle backend, for the web application build. |
Everything else your build needs — the token semantic-release pushes with, your application secrets — stays yours to manage in the repository.
The release.yml workflow #
The console dispatches .github/workflows/release.yml on the release branch of the environment. The workflow must:
- be triggerable by
workflow_dispatch, with aconsole_dispatch_idinput; - include
console_dispatch_idin its run name: the console finds the run it started by this id; - run
semantic-release, which creates the Git tag and the GitHub Release. The console reads the version from the GitHub Release created during the run; whensemantic-releasefinds nothing to release, the release ends asno-release.
On a prod release branch, direct pushes are refused except for the platform's release bot GitHub App: semantic-release must push its version commit with that App's token.
name: Release
run-name: Release ${{ inputs.console_dispatch_id }}
on:
workflow_dispatch:
inputs:
console_dispatch_id:
description: Correlation id set by the Kuzzle PaaS console
required: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ... install, then run semantic-releaseThe build.yml workflow #
To deploy a release, the console dispatches .github/workflows/build.yml, on the release branch of the environment, with three inputs:
| Input | Value |
|---|---|
release_tag | The release version, which is also its Git tag (for example v1.4.0). |
environment | The console environment name. |
console_dispatch_id | Correlation id: include it in the run name. |
The workflow must:
declare
environment: ${{ inputs.environment }}on its jobs, to read the variables and secrets of that GitHub Environment;check out the release tag (
inputs.release_tag), not the branch head. A fix to the workflow itself therefore only takes effect from the next release;build one image per deployable application, with the configuration of
inputs.environment, and push it to${KUZZLE_PAAS_REGISTRY}/${KUZZLE_PAAS_PROJECT}/<environment>/<application id>:<release tag>where
<application id>is the_idof the application in the console (for exampleapi). This is the exact path the console applies: an image pushed elsewhere makes the deployment fail withTag <version> does not exist for image <path>;log in to the registry with
PAAS_REGISTRY_USERNAME/PAAS_REGISTRY_PASSWORD;not deploy: the console applies the images once the run has succeeded.
name: Build
run-name: Build ${{ inputs.release_tag }} for ${{ inputs.environment }} ${{ inputs.console_dispatch_id }}
on:
workflow_dispatch:
inputs:
release_tag:
required: true
environment:
required: true
console_dispatch_id:
required: false
jobs:
api:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.release_tag }}
- uses: docker/login-action@v3
with:
registry: ${{ vars.KUZZLE_PAAS_REGISTRY }}
username: ${{ secrets.PAAS_REGISTRY_USERNAME }}
password: ${{ secrets.PAAS_REGISTRY_PASSWORD }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ vars.KUZZLE_PAAS_REGISTRY }}/${{ vars.KUZZLE_PAAS_PROJECT }}/${{ inputs.environment }}/api:${{ inputs.release_tag }}
# one job per deployable application (web application, deployable custom applications...)Private npm packages in the build #
To install licensed @kuzzleio packages, authenticate npm to the private registry with the PAAS_ROBOT_* repository secrets. The API key goes into _password, base64-encoded — an API key set as _authToken is refused:
cat > .npmrc <<EOF
@kuzzleio:registry=https://packages.paas.kuzzle.io/
//packages.paas.kuzzle.io/:username=${PAAS_ROBOT_USERNAME}
//packages.paas.kuzzle.io/:_password=$(printf '%s' "${PAAS_ROBOT_APIKEY}" | base64 | tr -d '\n')
EOFkuzzleio/paas-action is no longer needed in this flow: it deployed images in the previous model, and the console now does.
Release and deploy from a script #
The console view is the usual entry point, but the same actions can be called with a user's credentials, for example with Kourou:
# Cut a release from the branch of the `production` environment
kourou org-release:create -a organizationId=paas-org-my-company -a projectId=my-project -a environmentId=production
# Poll it until `version` is set and `outcome` is `released`
kourou org-release:refresh -a organizationId=paas-org-my-company -a projectId=my-project -a releaseId=<release-id>
# Deploy it, then poll until `status` is `succeeded` (or `failed`)
kourou org-deployment:create -a organizationId=paas-org-my-company -a projectId=my-project -a environmentId=production -a releaseId=<release-id>
kourou org-deployment:refresh -a organizationId=paas-org-my-company -a projectId=my-project -a deploymentId=<deployment-id>
# Roll back if needed
kourou org-deployment:rollback -a organizationId=paas-org-my-company -a projectId=my-project -a deploymentId=<deployment-id>The scoped API keys stored in PAAS_ROBOT_APIKEY only give access to the private package registry: they cannot release or deploy.
Projects still on paas-action #
Projects whose CI still deploys with kuzzleio/paas-action@<=1.2.2 keep working through a deprecated compatibility bridge, which will be removed once the last of them has moved to this flow.