Skip to main content
XyraPanel is configured entirely through environment variables stored in the .env file. This guide explains all available configuration options.

Environment File Location

/opt/xyrapanel/.env

Essential Configuration

These variables must be configured before running XyraPanel.

Application Settings

.env
APP_NAME="XyraPanel"
NODE_ENV="production"
DEBUG=false
APP_NAME
string
default:"XyraPanel"
The display name of your panel. Shown in the UI and emails.
NODE_ENV
string
default:"production"
Environment mode. Use production for live deployments, development for local testing.
DEBUG
boolean
default:"false"
Enable debug logging. Only use in development.

Application URLs

.env
BETTER_AUTH_URL=https://panel.example.com
BETTER_AUTH_TRUSTED_ORIGINS=https://panel.example.com
NUXT_PUBLIC_APP_URL=https://panel.example.com
PANEL_PUBLIC_URL="https://panel.example.com"
PANEL_INTERNAL_URL="http://127.0.0.1:3000"
PORT="3000"
BETTER_AUTH_URL
string
required
Public URL where your panel is accessible. Must include protocol (https://).
BETTER_AUTH_TRUSTED_ORIGINS
string
required
Comma-separated list of trusted origins for authentication. Typically matches BETTER_AUTH_URL.
NUXT_PUBLIC_APP_URL
string
required
Public-facing application URL. Used for client-side routing.
PANEL_PUBLIC_URL
string
required
External URL used in emails and API responses.
PANEL_INTERNAL_URL
string
default:"http://127.0.0.1:3000"
Internal URL for server-to-server communication.
PORT
number
default:"3000"
Port the application listens on. Nginx proxies to this port.

Authentication Secrets

Security Critical: Generate strong, unique secrets for production. Never share these values.
.env
# Generate with: openssl rand -base64 32
BETTER_AUTH_SECRET=<your-generated-secret>
SEED_SECRET=<your-generated-secret>
BETTER_AUTH_SECRET
string
required
Secret key for authentication token signing. Generate with openssl rand -base64 32.
Changing this will invalidate all existing sessions.
SEED_SECRET
string
required
Secret used to protect the admin seed endpoint. Required for creating the initial admin account.

Admin Account Seeding

.env
SEED_ADMIN_EMAIL="[email protected]"
SEED_ADMIN_PASSWORD="changeme"
SEED_ADMIN_USERNAME="admin"
SEED_ADMIN_NAME="Admin"
SEED_ADMIN_EMAIL
string
required
Email address for the initial admin account.
SEED_ADMIN_PASSWORD
string
required
Password for the initial admin account. Change this immediately after first login.
SEED_ADMIN_USERNAME
string
required
Username for the admin account.
SEED_ADMIN_NAME
string
required
Display name for the admin user.

Database Configuration

.env
# PostgreSQL connection string
DATABASE_URL="postgresql://xyra:changeme@postgres:5432/xyrapanel"

# Docker only: these configure the postgres container
DB_USER="xyra"
DB_PASSWORD="changeme"
DB_NAME="xyrapanel"
DATABASE_URL
string
required
PostgreSQL connection string. Format:
postgresql://[user]:[password]@[host]:[port]/[database]
Examples:
  • Docker: postgresql://xyra:changeme@postgres:5432/xyrapanel
  • Manual: postgresql://xyra:[email protected]:5432/xyrapanel
DB_USER
string
default:"xyra"
Database username. Docker only - must match credentials in DATABASE_URL.
DB_PASSWORD
string
required
Database password. Docker only - must match credentials in DATABASE_URL.
DB_NAME
string
default:"xyrapanel"
Database name. Docker only - must match database in DATABASE_URL.

Redis Configuration

.env
REDIS_HOST="redis"
REDIS_PORT="6379"
# REDIS_USERNAME=""  # Optional
# REDIS_PASSWORD=""  # Optional
# REDIS_TLS="false"  # Optional
REDIS_HOST
string
required
Redis server hostname.
  • Docker: redis
  • Manual: 127.0.0.1 or localhost
REDIS_PORT
number
default:"6379"
Redis server port.
REDIS_USERNAME
string
Redis username (ACL). Leave empty if not using authentication.
REDIS_PASSWORD
string
Redis password. Leave empty if not using authentication.
REDIS_TLS
boolean
default:"false"
Enable TLS for Redis connection. Set to true for managed Redis services.

Advanced Configuration

Nuxt/Nitro Redis Storage

Internal caching configuration. Must match your Redis settings.
.env
NITRO_STORAGE_CACHE_DRIVER="redis"
NITRO_STORAGE_CACHE_HOST="redis"
NITRO_STORAGE_CACHE_PORT="6379"
NUXT_REDIS_HOST="redis"
NUXT_REDIS_PORT="6379"

Security Settings

.env
NUXT_SECURITY_CORS_ORIGIN="https://panel.example.com"
NUXT_SECURITY_CONNECT_SRC="https://panel.example.com"
NUXT_SECURITY_RATE_LIMIT_DRIVER="redis"
NUXT_SECURITY_RATE_LIMIT_TOKENS="150"
NUXT_SECURITY_RATE_LIMIT_INTERVAL_MS="300000"
NUXT_SECURITY_CSP_REPORT_ONLY="false"
NUXT_SECURITY_CSP_REPORT_URI=""
NUXT_SECURITY_CORS_ORIGIN
string
required
Allowed CORS origin. Should match your panel URL.
NUXT_SECURITY_RATE_LIMIT_DRIVER
string
default:"redis"
Rate limiting storage driver. Use redis in production, lruCache for development.
NUXT_SECURITY_RATE_LIMIT_TOKENS
number
default:"150"
Number of requests allowed per interval.
NUXT_SECURITY_RATE_LIMIT_INTERVAL_MS
number
default:"300000"
Rate limit interval in milliseconds (default: 5 minutes).
NUXT_SECURITY_CSP_REPORT_ONLY
boolean
default:"false"
Content Security Policy mode.
  • true: Report violations without blocking (testing)
  • false: Enforce CSP and block violations (production)

HTTP Cache Settings

.env
NUXT_HTTP_CACHE_ENABLED="true"
NUXT_HTTP_CACHE_DEFAULT_MAX_AGE="5"
NUXT_HTTP_CACHE_DEFAULT_SWR="15"
NUXT_HTTP_CACHE_DASHBOARD_MAX_AGE="10"
NUXT_HTTP_CACHE_DASHBOARD_SWR="30"
NUXT_HTTP_CACHE_ENABLED
boolean
default:"true"
Enable HTTP response caching for improved performance.
NUXT_HTTP_CACHE_DEFAULT_MAX_AGE
number
default:"5"
Default cache max-age in seconds.
NUXT_HTTP_CACHE_DEFAULT_SWR
number
default:"15"
Stale-while-revalidate duration in seconds.

Captcha Configuration

XyraPanel supports Cloudflare Turnstile, Google reCAPTCHA v3, and hCaptcha.
.env
CAPTCHA_PROVIDER="turnstile"
NUXT_TURNSTILE_SECRET_KEY="your-secret-key"
NUXT_PUBLIC_TURNSTILE_SITE_KEY="your-site-key"
Get your keys at: Cloudflare Turnstile
Test mode key: 1x00000000000000000000AA (allows testing without validation)

Request Limits

.env
NUXT_MAX_REQUEST_SIZE_MB="10"
NUXT_MAX_UPLOAD_SIZE_MB="20"
NUXT_MAX_REQUEST_SIZE_MB
number
default:"10"
Maximum request body size in megabytes.
NUXT_MAX_UPLOAD_SIZE_MB
number
default:"20"
Maximum file upload size in megabytes.

PM2 Configuration

.env
# INSTANCES=1  # Uncomment to force single instance
# MAX_MEMORY_RESTART="1G"  # Restart if memory exceeds limit
INSTANCES
number
default:"max"
Number of PM2 instances to run.
  • max: Use all CPU cores (default)
  • 1: Single instance (recommended for servers with less than 2GB RAM)
  • <number>: Specific number of instances
MAX_MEMORY_RESTART
string
default:"1G"
Restart instance if memory usage exceeds this limit. Format: <number>G or <number>M.

Configuration Examples

Development Setup

.env
APP_NAME="XyraPanel Dev"
NODE_ENV="development"
DEBUG=true

BETTER_AUTH_URL=http://localhost:3000
BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000
NUXT_PUBLIC_APP_URL=http://localhost:3000
PANEL_PUBLIC_URL="http://localhost:3000"
PANEL_INTERNAL_URL="http://127.0.0.1:3000"
PORT="3000"

BETTER_AUTH_SECRET=<generated-secret>
SEED_SECRET=<generated-secret>

SEED_ADMIN_EMAIL="dev@localhost"
SEED_ADMIN_PASSWORD="admin"
SEED_ADMIN_USERNAME="admin"
SEED_ADMIN_NAME="Dev Admin"

DATABASE_URL="postgresql://xyra:changeme@localhost:5432/xyrapanel"

REDIS_HOST="localhost"
REDIS_PORT="6379"

NUXT_SECURITY_RATE_LIMIT_DRIVER="lruCache"
CAPTCHA_PROVIDER="turnstile"
NUXT_PUBLIC_TURNSTILE_SITE_KEY="1x00000000000000000000AA"

Production Setup

.env
APP_NAME="XyraPanel"
NODE_ENV="production"
DEBUG=false

BETTER_AUTH_URL=https://panel.yourdomain.com
BETTER_AUTH_TRUSTED_ORIGINS=https://panel.yourdomain.com
NUXT_PUBLIC_APP_URL=https://panel.yourdomain.com
PANEL_PUBLIC_URL="https://panel.yourdomain.com"
PANEL_INTERNAL_URL="http://127.0.0.1:3000"
PORT="3000"

BETTER_AUTH_SECRET=<strong-generated-secret>
SEED_SECRET=<strong-generated-secret>

SEED_ADMIN_EMAIL="[email protected]"
SEED_ADMIN_PASSWORD="<strong-password>"
SEED_ADMIN_USERNAME="admin"
SEED_ADMIN_NAME="Administrator"

DATABASE_URL="postgresql://xyrapanel:<secure-password>@127.0.0.1:5432/xyrapanel"

REDIS_HOST="127.0.0.1"
REDIS_PORT="6379"
REDIS_PASSWORD="<redis-password>"

NUXT_SECURITY_CORS_ORIGIN="https://panel.yourdomain.com"
NUXT_SECURITY_RATE_LIMIT_DRIVER="redis"
NUXT_SECURITY_RATE_LIMIT_TOKENS="1000"
NUXT_SECURITY_CSP_REPORT_ONLY="false"

CAPTCHA_PROVIDER="turnstile"
NUXT_TURNSTILE_SECRET_KEY="<your-turnstile-secret>"
NUXT_PUBLIC_TURNSTILE_SITE_KEY="<your-turnstile-site-key>"

INSTANCES=2
MAX_MEMORY_RESTART="1G"

Applying Configuration Changes

After modifying .env, restart the panel:
pm2 restart xyrapanel

Security Best Practices

Always generate cryptographically secure secrets:
# Generate BETTER_AUTH_SECRET
openssl rand -base64 32

# Generate SEED_SECRET
openssl rand -base64 32

# Generate database password
openssl rand -hex 16
Ensure proper file permissions:
chmod 600 /opt/xyrapanel/.env
chown xyrapanel:xyrapanel /opt/xyrapanel/.env
Never commit .env to version control. Add it to .gitignore.
Always use https:// URLs for production deployments:
  • BETTER_AUTH_URL
  • NUXT_PUBLIC_APP_URL
  • PANEL_PUBLIC_URL
Use Let’s Encrypt for free SSL certificates.
Use Redis-based rate limiting in production:
NUXT_SECURITY_RATE_LIMIT_DRIVER="redis"
NUXT_SECURITY_RATE_LIMIT_TOKENS="1000"
Implement a secret rotation policy:
  1. Generate new BETTER_AUTH_SECRET
  2. Update .env
  3. Restart the panel
  4. All users will need to re-authenticate

Next Steps

First Server

Create your first game server

Wings Setup

Install and configure Wings daemon

Build docs developers (and LLMs) love