XAXA Server control panel

Sites

Git Deploy

Deploy a site straight from Git under the site's Deploy tab — manually or automatically on every push.

Set up

  1. Enter the repository URL (SSH git@github.com:acme/app.git or HTTPS) and the branch.
  2. For private repositories click Generate deploy key and add the public key to your repository as a read-only deploy key.
  3. Adjust the deploy script if needed and save.

What a deployment does

As the site user, in ~/htdocs/<domain> (with atomic deployments: in a new release folder, see below):

  1. Fetches the branch and checks it out (git checkout -f), so the folder always matches the repository.
  2. Runs your deploy script with bash — it stops at the first failing command.
  3. Restarts the running Node.js/Python instances; stopped instances stay stopped. If a health check path is set, every running instance must answer it (status below 500); otherwise the deployment fails.

Node.js/Python deploy scripts run in the configured Application directory, with .env followed by .env.build. Runtime uses .env followed by .env.runtime and then Service overrides. See Node.js apps for package managers and environment syntax.

Every run is recorded with its status, commit, duration and full log. Runs older than 90 days are removed, but the last 50 of each site are always kept. Deployments time out after 15 minutes. While a deployment is waiting in the queue, further pushes do not add another one: the waiting run fetches the latest commit.

Default scripts by site type:

Type Script
PHP composer install if there is a composer.json, then php artisan migrate --force and php artisan optimize for Laravel, then npm ci and npm run build if there is a package.json
Node.js detects the package manager/pin and lockfile, installs build dependencies and runs the build script if present
Python create .venv and pip install -r requirements.txt
Static npm ci and npm run build if there is a package.json

A failed step (for example a migration) fails the deployment. If you saved a deploy script before this behavior was introduced, check it for a && b chains: with bash -e, a failure in the middle of such a chain is ignored — use separate lines or if … then … fi.

Atomic deployments

Turn on Atomic deployments to build every deployment in its own folder and switch the site only when the script succeeded. A failed composer install or build never reaches visitors, and the site never serves a half-updated folder.

  • The commit is exported to ~/releases/<time> (from a cached clone in ~/.xaxa/repo) and the deploy script runs there.
  • Shared paths (one per line, for example .env, storage, public/uploads) live in ~/shared and are linked into every release. On the first deploy they are copied from the current site folder. Put everything the app writes at runtime here. Paths cannot contain one another: use storage, not both storage and storage/app/public.
  • Existing saved Shared paths lists are not expanded automatically. For Node.js/Python add .env, .env.build and .env.runtime for the files you use, prefixed by the application directory if configured (for example apps/web/.env). This keeps environment files outside Git across releases.
  • When the script succeeds, htdocs/<domain> becomes a link to the new release, switched in one step. nginx resolves the link per request, so PHP and OPcache see the new code at once.
  • The newest 3 releases are kept. The previous live release is also protected from cleanup so a failed startup can roll back, even after intervening failed builds. The folder that existed before the first atomic deployment is moved to ~/releases/initial-<time> and never deleted automatically: remove it when you no longer need it.

Node.js/Python services restart during activation; instances you stopped stay stopped, and a partly stopped app is not health-checked through nginx. This can briefly interrupt requests. A failed HTTP health check attempts to switch back to the previous release and restart it. This is a file release rollback; database migrations are not undone.

Redeploy this commit works the same way: it builds a new release from the older commit. Database migrations are not rolled back. Backups include ~/releases and ~/shared; clones copy the shared files of the live release.

Push to deploy

Copy the webhook URL into your Git provider (GitHub: Settings → Webhooks, content type application/json, event push). Pushes to other branches are ignored, and so are other events (the ping GitHub sends when the hook is added, tag pushes on GitLab).

For GitHub, set the webhook secret to the token at the end of the URL; XAXA then also checks the X-Hub-Signature-256 signature. Use Regenerate if the URL leaks.

Failed deploy alerts

When a deploy fails, the admins and the account that started it get an alert (email, and the alert webhook as event deploy). It names the site, repository and branch, the commit, who or what started it (panel, API, webhook push, redeploy), how long it ran, whether the site most likely still serves the previous release (atomic) or may be half updated (in place), the last 20 lines of the deploy log and a link to the deployments. The first successful deploy after a failed one sends a "works again" alert; successful deploys otherwise send nothing.

The log lines are sent as they are: keep secrets out of your build output, since they would reach the inbox and the chat channel of the webhook.

Found a mistake or need help? support@xaxa.com.tr