Back to DocumentationApp Deployment

Auto-Deploy Your App From GitHub Actions

Trigger NoobHost deployments from GitHub Actions, including how to reuse the same App ID for in-place redeploys.

April 25, 202633 views

Auto-Deploy Your App From GitHub Actions

You can have GitHub deploy to NoobHost automatically every time you push to your repository. GitHub Actions sends a secure request to NoobHost, and NoobHost deploys the latest commit to your app server.

Before you start

You will need:

  • A NoobHost App Server in the active state
  • Your Server ID from the server details page
  • A NoobHost API token with the deployments:write scope
  • For private repositories, a GitHub token with read access to the repository
  • Optional: an App ID if you want to redeploy an existing app in place

Server ID vs App ID

These two IDs do different jobs:

  • Server ID tells NoobHost which app server should run the deployment
  • App ID tells NoobHost which existing app should be replaced

Use them like this:

  • Leave App ID empty if you want to create a brand-new app on that server
  • Set App ID if you want GitHub Actions to redeploy over an existing app without using another app slot

You can copy the App ID from:

Dashboard > Deployments > open your app > Identifiers card

The App ID stays the same across redeploys. The Deployment ID changes every time you start a new deploy, retry, or rollback.

Add these GitHub Actions secrets

In your GitHub repository, go to:

Settings > Secrets and variables > Actions

Add these secrets:

SecretRequiredWhat it is
NOOBHOST_API_TOKENYesYour NoobHost API token
NOOBHOST_SERVER_IDYesThe UUID of your app server
NOOBHOST_APP_IDOptionalThe UUID of an existing app to redeploy in place
NOOBHOST_GIT_TOKENPrivate repos onlyA GitHub token with read access to the repo

Example workflow

Create .github/workflows/deploy.yml:

name: Deploy to NoobHost

on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: noobhost-deploy-${{ github.ref }}
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger NoobHost deployment
        env:
          NOOBHOST_API_TOKEN: ${{ secrets.NOOBHOST_API_TOKEN }}
          NOOBHOST_SERVER_ID: ${{ secrets.NOOBHOST_SERVER_ID }}
          # Set this only if you want to redeploy an existing app in place.
          NOOBHOST_APP_ID: ${{ secrets.NOOBHOST_APP_ID }}
          # Only needed for private repositories.
          NOOBHOST_GIT_TOKEN: ${{ secrets.NOOBHOST_GIT_TOKEN }}
        run: |
          set -euo pipefail

          payload=$(jq -nc \
            --arg vpsId   "$NOOBHOST_SERVER_ID" \
            --arg appId   "${NOOBHOST_APP_ID:-}" \
            --arg gitRepo "https://github.com/${GITHUB_REPOSITORY}.git" \
            --arg branch  "${GITHUB_REF_NAME}" \
            --arg sha     "${GITHUB_SHA}" \
            --arg appName "${GITHUB_REPOSITORY##*/}" \
            --arg token   "${NOOBHOST_GIT_TOKEN:-}" \
            '{
              vpsId: $vpsId,
              gitRepo: $gitRepo,
              gitBranch: $branch,
              commitHash: $sha,
              appName: $appName
            }
            + (if $appId == "" then {} else { appId: $appId } end)
            + (if $token == "" then {} else { gitToken: $token } end)')

          echo "Triggering NoobHost deploy for ${GITHUB_REPOSITORY}@${GITHUB_SHA}"

          http_status=$(curl -sS -o response.json -w "%{http_code}" -X POST \
            -H "Authorization: Bearer ${NOOBHOST_API_TOKEN}" \
            -H "Content-Type: application/json" \
            -d "$payload" \
            https://noobhost.com/api/v1/deployments)

          echo "HTTP $http_status"
          cat response.json
          echo

          if [ "$http_status" -lt 200 ] || [ "$http_status" -ge 300 ]; then
            echo "Deployment trigger failed"
            exit 1
          fi

          deployment_id=$(jq -r '.id' response.json)
          echo "Deployment created: $deployment_id"

Optional: wait for the deployment to finish

If you want the workflow to fail when the deployment fails, add a follow-up step:

      - name: Wait for deployment
        env:
          NOOBHOST_API_TOKEN: ${{ secrets.NOOBHOST_API_TOKEN }}
          DEPLOYMENT_ID: ${{ steps.deploy.outputs.deployment_id }}
        run: |
          set -euo pipefail
          for i in $(seq 1 60); do
            status=$(curl -fsS \
              -H "Authorization: Bearer ${NOOBHOST_API_TOKEN}" \
              "https://noobhost.com/api/v1/deployments/${DEPLOYMENT_ID}" \
              | jq -r '.status')
            echo "[$i] status=$status"
            case "$status" in
              active) echo "Deployment finished"; exit 0 ;;
              failed|rolled_back) echo "Deployment failed"; exit 1 ;;
              *) sleep 10 ;;
            esac
          done
          echo "Timed out after 10 minutes"
          exit 1

Common errors

401 Unauthorized

Your API token is invalid or missing the deployments:write scope.

403 Forbidden

The Server ID does not belong to the account that owns the token.

403 Container limit reached

You are trying to create a new app on a server that is already at its plan limit. If you meant to replace an existing app, set NOOBHOST_APP_ID to that app's App ID.

Could not read from remote repository

For private repos, make sure NOOBHOST_GIT_TOKEN is set and has read access to the repository.

One-line API example

If you want to trigger a deployment from any CI system, you can call the API directly:

curl -X POST https://noobhost.com/api/v1/deployments \
  -H "Authorization: Bearer $NOOBHOST_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "vpsId": "YOUR_SERVER_ID",
    "appId": "YOUR_APP_ID",
    "gitRepo": "https://github.com/you/your-repo.git",
    "gitBranch": "main"
  }'

Leave appId out if you want NoobHost to create a new app instead of replacing an existing one.

githubgithub-actionsci-cdapp-deploymentdeployments