Skip to content

Your cloud

Controller node

Build the control plane first. It remembers cloud state, authenticates requests and directs work; it does not run guest virtual machines.

Saphira Linux dragon mascot

What this machine does

The controller is the coordination point for the cloud. It records identities, images, networks, instance requests and scheduler state. When a user asks to start a VM, the controller decides whether the request is permitted, finds a compute host, sends work to it and records the result. The compute host performs the actual boot.

Put the controller on a stable, reachable address. Its failure affects the dashboard and control APIs even if an already-running guest continues to execute on a compute host. The Saphira role is a controller role only: it does not configure compute or storage services on this machine.

Known completion boundary

The setup script checks for /usr/share/novnc/vnc_lite.html before it configures the browser console. The noVNC web-assets package is not yet part of the verified package path. If this file is absent, setup stops at the console phase and must not be described as a complete, ready controller. The API services configured before that point may still require separate diagnosis.

Prerequisites and network plan

Install Saphira Linux first, and become root for the role setup. Use a wired, stable network path for the controller where possible: compute hosts will use its address for Keystone, RabbitMQ, image, placement, Nova and Neutron services.

Before starting, write down the controller address, a region label, the browser-facing console hostname, and three distinct secrets. The package documentation does not specify hardware minimums; do not copy unverified sizing numbers into a production plan. Give the controller capacity for its database, message queue, service processes, logs and image storage, then measure it under your workload.

The controller script embeds secrets in service connection settings. Use distinct, safely stored values that are suitable for those connection strings; the packaged documentation recommends letters, digits, _, @ and -. Never reuse the administrator password as the service password or database password.

For external browser consoles, the hostname must be served by a working TLS virtual host. The script can add a /vnc/ proxy block only when it finds the expected nginx configuration; it does not supply a general TLS deployment for you.

Install the controller role

# Run as root. Installing the package fetches the role closure but does not configure or start OpenStack.
apk add saphira-openstack-controller

This installs the controller role’s dependencies: MariaDB, RabbitMQ, memcached, Keystone, Glance, Placement, Nova, Neutron, Horizon and the Saphira installer foundation. Installation is deliberately separate from configuration, so a package install does not create databases, credentials, endpoints or services by surprise.

A successful package transaction returns to the shell without a setup banner. That is expected: the next command performs the configuration.

# Start the interactive controller configuration.
saphira-openstack-setup-controller

The script writes configuration files, bootstraps databases and identity data, starts services and probes them. It refuses to overwrite an existing configuration unless you later give --force. Do not use --force as a first response to a failure: it overwrites the files the script owns and can hide the state you need to inspect.

The six setup questions

PromptWhat it controlsHow to choose it
controller IP addressService endpoints, database and RabbitMQ URLs, and Horizon’s OpenStack host.Use this controller’s stable address reachable by every compute node. Check it carefully; it is not an arbitrary example address.
region nameThe OpenStack service region label.Keep RegionOne unless you have a documented reason to use another stable label. Compute configuration currently uses that region name.
public hostname serving the consoleThe browser-facing noVNC URL written into Nova configuration.Use the name on the TLS virtual host users will actually reach, not an internal address that an outside browser cannot route to.
admin passwordThe Keystone administrator credential used to bootstrap and administer the cloud.Store it in an approved secret store. Do not use it for service-to-service authentication.
service users passwordThe shared credential for the Glance, Nova, Neutron and Placement service users.Use a separate secret. Compute nodes require this value to authenticate their agents to the controller.
database passwordDatabase connection credentials written for the controller services.Use a third distinct secret. The script does not retain passwords in its saved answers file, so store it before proceeding.

The script saves only the controller IP and region in /etc/saphira-openstack/controller.env with restrictive permissions. Passwords are not saved there; a later repair or related role setup may need you to supply them again.

What setup configures and why

LayerPurposeCommunication path
MariaDBKeeps each service’s durable state in separate databases: Keystone, Glance, Placement, Nova and Neutron.Local database connection; the script creates database grants for localhost and 127.0.0.1.
RabbitMQCarries asynchronous work between control services and agents.Nova and Neutron use the openstack RabbitMQ user; agents cannot work merely because the HTTP APIs answer.
memcachedSupports token and service authentication caching.Referenced by Keystone authentication configuration on controller and compute services.
KeystoneIssues tokens and records users, projects, roles, services and endpoints.Other services authenticate to its v3 API before calling one another.
GlanceStores and serves boot images.Nova requests the selected image when it builds an instance.
PlacementTracks reported resource inventory for scheduling.Nova queries it when deciding where an instance can run.
NovaExposes compute API, schedules work and coordinates compute hosts.API, conductor and scheduler run here; Nova Compute runs on each compute node.
NeutronExposes network API and handles RPC for OVS/DHCP agents.The script starts both neutron-api and neutron-rpc-server; the RPC server is essential for agents.
HorizonProvides the browser dashboard.Uses Keystone and service APIs; static assets are collected during setup.

The setup creates individual databases for Keystone, Glance, Placement, Placement API, Nova, Nova API, Nova cell0 and Neutron. It configures a RabbitMQ openstack user and, on RabbitMQ 4, enables the compatibility setting required for transient non-exclusive queues.

Keystone is bootstrapped with the administrator and identity endpoints. The script creates the service project, service users and service catalogue entries. Each service user receives both admin and service roles on the service project. The second role matters: modern services send a service token alongside a user token, and missing service-role grants produce the misleading empty-401 failure described in the pitfalls guide.

Nova’s API database, cell0, cell1 and main database are synchronised. Neutron’s database migration is run with both its main and ML2 configuration files. Horizon gets file sessions, a local-memory cache, a generated secret and collected static files; missing collectstatic output produces an unstyled, broken dashboard rather than a usable login experience.

What successful setup looks like

When all phases complete, the script prints controller ready and tells you to join a compute node. It also obtains an administrator token and probes Keystone, Glance, Placement, Nova and Neutron. Successful protected API probes return HTTP 200 or 300; an unauthenticated request is not the same test.

# Read-only verification after a completed setup.
saphira-openstack-setup-controller --check

The check reads the saved controller address and probes Keystone, Glance, Placement, Nova, Neutron and Horizon. It changes nothing. Each line should report a reachable endpoint rather than a timeout, refused connection or HTTP 000.

# Inspect the service state that the setup script starts.
systemctl is-active mariadb rabbitmq-server memcached
systemctl is-active keystone glance placement nova-api nova-conductor nova-scheduler
systemctl is-active neutron-api neutron-rpc-server horizon

Each successful line is active. If a service is inactive, do not continue to create networks or boot guests: read the unit log for that service and fix the first failing layer.

Horizon, console access and first cloud objects

Horizon is reached through the web service configured for the controller. Sign in with the Keystone administrator account only after the setup verification passes. The exact public URL and TLS policy are site-specific; the role script does not create a general HTTPS site. Confirm the browser sees the intended hostname and certificate before entering an administrator password.

After a controller and a discovered compute host are healthy, create the dependency chain in this order: a provider network and subnet with DHCP enabled, an image, then a flavor. An instance needs all three plus a compute host. The compute guide explains the launch workflow and why each proof is needed.

Do not mistake a dashboard page for proof that the backend works. A useful progression is: controller endpoint checks, live Neutron agents, a live Nova hypervisor, an image and network visible in Horizon, then an instance which is ACTIVE, has a lease, and is reachable by the method you configured.

Failures, logs, maintenance and recovery

Use the unit name from the failed phase. For example, a healthy Neutron HTTP API with agents timing out points at neutron-rpc-server, not the web dashboard. A Nova-to-Neutron empty 401 points at Keystone service-token roles, not the user’s browser session.

# Examples: inspect the current boot’s service logs without changing configuration.
journalctl -u neutron-rpc-server -b --no-pager
journalctl -u nova-api -b --no-pager
journalctl -u rabbitmq-server -b --no-pager
journalctl -u horizon -b --no-pager

Re-run the setup script after correcting the specific issue; it preserves existing configuration unless --force is supplied. Use --force only when you have inspected the existing files and intentionally want the script’s generated configuration to replace them.

The role provides no automated controller backup, upgrade workflow, high-availability setup or tested rollback procedure. Before upgrades or manual configuration changes, make and test your own recovery plan for MariaDB, service configuration, image data and secrets. One controller is a single control-plane failure point; adding a compute host adds capacity, not controller redundancy.

For the known failure modes and their specific checks, continue to the OpenStack pitfalls book. When the controller is verified, continue with the compute-node joining procedure.