Deployment Guide
Xenon supports three deployment topologies. Choose the one that matches your scale and infrastructure.
1. Standalone (Single Node)
The simplest setup — one machine running Appium + Xenon with devices connected directly. Best for local development, small teams, or CI runners.
Characteristics:
- SQLite database (zero setup)
- All devices connected to a single host
- Dashboard accessible on the same machine
- YAML Config
- CLI
server:
keepAliveTimeout: 800
basePath: /wd/hub
usePlugins:
- xenon
plugin:
xenon:
platform: both
maxSessions: 8
enableDashboard: true
bootedSimulators: true
appium server -ka 800 --use-plugins=xenon \
-pa /wd/hub \
--plugin-xenon-platform=both \
--plugin-xenon-max-sessions=8 \
--plugin-xenon-enable-dashboard=true
Database
By default, Xenon uses SQLite stored at ~/.cache/xenon/xenon.db. No setup required.
2. Hub-Node (Distributed Grid)
For larger teams or CI farms with devices spread across multiple machines. The Hub acts as the controller and the Nodes register over HTTP REST (/xenon/api/register) and stream live state over Socket.IO. Each node authenticates with a per-node (accessKey, token) pair provisioned on the hub — see Node Provisioning.
Hub Configuration
server:
keepAliveTimeout: 800
basePath: /wd/hub
usePlugins:
- xenon
plugin:
xenon:
platform: both
maxSessions: 16
enableDashboard: true
databaseProvider: postgresql
databaseUrl: "postgresql://user:password@localhost:5432/xenon"
Node Configuration
server:
keepAliveTimeout: 800
basePath: /wd/hub
usePlugins:
- xenon
plugin:
xenon:
platform: android
hub: "http://hub-ip:4723"
Set the node's pair-auth env vars before starting the Appium server (provision the credentials on the hub first per Node Provisioning):
export XENON_HUB_ACCESS_KEY="xen_..."
export XENON_HUB_TOKEN="..."
PostgreSQL Setup
PostgreSQL is required for Hub-Node deployments to maintain shared state across nodes.
# Create the database
createdb xenon
# Set the connection URL
export DATABASE_URL="postgresql://user:password@localhost:5432/xenon"
# Or configure via plugin args
--plugin-xenon-database-provider=postgresql
--plugin-xenon-database-url="postgresql://user:password@localhost:5432/xenon"
Xenon auto-applies pending schema changes on every startup — prisma db push for SQLite, prisma migrate deploy for PostgreSQL — so deploying a new plugin version never requires a manual migration step. Set XENON_AUTO_MIGRATE=false if you manage schema externally via CI for auditable change-control; in that case run prisma migrate deploy against your DB before booting the new plugin version, otherwise the next request that hits an unmigrated column will throw.
3. Cloud Execution
Execute tests on cloud device farms without managing physical hardware. Xenon supports five cloud providers:
| Provider | Configuration Key |
|---|---|
| BrowserStack | browserstack |
| SauceLabs | sauce |
| LambdaTest | lambdatest |
| HeadSpin | headspin |
| pCloudy | pcloudy |
See the Cloud Execution Guide for provider-specific setup.
Environment Variables Reference
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | PostgreSQL or SQLite connection string | file:~/.cache/xenon/xenon.db |
XENON_DB_PROVIDER | Database provider (sqlite or postgresql) | sqlite |
GEMINI_API_KEY | Google Gemini API key for AI features | — |
OPENAI_API_KEY | OpenAI API key for AI features | — |
ANTHROPIC_API_KEY | Anthropic API key for AI features | — |
XENON_AI_PROVIDER | AI provider selection | gemini |
XENON_AI_MODEL | AI model override | Provider default |
XENON_AI_BASE_URL | Custom AI endpoint (for Ollama) | — |
XENON_HUB_ACCESS_KEY | Node→hub access key (pair auth) | — |
XENON_HUB_TOKEN | Node→hub API token (pair auth) | — |
XENON_BOOTSTRAP_ADMIN_EMAIL / XENON_BOOTSTRAP_ADMIN_PASSWORD | First-run super-admin user (hub) | admin@xenon.local / Admin@123 |
OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry trace endpoint, full URL (the JS exporter does not append /v1/traces). Tempo: http://tempo:4318/v1/traces. Collector: http://collector:4318/v1/traces. | — |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | OpenTelemetry log endpoint. For Loki 3.0+ direct: http://loki:3100/otlp/v1/logs. See examples/observability/. | — |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | OpenTelemetry metrics endpoint. Typically an OTel Collector at http://collector:4318/v1/metrics; pre-aggregated on a 60s cadence. | — |
OTEL_TRACES_ENABLED | Set to false to disable trace export even if endpoint is set | true |
OTEL_LOGS_ENABLED | Set to false to disable log export even if endpoint is set | true |
OTEL_METRICS_ENABLED | Set to false to disable metrics export even if endpoint is set | true |
OTEL_SDK_DISABLED | Master kill switch — disables traces, logs, and metrics regardless of other vars | false |
XENON_OTEL_DEBUG | Dump traces, log records, and metrics to console (useful for verifying SDK init) | false |
Production Checklist
- Use PostgreSQL for any multi-node deployment
- Set
maxSessionsto match your hardware capacity (CPU cores × 2 is a good starting point) - Configure
newCommandTimeoutSecto auto-release idle sessions (default: 60s) - Set up Data Retention policies to prevent disk exhaustion
- Configure Notifications for
device_offlinealerts - Enable AI Features for automatic failure triage
- Set
keepAliveTimeoutto at least 600 for long-running tests