Application Development Azure

Cube on Ubuntu 24.04 on Azure User Guide

| Product: Cube on Ubuntu 24.04 LTS on Azure

Overview

Cube is the open-source headless BI and semantic layer (formerly Cube.js). It sits in front of your data warehouse or database and exposes a single, consistent data model through REST, GraphQL and SQL APIs, with built in caching and access control - so every dashboard, notebook and application queries the same governed metrics. The cloudimg image runs Cube 1.6.60 from the official Docker image as a systemd service behind an nginx reverse proxy on port 80, ships a self contained sample DuckDB warehouse and a matching data model so the Cube Playground works out of the box, generates a unique API secret and a unique Playground admin password on the first boot of every VM, and stores the data model, sample warehouse and query cache on a dedicated Azure data disk. Backed by 24/7 cloudimg support.

What is included:

  • Cube 1.6.60 (Apache-2.0) run from the official cubejs/cube Docker image, managed by cube.service
  • The Cube API and Playground published on port 80 via nginx (with WebSocket upgrade for the Playground)
  • HTTP Basic auth in front of the Playground so the dev UI is not open to the internet
  • A self contained sample DuckDB warehouse and sample data model (orders and users) so the Playground shows real cubes, measures and dimensions immediately
  • A dedicated Azure data disk at /var/lib/cube for the data model, the sample warehouse, the .env and the query cache
  • A unique CUBEJS_API_SECRET and a unique admin password generated on first boot, written to a root only credentials file
  • cube.service + nginx.service as systemd units, enabled and active
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network and 80/tcp for the API and Playground (front with TLS for public exposure - see Enabling HTTPS).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Cube by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Review the dedicated data disk on the Disks tab, then Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name cube \
  --image <marketplace-image-urn> \
  --size Standard_B2ms \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name cube --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active cube.service nginx.service

Both report active. On first boot Cube generates a unique API secret and a unique Playground admin password.

Cube and nginx service status

Step 5 - Retrieve your admin credentials

The admin password and the API secret are generated uniquely on the first boot of your VM and written to a root-only file:

sudo cat /root/cube-credentials.txt

This file contains CUBE_ADMIN_USER (admin), CUBE_ADMIN_PASSWORD and CUBEJS_API_SECRET. Store them somewhere safe.

Cube per-VM credentials file

Step 6 - Check the health and readiness endpoints

nginx serves a static health endpoint and proxies Cube's readiness probe, both unauthenticated (each returns 200):

curl -s -o /dev/null -w '%{http_code}\n' http://localhost/health
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/readyz

Step 7 - Confirm your credentials gate the Playground

The Cube Playground is fronted by HTTP Basic auth. A valid login returns 200, a missing or wrong password returns 401:

curl -s -o /dev/null -w '%{http_code}\n' -u 'admin:<CUBE_ADMIN_PASSWORD>' http://localhost/
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/

The first command prints 200, the second prints 401.

Step 8 - Open the Cube Playground

Browse to http://<vm-public-ip>/ and sign in with admin and the password from Step 5. The Data Model tab shows the bundled sample data model (cubes/orders.yml and cubes/users.yml):

Cube Playground data model

On the Playground tab, expand the orders cube and add the count measure and the status dimension, then click Run Query. The results table shows live data from the bundled sample warehouse:

Cube Playground query builder and results

Expand the Chart panel to visualise the same query as a line, bar, area or pivot chart:

Cube Playground chart view

The Generated SQL tab shows the exact SQL Cube compiled and pushed down to the warehouse, and the SQL API, REST API and GraphQL API tabs show ready-to-use snippets for each interface:

Cube Playground generated SQL and API tabs

Step 9 - Explore the data model over the REST API

The REST API is the same interface your applications use. List the cubes, measures and dimensions in the loaded model:

curl -s -u 'admin:<CUBE_ADMIN_PASSWORD>' http://localhost/cubejs-api/v1/meta | jq '.cubes[].name'

This returns the sample cubes "orders" and "users".

Step 10 - Run a query through the REST API

Run an aggregating query (the total number of orders) through the Cube load endpoint:

curl -s -u 'admin:<CUBE_ADMIN_PASSWORD>' -G \
  --data-urlencode 'query={"measures":["orders.count"]}' \
  http://localhost/cubejs-api/v1/load | jq '.data'

Cube compiles the query against the sample warehouse and returns the result, for example [{ "orders.count": "2000" }]. Group it by a dimension by adding "dimensions":["orders.status"] to the query:

Cube sample data model and query over the REST API

Step 11 - Confirm the data lives on the dedicated disk

The data model, the sample warehouse, the .env and the query cache are stored on the dedicated Azure data disk so they survive OS changes and can be resized independently:

findmnt /var/lib/cube

The mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM.

Point Cube at your own data warehouse

The image ships a self-contained sample DuckDB warehouse so the Playground works out of the box. To connect Cube to your own warehouse, edit the environment file on the data disk and replace the sample data model.

Edit /var/lib/cube/.env and set the connection variables for your database. For example, for PostgreSQL:

CUBEJS_DB_TYPE=postgres
CUBEJS_DB_HOST=your-warehouse.example.com
CUBEJS_DB_PORT=5432
CUBEJS_DB_NAME=analytics
CUBEJS_DB_USER=cube
CUBEJS_DB_PASS=your-db-password

Cube supports many data sources (PostgreSQL, MySQL, Snowflake, BigQuery, Databricks, ClickHouse, DuckDB and more) - set CUBEJS_DB_TYPE and the matching CUBEJS_DB_* variables for your warehouse. Replace the sample model under /var/lib/cube/model/cubes/ with cubes that describe your own tables, then restart Cube:

sudo systemctl restart cube

The Playground Data Model tab can generate a starting model from your warehouse tables for you.

Using the API secret

Applications authenticate to the Cube REST, GraphQL and SQL APIs with a JSON Web Token signed by the per-VM CUBEJS_API_SECRET from your credentials file. Generate a token and send it in the Authorization header of your API requests - see the Cube authentication docs for token claims and security context. The nginx Basic auth in this image protects the Playground; your production applications use the API secret.

Enabling HTTPS

The nginx reverse proxy terminates plain HTTP on port 80. For public exposure, put a certificate in front of it - add a DNS name for the VM and install certbot, or use the companion cloudimg nginx-ssl-certbot image as a TLS reverse proxy. Keep Cube bound to loopback (127.0.0.1:4000) so the only public surface is the TLS-terminated proxy.

Maintenance

  • Backups: snapshot the /var/lib/cube data disk to back up the data model, the warehouse connection and the query cache.
  • Playground password: rotate it with sudo htpasswd /etc/nginx/.htpasswd admin then sudo systemctl reload nginx.
  • Service: sudo systemctl restart cube after configuration changes; logs via sudo journalctl -u cube or sudo docker logs cube.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.

Cube is a trademark of Cube Dev, Inc. This image is produced by cloudimg and is not affiliated with or endorsed by Cube Dev, Inc.