Zaroz
Deploy from CI/CD

Deploy from Forgejo and Gitea Actions

Forgejo and Gitea Actions read GitHub-style workflow files. The differences that matter here: the workflow lives in .forgejo/workflows/ (Gitea: .gitea/workflows/), the runner needs Docker, and the image goes to your instance's package registry, not GHCR.

Prerequisites: a runner with the label used in runs-on and access to a Docker daemon, a running Workload, its service instance id, the deploy token, and zaroz-deploy.sh as deploy/zaroz-deploy.sh.

Secrets and variables

In the repository (or organization) Settings > Actions:

NameKindValue
ZAROZ_TOKENsecretthe zaroz_... deploy token
ZAROZ_SERVICEvariablethe service instance UUID
REGISTRY_HOSTvariableyour instance host, for example git.example.com
REGISTRY_USERNAMEvariablethe account that owns the packages
REGISTRY_PASSWORDsecretan access token with write:package (pushes)
REGISTRY_PULL_TOKENsecretfor a private package: an access token with read:package only. Zaroz uses this one to pull

The workflow

YAMLCode
# .forgejo/workflows/deploy.yml (Gitea Actions reads .gitea/workflows/ instead; same file) name: deploy on: push: branches: [main] concurrency: group: deploy-production cancel-in-progress: false jobs: deploy: runs-on: docker steps: - uses: actions/checkout@v4 - name: Install tools run: apt-get update -qq && apt-get install -y -qq curl jq - name: Build and push id: build env: REGISTRY: ${{ vars.REGISTRY_HOST }} # git.example.com REGISTRY_USERNAME: ${{ vars.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} # package write token run: | IMAGE="$REGISTRY/${GITHUB_REPOSITORY,,}:$(echo "$GITHUB_SHA" | cut -c1-12)" echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY" -u "$REGISTRY_USERNAME" --password-stdin docker build -t "$IMAGE" . docker push "$IMAGE" echo "image=$IMAGE" >> "$GITHUB_OUTPUT" - name: Deploy to Zaroz run: sh deploy/zaroz-deploy.sh env: IMAGE: ${{ steps.build.outputs.image }} ZAROZ_TOKEN: ${{ secrets.ZAROZ_TOKEN }} ZAROZ_SERVICE: ${{ vars.ZAROZ_SERVICE }} # A private package needs a pull-only token, separate from the push one: REGISTRY_USERNAME: ${{ vars.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PULL_TOKEN }}

How it behaves:

  • The image is <host>/<owner>/<repo>:<12-char sha>. A package is private by default; make it public to deploy without a pull token.
  • concurrency queues pushes, as in the other guides.
  • Zaroz pulls from inside its cluster, so the instance must be reachable from the internet over HTTPS with a valid certificate.
  • If your runner has no docker binary, build with Kaniko or Buildah in a job container instead; only the Build and push step changes.

Roll back

Re-run the workflow for an older commit from the Actions tab, or run the script yourself with IMAGE=<host>/<owner>/<repo>:<old sha>.

Last modified on