DevelopersDeployments and variables

Deployments, variables and logs

Examples use the hw helper and $API from the quick start, and $APP is an application uuid.

Environment variables#

Variables reach your app as environment variables at runtime, and at build time unless you turn that off.

CallWhat it does
GET /applications/{uuid}/envsList them. Values are null unless the token has Read sensitive data.
PATCH /applications/{uuid}/envs/bulkCreate or update several at once: {"data": [{"key", "value"}, …]}
POST /applications/{uuid}/envsCreate one (409 if the key exists)
PATCH /applications/{uuid}/envsUpdate one by key
DELETE /applications/{uuid}/envs/{env_uuid}Delete one
hw -X PATCH $API/applications/$APP/envs/bulk -d '{"data": [
  {"key": "LOG_LEVEL", "value": "info"},
  {"key": "STRIPE_KEY", "value": "sk_live_…", "is_shown_once": true},
  {"key": "GREETING", "value": "Hello $USER", "is_literal": true}
]}'
  • is_shown_once: the value can never be read back, in the console or the API.
  • is_literal: $NAMES inside the value are kept as text instead of being expanded.
  • is_multiline: for values such as PEM keys.
  • is_buildtime / is_runtime: when the variable is available (both by default).

Shared variables are set once and used by many apps: {{team.KEY}}, {{project.KEY}} or {{environment.KEY}} in an app variable's value. Manage them with /team/envs, /projects/{uuid}/envs and /projects/{uuid}/environments/{env}/envs.

Running containers keep the variables they started with. Deploy the app (below) after changing them.

Deploying#

hw -X POST $API/applications/$APP/start            # build and start
hw -X POST "$API/applications/$APP/start?force=true" # rebuild without the build cache
hw -X POST $API/applications/$APP/restart          # restart without rebuilding
hw -X POST $API/applications/$APP/stop             # take it offline

start answers {"message": "Deployment request queued.", "deployment_uuid": "…"}. A deployment moves through queued → in_progress → finished, or ends as failed or cancelled-by-user. If a build fails, the previous version keeps running. With a health check turned on (health_check_enabled, health_check_path), a new version only takes over once it answers.

CallWhat it does
GET /deployments/{uuid}Status of one deployment, with its build log in logs
GET /deployments/applications/{uuid}?skip=0&take=10An app's deployments, newest first: {count, deployments}
GET /deploymentsDeployments queued or running right now, across the team
POST /deployments/{uuid}/cancelCancel a queued or running deployment
POST /deploy?uuid=a,b or ?tag=webDeploy several apps at once, by uuid or tag

The SDK has deployAndWait(appUuid) and deployments.wait(deploymentUuid), which poll for you and throw with the end of the build log when a deployment fails.

Logs#

Build logs are part of the deployment. logs is a JSON-encoded list of lines; lines marked hidden are internal build commands:

hw $API/deployments/$DEPLOYMENT | jq -r '.logs | fromjson | map(select(.hidden | not) | .output) | .[-50:][]'

Runtime logs are the running container's output (needs Read sensitive data):

hw "$API/applications/$APP/logs?lines=200&show_timestamps=true" | jq -r .logs

A stopped app answers 400 Application is not running. For CPU and memory over time, use GET /applications/{uuid}/metrics?minutes=60.

Rolling back#

hw $API/applications/$APP/rollback-images | jq        # images you can go back to
hw -X POST $API/applications/$APP/rollback -d '{"tag": "<image tag>"}'

A rollback redeploys an earlier image without building it again.

Push deploys#

To deploy on every git push, use one of these:

  • GitHub App (recommended for GitHub): connect it in the console under Sources, then create apps from its repositories (POST /applications/private-github-app). Pushes to the app's branch deploy automatically; no webhook to set up.
  • Repository webhook (any public or deploy-key repository on GitHub, GitLab, Bitbucket or Gitea): set a secret on the app, then add a webhook in your repository.
SECRET=$(openssl rand -hex 24)
hw -X PATCH $API/applications/$APP -d "{\"manual_webhook_secret_github\": \"$SECRET\"}"

In GitHub, open Settings → Webhooks → Add webhook on the repository:

FieldValue
Payload URLhttps://console.app.hostwolf.net/webhooks/source/github/events/manual
Content typeapplication/json
Secretthe $SECRET above
EventsJust the push event

For the other hosts, use manual_webhook_secret_gitlab, _bitbucket or _gitea and the matching /webhooks/source/<host>/events/manual URL. The app's Webhooks tab in the console shows the URLs too. Secrets need at least 16 characters. Only pushes to the app's git_branch deploy it; watch_paths (e.g. "src/**") limits deploys to changes in those paths.

Deploy from CI#

Call the deploy endpoint after your tests pass. A token with only the Deploy and Read permissions is enough:

curl -fsS -X POST "https://console.app.hostwolf.net/api/v1/deploy?uuid=$APP_UUID" \
  -H "Authorization: Bearer $HOSTWOLF_APPS_TOKEN"

In GitHub Actions, store the token as a repository secret:

# .github/workflows/deploy.yml
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to Hostwolf Apps
        run: |
          curl -fsS -X POST "https://console.app.hostwolf.net/api/v1/deploy?uuid=${{ vars.HOSTWOLF_APP }}" \
            -H "Authorization: Bearer ${{ secrets.HOSTWOLF_APPS_TOKEN }}"

To deploy an image your pipeline already built, create the app from that image (POST /applications/dockerimage) and pass docker_tag to /deploy.

Stuck, or missing an endpoint? Tell us at app.hostwolf.net/contact or [email protected].