XAXA Server control panel

Guides

Node.js App

Create a Node.js site for Express, Next.js, Nuxt, NestJS or a custom server.

1. Create the site

Add site → Node.js lists installed Node versions. Install a missing version under Instance → Runtimes first. The application template suggests a start command; check it against your project's package.json.

Advanced contains the application directory (for example apps/web in a monorepo), internal port, instance count and HTTP health check path. Empty application directory means the repository root. Port assignment is automatic unless you specify one; the entire instance range must be free and exclude the panel's ports.

Creating a site prepares its Linux user, routing and service; it does not download a framework or start an empty application. Overview explains the next steps.

2. Runtime and package managers

Node binaries are shared by sites selecting the same version. Each site has its own Linux user, project dependencies and package manager cache. npm, Yarn, pnpm and Bun are available in SSH, terminal, deploy and app services. Tool versions are pinned and downloaded with integrity verification. Bun is also a runtime: bun run start may be used as the start command.

The default Node deploy script reads the application's package.json:

  • An exact packageManager pin chooses the manager and version. Yarn/pnpm pins are handled by Corepack. npm/Bun pins use the installed version and print a warning when it differs.
  • Otherwise the lockfile chooses npm (package-lock.json / npm-shrinkwrap.json), Yarn (yarn.lock), pnpm (pnpm-lock.yaml) or Bun (bun.lock / bun.lockb). No lockfile defaults to npm. A Yarn 1 lockfile without a pin uses Yarn 1; for it the suggested start command is corepack yarn@1.22.22 start.
  • pnpm runs dependency build scripts (esbuild, sharp, prisma) like npm does, unless the project sets onlyBuiltDependencies or neverBuiltDependencies.
  • Conflicting managers or lockfiles fail instead of silently replacing a lockfile.
  • Dependencies required for a build are installed, including development dependencies; the build script runs if present. Existing custom deploy scripts are kept.
  • For a monorepo, an ancestor lockfile and package manager pin are detected up to the repository root. Dependency installation runs there; the build runs in the application directory.

Upgrading existing sites

Saved deploy scripts are preserved, including scripts that were saved from the previous default. To enable automatic package manager detection on an existing site, replace its dependency-install/build commands with:

/usr/bin/php /usr/local/lib/xaxa/xaxa-app node-deploy

Keep any application-specific migration or other custom commands. Existing atomic deployment Shared paths lists are also preserved: add .env.build and .env.runtime alongside .env, with the application directory prefix if configured (for example apps/web/.env.runtime). Otherwise files kept outside Git will not be carried into the next release.

3. Make the app listen on the assigned port

const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello from XAXA'));
app.listen(process.env.PORT, process.env.HOST);

Each instance receives its own PORT and HOST=127.0.0.1. Your app must use them; setting HOST does not force a framework that ignores it to bind to localhost. Check the command/framework configuration.

Multiple instances share the application files but have separate processes. Use shared sessions and storage where needed. Do not run the same scheduled task in every instance.

4. Configure environment

Settings → Environment edits the same files as Files, in the application directory:

File Scope
.env Build and runtime
.env.build Build overrides
.env.runtime Runtime overrides

Service overrides preserves variables previously entered in the panel. They take precedence over runtime files and are not loaded for builds. PORT, HOST, PATH, HOME, USER, LOGNAME and SHELL are managed by the panel; project files cannot override them.

Comments, single/double quotes, empty values, double-quoted \n escapes and quoted values over several lines (PEM keys) are supported. ${NAME} in unquoted and double-quoted values expands from earlier keys and the service environment (${PORT} works); single-quoted values and \$ stay literal. Shell commands are never run. Settings rejects duplicate keys; in a file edited elsewhere the last one wins, as in dotenv. Settings preserves comments/formatting and checks for changes made since the file was opened. New files are private (0600).

Saving does not start a stopped app. Choose Restart running instances to apply runtime changes immediately, or restart later from Actions. Build changes need a new deployment. Edits to .env / .env.runtime in Files also mark a restart as pending. If you edit by SSH/SFTP, restart the app yourself. Never put secrets in browser-visible framework build variables.

5. Deploy and verify

Connect a repository in Deploy and save, then Deploy now. The default script installs the appropriate dependencies, builds and starts the app. Deploy and runtime use the configured application directory.

For a manual upload, install dependencies before building (do not omit development dependencies needed by the build):

ssh example@your-server
cd ~/htdocs/example.com
npm ci
npm run build --if-present

Then click Start on Overview. App logs are under Logs → App. The service restarts automatically after a crash. If a health check path is set, a start/restart or deployment waits up to 40 seconds for every instance to answer it with a status below 500. Leave it empty for workers and apps without HTTP.

Atomic deployments build in a new release folder, then switch and restart. The restart can cause a brief interruption. If startup health fails, the deploy fails and the agent attempts to restore the previous release. Database changes are not rolled back.

Clones can include or omit project environment files and service overrides. Review database URLs, external services and domain-specific values before starting a clone.

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