Workflows

Workflow examples

Ready-to-use workflows you can drop into your projects. Each one uses the public REST API; mint a token in the console (Settings -> API) and replace the placeholder values with your own.

Every snippet below assumes the token is exported as ORKESTR_TOKEN (or stored as a GitHub secret). For PR previews you also need ORKESTR_PROJECT_ID (UUID from the project URL) and ORKESTR_PROJECT_NAME (the slug).

PR deploy previews

Deploys a preview environment when a PR is opened or updated, comments the live URL on the PR, and cleans up when the PR is closed. GitHub Actions; adapts to GitLab CI or Bitbucket Pipelines with minor edits.

.github/workflows/preview.yml
# .github/workflows/preview.yml
name: Deploy Preview
on:
  pull_request:
    types: [opened, synchronize, closed]

env:
  API: https://api.orkestr.eu/api/v1
  TOKEN: ${{ secrets.ORKESTR_TOKEN }}
  PROJECT: ${{ secrets.ORKESTR_PROJECT_ID }}

jobs:
  deploy-preview:
    if: github.event.action != 'closed'
    runs-on: ubuntu-latest
    steps:
      - name: Create preview environment
        id: env
        run: |
          # Create environment (409 = already exists, that's fine)
          RESULT=$(curl -s -w "\n%{http_code}" -X POST \
            -H "Authorization: Bearer $TOKEN" \
            -H "Content-Type: application/json" \
            -d '{"name":"pr-${{ github.event.number }}","branch":"${{ github.head_ref }}","auto_deploy":true}' \
            $API/projects/$PROJECT/environments)

          # Get the environment ID
          ENV_ID=$(curl -s \
            -H "Authorization: Bearer $TOKEN" \
            $API/projects/$PROJECT/environments \
            | jq -r '.[] | select(.name=="pr-${{ github.event.number }}") | .id')
          echo "env_id=$ENV_ID" >> $GITHUB_OUTPUT

      - name: Trigger deployment
        run: |
          curl -s -X POST \
            -H "Authorization: Bearer $TOKEN" \
            "$API/projects/$PROJECT/deployments?environment_id=${{ steps.env.outputs.env_id }}"

      - name: Comment preview URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              owner: context.repo.owner, repo: context.repo.repo,
              issue_number: context.issue.number,
              body: '🚀 **Preview deployed!**\n\nhttps://pr-${{ github.event.number }}-${{ secrets.ORKESTR_PROJECT_NAME }}.orkestr.run'
            })

  cleanup-preview:
    if: github.event.action == 'closed'
    runs-on: ubuntu-latest
    steps:
      - name: Get environment ID and delete
        run: |
          ENV_ID=$(curl -s \
            -H "Authorization: Bearer $TOKEN" \
            $API/projects/$PROJECT/environments \
            | jq -r '.[] | select(.name=="pr-${{ github.event.number }}") | .id')
          if [ -n "$ENV_ID" ]; then
            curl -s -X DELETE \
              -H "Authorization: Bearer $TOKEN" \
              $API/projects/$PROJECT/environments/$ENV_ID
          fi

Test + deploy on push to main

Runs your test suite first, then triggers an orkestr deployment only if tests pass. Polls until the deployment completes and fails the workflow if the deploy fails - so a failed deploy turns the commit status red just like a failed test would.

.github/workflows/deploy.yml
# .github/workflows/deploy.yml
name: Test & Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Trigger deployment
        id: deploy
        run: |
          DEPLOY=$(curl -s -X POST \
            -H "Authorization: Bearer ${{ secrets.ORKESTR_TOKEN }}" \
            https://api.orkestr.eu/api/v1/projects/${{ secrets.ORKESTR_PROJECT_ID }}/deployments)
          echo "id=$(echo $DEPLOY | jq -r '.id')" >> $GITHUB_OUTPUT
          echo "Deploy triggered: $(echo $DEPLOY | jq -r '.id')"

      - name: Wait for deployment
        run: |
          for i in $(seq 1 60); do
            STATUS=$(curl -s \
              -H "Authorization: Bearer ${{ secrets.ORKESTR_TOKEN }}" \
              https://api.orkestr.eu/api/v1/deployments/${{ steps.deploy.outputs.id }} \
              | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in
              live) echo "Deployed!"; exit 0 ;;
              failed) echo "Deploy failed"; exit 1 ;;
            esac
            sleep 5
          done
          echo "Timeout"; exit 1

Auto-rollback on alert

Wire this script into your uptime monitor's webhook (UptimeRobot, Betterstack, Pingdom, your own healthcheck). When your site goes down, it finds the last successful deployment and rolls back automatically. Pairs well with rate-limit retries in your monitor so a flapping endpoint doesn't trigger needless rollbacks.

auto-rollback.sh
#!/bin/bash
# auto-rollback.sh - triggered by uptime monitor webhook

API="https://api.orkestr.eu/api/v1"
TOKEN="ork_your_token"
PROJECT="your-project-id"

# Find the last successful deployment
LAST_GOOD=$(curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "$API/projects/$PROJECT/deployments?limit=10" \
  | jq -r '[.deployments[] | select(.status=="superseded" and .docker_image!=null)] | first | .id')

if [ "$LAST_GOOD" != "null" ] && [ -n "$LAST_GOOD" ]; then
  echo "Rolling back to deployment $LAST_GOOD"
  curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    "$API/deployments/$LAST_GOOD/rollback"
  echo "Rollback triggered"
else
  echo "No previous deployment to rollback to"
fi

Batch operations across projects

Loop through all your projects to update env vars, trigger deploys, or collect stats. Useful for agencies managing multiple client apps or teams with shared configuration.

batch-update.sh
#!/bin/bash
# batch-update.sh - update an env var across all projects

API="https://api.orkestr.eu/api/v1"
TOKEN="ork_your_token"

# Get all project IDs
PROJECTS=$(curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "$API/projects" \
  | jq -r '.projects[].id')

# Update env vars and redeploy each project
for id in $PROJECTS; do
  echo "Updating project $id..."

  # Set new env var
  curl -s -X PATCH \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"env_vars":{"APP_VERSION":"2.1.0","UPDATED_AT":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}}' \
    "$API/projects/$id"

  # Trigger redeploy
  curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    "$API/projects/$id/deployments"

  echo "Done. Deployment queued."
done

echo "All projects updated and deploying."

AI assistant via MCP

Connect the MCP server to Claude Code, Cursor, or Claude Desktop and manage your entire infrastructure conversationally. No scripts, no dashboards - just tell your AI assistant what you need.

You
create a staging environment for my-api on the develop branch
Claude
Created environment staging for my-api on branch develop.
Auto-deploy is enabled - pushes to develop will deploy automatically.
URL: my-api-staging.orkestr.run
You
add a postgres database and deploy it
Claude
Provisioned PostgreSQL 16 add-on for my-api.
Connection string injected as DATABASE_URL.
Deployment triggered - build started.
You
how's the CPU looking after the deploy?
Claude
Container stats for my-api (production):
CPU: 12.4% of 0.5 vCPU - Memory: 187 MB / 512 MB
Network: 2.1 MB in / 890 KB out - Uptime: 4 minutes
Looks healthy. Well within resource limits.

Next steps

  • REST API - every endpoint these workflows touch
  • CLI - many of the curl invocations above have a higher-level CLI equivalent
  • MCP server - if scripting feels like overkill, let an LLM drive
  • Sandboxes - new EU-native sandbox runtime for AI agents