Skip to main content

Overview

The Xloud Dashboard stores user session data (authentication tokens, UI state, flash messages) in a configurable backend. The default is Memcached — suitable for most production deployments. In high-availability configurations where multiple Dashboard instances are load-balanced, the session backend must be shared across all nodes.
Prerequisites
  • SSH access to the Dashboard host
  • The session backend service (Memcached, Redis, or database) must already be running and accessible from the Dashboard host

Session Storage Configuration

Session storage is automatically configured during deployment. The default backend (Memcached) is provisioned and connected to the Dashboard without manual intervention.For advanced customization (such as switching to Redis or adjusting session parameters):

Open Advanced Configuration

Navigate to XDeploy → Advanced Configuration and select horizon in the Service Tree.

Edit local_settings.py

Select or create local_settings.py in the file list. Modify the SESSION_ENGINE and CACHES configuration as needed (see the backend-specific examples in the CLI tab for reference values).Click Save Current File.

Deploy the changes

Navigate to XDeploy → Operations and run a Reconfigure for the Dashboard service.
Session storage backend is updated across all Dashboard instances.
For most deployments, the default Memcached configuration requires no changes. Only modify session storage when switching backends or tuning HA behaviour.

Session Backend Comparison

BackendHA SupportPerformancePersistenceWhen to Use
MemcachedYes (shared cluster)FastestNo (data lost on restart)Default — recommended for most deployments
RedisYes (Sentinel or Cluster)FastOptional (RDB/AOF)When session persistence is required
DatabaseYes (shared DB)SlowerYesLegacy or when no caching layer available
CookieN/A (client-side)N/AClient-managedDevelopment only — insecure for production

Memcached (Default)

Xloud XAVS deploys Memcached as part of the standard stack. The Dashboard is pre-configured to use it.
local_settings.py — Memcached session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyMemcache',
        'LOCATION': [
            '10.0.1.71:11211',
            '10.0.1.72:11211',
            '10.0.1.75:11211',
        ],
    }
}
For a single-node Memcached:
Single-node Memcached
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyMemcache',
        'LOCATION': '127.0.0.1:11211',
    }
}
In multi-node Dashboard deployments (multiple Horizon containers behind a load balancer), all nodes must point to the same Memcached cluster to share sessions. A user logging in on Node A must be able to authenticate on Node B without being prompted to log in again.

Redis

Redis provides session persistence and supports Sentinel and Cluster modes for HA.

Install Redis client library

Install django-redis in the Horizon container
docker exec horizon pip install django-redis
For persistent configuration, add django-redis to the Horizon image build.

Configure the session backend

local_settings.py — Redis session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://10.0.1.71:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'PASSWORD': 'your-redis-password',
            'SOCKET_CONNECT_TIMEOUT': 5,
            'SOCKET_TIMEOUT': 5,
        }
    }
}

Sentinel HA configuration

Redis Sentinel session
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://mymaster/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.SentinelClient',
            'SENTINELS': [
                ('10.0.1.71', 26379),
                ('10.0.1.72', 26379),
                ('10.0.1.75', 26379),
            ],
            'SENTINEL_KWARGS': {
                'password': 'sentinel-password'
            },
            'PASSWORD': 'redis-password',
        }
    }
}

Database Sessions

Database sessions store session data in the Django django_session table. Suitable when no caching infrastructure is available but performs worse under load due to database round-trips on every request.
local_settings.py — Database session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'horizon',
        'USER': 'horizon',
        'PASSWORD': 'your-db-password',
        'HOST': '10.0.1.71',
        'PORT': '3306',
    }
}
After changing to database sessions, run migrations:
Create session table
docker exec horizon python manage.py migrate

Session Expiry and Security

Session security settings
# Session lifetime in seconds (default: 3600 = 1 hour)
SESSION_COOKIE_AGE = 3600

# Extend session on every request (resets the timer)
SESSION_SAVE_EVERY_REQUEST = True

# Expire session when the browser closes
SESSION_EXPIRE_AT_BROWSER_CLOSE = False

# Secure cookies (require HTTPS)
SESSION_COOKIE_SECURE = True

# Prevent JavaScript access to the session cookie
SESSION_COOKIE_HTTPONLY = True

# Enforce SameSite cookie policy
SESSION_COOKIE_SAMESITE = 'Lax'
Token timeout in Keystone ([token] expiration) and session timeout in the Dashboard (SESSION_COOKIE_AGE) are independent. If the Keystone token expires before the session cookie, you will encounter 401 errors. Set SESSION_COOKIE_AGE to match or be slightly less than the Keystone token lifetime.

Next Steps

Quotas & Limits

Configure project quotas and resource limits

Projects & Users

Manage project membership and user accounts

Token Configuration

Configure Keystone token lifetimes and rotation

Security Hardening

Broader infrastructure security configuration