---
sidebar_label: 'Customize and configure the Dashboard'
sidebar_position: 1
---

<!-- truncate -->
import CodeBlock from '@site/src/components/CodeBloack';

# Customize and configure the Dashboard

<div className="text">Once you have the Dashboard installed, you can customize the way it looks and feels to suit the needs of your environment, your project, or your business.<br/><br/>
You can also configure the Dashboard for a secure HTTPS deployment, or an HTTP deployment. The standard OpenStack installation uses a non-encrypted HTTP channel, but you can enable SSL support for the Dashboard.<br/>
For information on configuring HTTPS or HTTP, see Configure the Dashboard.</div>

<div className="head">Customize the Dashboard</div>
<div className="text">The OpenStack Dashboard on Ubuntu installs the ***openstack-dashboard-ubuntu-theme*** package by default. If you do not want to use this theme, remove it and its dependencies:</div>

<CodeBlock code={`# apt-get remove --auto-remove openstack-dashboard-ubuntu-theme
`} /> <br/>

<div className="note"><strong>Note</strong>: This guide focuses on the local_settings.py file.</div><br/>
<div className="text">The following Dashboard content can be customized to suit your needs:</div>
<div className="text"><ul><li>Logo</li><li>Site colors</li><li>HTML title</li><li>Logo link</li><li>Help URL</li></ul></div>

<div className="head">Logo and site colors</div>
<div className="text"><ol><li>Create two PNG logo files with transparent backgrounds using the following sizes:<br/>&bull; Login screen: 365 x 50<br/>&bull; Logged in banner: 216 x 35</li><li>Upload your new images to ***/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/***.</li><li>Create a CSS style sheet in ***/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/scss/***.</li><li>Change the colors and image file names as appropriate. Ensure the relative directory paths are the same. The following example file shows you how to customize your CSS file:</li></ol></div>

<CodeBlock code={`/*
* New theme colors for dashboard that override the defaults:
*  dark blue: #355796 / rgb(53, 87, 150)
*  light blue: #BAD3E1 / rgb(186, 211, 225)
*
* By Preston Lee <plee@tgen.org>
*/
h1.brand {
background: #355796 repeat-x top left;
border-bottom: 2px solid #BAD3E1;
}
h1.brand a {
background: url(../img/my_cloud_logo_small.png) top left no-repeat;
}
#splash .login {
background: #355796 url(../img/my_cloud_logo_medium.png) no-repeat center 35px;
}
#splash .login .modal-header {
border-top: 1px solid #BAD3E1;
}
.btn-primary {
background-image: none !important;
background-color: #355796 !important;
border: none !important;
box-shadow: none;
}
.btn-primary:hover,
.btn-primary:active {
border: none;
box-shadow: none;
background-color: #BAD3E1 !important;
text-decoration: none;
}
`} /> <br/>

<div className="text">5. Open the following HTML template in an editor of your choice:</div>

<CodeBlock code={`/usr/share/openstack-dashboard/openstack_dashboard/templates/_stylesheets.html
`} /> <br/>

<div className="text">6. Add a line to include your newly created style sheet. For example, ***custom.css*** file:</div>

<CodeBlock code={`<link href='{{ STATIC_URL }}bootstrap/css/bootstrap.min.css' media='screen' rel='stylesheet' />
<link href='{{ STATIC_URL }}dashboard/css/{% choose_css %}' media='screen' rel='stylesheet' />
<link href='{{ STATIC_URL }}dashboard/css/custom.css' media='screen' rel='stylesheet' />
`} /> <br/>


<div className="text">7. Restart the Apache service.</div>

<div className="text">8. To view your changes, reload your Dashboard. If necessary, go back and modify your CSS file as appropriate.</div>

<div className="head">HTML title</div>

<div className="text">1. Set the HTML title, which appears at the top of the browser window, by adding the following line to ***local_settings.py:***</div>

<CodeBlock code={`SITE_BRANDING = "Example, Inc. Cloud"
`} /> <br/>

<div className="text">2. Restart Apache for this change to take effect.</div>


<div className="head">Logo link</div>
<div className="text">1. The logo also acts as a hyperlink. The default behavior is to redirect to ***horizon:user_home***. To change this, add the following attribute to ***local_settings.py:***</div>

<CodeBlock code={`SITE_BRANDING_LINK = "http://example.com"
`} /> <br/>

<div className="text">2. Restart Apache for this change to take effect.</div>


<div className="head">Help URL</div>
<div className="text">1. By default, the help URL points to  <span style={{textDecoration:'underline', color: '#0000b3'}} >https://docs.openstack.org.</span> To change this, edit the following attribute in ***local_settings.py:***</div>

<CodeBlock code={`HORIZON_CONFIG["help_url"] = "http://openstack.mycompany.org"
`} /> <br/>

<div className="text">2. Restart Apache for this change to take effect.</div>

<div className="head">Configure the Dashboard</div>
<div className="text">The following section on configuring the Dashboard for a secure HTTPS deployment, or a HTTP deployment, uses concrete examples to ensure the procedure is clear. The file path varies by distribution, however. If needed, you can also configure the VNC window size in the Dashboard.</div>
<div className="text" style={{ fontSize:'28px' }}>Configure the Dashboard for HTTP</div>
<div className="text">You can configure the Dashboard for a simple HTTP deployment. The standard installation uses a non-encrypted HTTP channel.</div>

<div className="text">1. Specify the host for your Identity service endpoint in the local_settings.py file with the OPENSTACK_HOST setting.<br/><br/>The following example shows this setting:</div>

<CodeBlock code={`import os

from django.utils.translation import gettext_lazy as _

DEBUG = False
TEMPLATE_DEBUG = DEBUG
PROD = True

SITE_BRANDING = 'OpenStack Dashboard'

# Ubuntu-specific: Enables an extra panel in the 'Settings' section
# that easily generates a Juju environments.yaml for download,
# preconfigured with endpoints and credentials required for bootstrap
# and service deployment.
ENABLE_JUJU_PANEL = True

# Note: You should change this value
SECRET_KEY = 'elj1IWiLoWHgryYxFT6j7cM5fGOOxWY0'

# Specify a regular expression to validate user passwords.
# HORIZON_CONFIG = {
#     "password_validator": {
#         "regex": '.*',
#         "help_text": _("Your password does not meet the requirements.")
#     }
# }

LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))

CACHES = {
    'default': {
        'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION' : '127.0.0.1:11211'
    }
}

# Send email to the console by default
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# Or send them to /dev/null
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'

# Configure these for your outgoing email host
# EMAIL_HOST = 'smtp.my-company.com'
# EMAIL_PORT = 25
# EMAIL_HOST_USER = 'djangomail'
# EMAIL_HOST_PASSWORD = 'top-secret!'

# For multiple regions uncomment this configuration, and add (endpoint, title).
# AVAILABLE_REGIONS = [
#     ('http://cluster1.example.com/identity/v3', 'cluster1'),
#     ('http://cluster2.example.com/identity/v3', 'cluster2'),
# ]

OPENSTACK_HOST = "127.0.0.1"
OPENSTACK_KEYSTONE_URL = "http://%s/identity/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"

# The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the
# capabilities of the auth backend for Keystone.
# If Keystone has been configured to use LDAP as the auth backend then set
# can_edit_user to False and name to 'ldap'.
#
# TODO(tres): Remove these once Keystone has an API to identify auth backend.
OPENSTACK_KEYSTONE_BACKEND = {
    'name': 'native',
    'can_edit_user': True
}

# OPENSTACK_ENDPOINT_TYPE specifies the endpoint type to use for the endpoints
# in the Keystone service catalog. Use this setting when Horizon is running
# external to the OpenStack environment. The default is 'internalURL'.
#OPENSTACK_ENDPOINT_TYPE = "publicURL"

# The number of Swift containers and objects to display on a single page before
# providing a paging element (a "more" link) to paginate results.
API_RESULT_LIMIT = 1000

# If you have external monitoring links, eg:
# EXTERNAL_MONITORING = [
#     ['Nagios','http://foo.com'],
#     ['Ganglia','http://bar.com'],
# ]

LOGGING = {
        'version': 1,
        # When set to True this will disable all logging except
        # for loggers specified in this configuration dictionary. Note that
        # if nothing is specified here and disable_existing_loggers is True,
        # django.db.backends will still log unless it is disabled explicitly.
        'disable_existing_loggers': False,
        'handlers': {
            'null': {
                'level': 'DEBUG',
                'class': 'logging.NullHandler',
                },
            'console': {
                # Set the level to "DEBUG" for verbose output logging.
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                },
            },
        'loggers': {
            # Logging from django.db.backends is VERY verbose, send to null
            # by default.
            'django.db.backends': {
                'handlers': ['null'],
                'propagate': False,
                },
            'horizon': {
                'handlers': ['console'],
                'propagate': False,
            },
            'novaclient': {
                'handlers': ['console'],
                'propagate': False,
            },
            'keystoneclient': {
                'handlers': ['console'],
                'propagate': False,
            }
        }
}
`} /> <br/>

<div className="text">The service catalog configuration in the Identity service determines whether a service appears in the Dashboard. For the full listing, see <span style={{textDecoration:'underline', color: '#0000b3'}}>Settings Reference.</span></div>
<div className="text">2. Restart the Apache HTTP Server.</div>
<div className="text">3. Restart ***memcached***.</div><br/>


<div className="text" style={{ fontSize:'28px' }}>Configure the Dashboard for HTTPS</div>
<div ClassName="text">You can configure the Dashboard for a secured HTTPS deployment. While the standard installation uses a non-encrypted HTTP channel, you can enable SSL support for the Dashboard.<br/>This example uses the ***http://openstack.example.com*** domain. Use a domain that fits your current setup.</div>

<div className="text">1. In the ***local_settings.py*** file, update the following options:</div>

<CodeBlock code={`CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
`} /> 

<div className="text">The other options require that HTTPS is enabled; these options defend against cross-site scripting.</div>

<div className="text">2. Edit the ***openstack-dashboard***.conf file as shown in the <strong>Example After:</strong></div>

<div className="text"><strong>Example Before</strong></div>

<CodeBlock code={`WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py
WSGIDaemonProcess horizon user=www-data group=www-data processes=3 threads=10
Alias /static /usr/share/openstack-dashboard/openstack_dashboard/static/
<Location />
  <ifVersion >=2.4>
    Require all granted
  </ifVersion>
  <ifVersion <2.4>
    Order allow,deny
    Allow from all
  </ifVersion>
</Location>
`} /> 

<div className="text"><strong>Example After</strong></div>

<CodeBlock code={`<VirtualHost *:80>
  ServerName openstack.example.com
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
  </IfModule>
  <IfModule !mod_rewrite.c>
    RedirectPermanent / https://openstack.example.com
  </IfModule>
</VirtualHost>

<VirtualHost *:443>
  ServerName openstack.example.com

  SSLEngine On
  # Remember to replace certificates and keys with valid paths in your environment
  SSLCertificateFile /etc/apache2/SSL/openstack.example.com.crt
  SSLCACertificateFile /etc/apache2/SSL/openstack.example.com.crt
  SSLCertificateKeyFile /etc/apache2/SSL/openstack.example.com.key
  SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

  # HTTP Strict Transport Security (HSTS) enforces that all communications
  # with a server go over SSL. This mitigates the threat from attacks such
  # as SSL-Strip which replaces links on the wire, stripping away https prefixes
  # and potentially allowing an attacker to view confidential information on the
  # wire
  Header add Strict-Transport-Security "max-age=15768000"

  WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py
  WSGIDaemonProcess horizon user=www-data group=www-data processes=3 threads=10
  Alias /static /usr/share/openstack-dashboard/openstack_dashboard/static/
  <Location />
    Options None
    AllowOverride None
    # For Apache http server 2.4 and later:
    <ifVersion >=2.4>
      Require all granted
    </ifVersion>
    # For Apache http server 2.2 and earlier:
    <ifVersion <2.4>
      Order allow,deny
      Allow from all
    </ifVersion>
  </Location>
</VirtualHost>
`} /> 

<div className="text">In this configuration, the Apache HTTP Server listens on port 443 and redirects all non-secure requests to the HTTPS protocol. The secured section defines the private key, public key, and certificate to use.</div>

<div className="text">3. Restart the Apache HTTP Server.</div>
<div className="text">4. Restart ***memcached***.<br/>If you try to access the Dashboard through HTTP, the browser redirects you to the HTTPS page.</div>

<div className="note"><strong>Note</strong>: Configuring the Dashboard for HTTPS also requires enabling SSL for the noVNC proxy service. On the controller node, add the following additional options to the ***[DEFAULT]*** section of the ***/etc/nova/nova.conf file:***</div><br/>

<CodeBlock code={`[DEFAULT]
# ...
ssl_only = true
cert = /etc/apache2/SSL/openstack.example.com.crt
key = /etc/apache2/SSL/openstack.example.com.key
`} /> <br/>

<div className="text">On the compute nodes, ensure the ***nonvncproxy_base_url*** option points to a URL with an HTTPS scheme:</div>

<CodeBlock code={`[DEFAULT]
# ...
novncproxy_base_url = https://controller:6080/vnc_auto.html
`} /> <br/>







