Developer Tools Azure

Redash on Ubuntu 24.04 on Azure User Guide

| Product: Redash on Ubuntu 24.04 LTS on Azure

Overview

Redash is an open-source platform for querying your data with SQL, visualising the results and assembling them into shareable dashboards. It connects to dozens of databases and APIs, runs and schedules queries, turns result sets into charts, and lets a team build and share dashboards from a browser. The cloudimg image deploys Redash 10.1.0.b50633 as the official production Docker Compose stack (the server, a scheduler, two Celery workers, PostgreSQL and Redis), fronts it with an nginx reverse proxy on port 80, persists all state on a dedicated Azure data disk, rotates every secret, and creates a unique admin account on the first boot of every VM. Backed by 24/7 cloudimg support.

What is included:

  • Redash 10.1.0.b50633 deployed from the official Docker Compose stack, pinned to redash/redash:10.1.0.b50633
  • The full multi-container stack: server (gunicorn), scheduler, scheduled_worker, adhoc_worker, PostgreSQL and Redis
  • nginx on :80 as a reverse proxy to the loopback Redash server, plus a static unauthenticated /health probe
  • PostgreSQL and Redis bound to the private Docker network only (never published on the host)
  • A per-VM admin account (email + password + API key) generated on first boot and recorded in a root-only file
  • A dedicated Azure data disk at /var/lib/redash holding the PostgreSQL metadata database and Redis data (Docker data-root relocated there)
  • redash.service, redash-firstboot.service, nginx.service and docker.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_B4ms (4 vCPU / 16 GiB RAM) is the recommended size - the multi-container Redash stack needs the memory. NSG inbound: allow 22/tcp from your management network and 80/tcp. Redash serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Redash by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size (Standard_B4ms or larger); 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 redash \
  --image <marketplace-image-urn> \
  --size Standard_B4ms \
  --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 redash --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

Redash runs as a Docker Compose stack managed by redash.service, behind nginx. Confirm the units are active:

systemctl is-active redash.service nginx.service docker.service

Each reports active. On first boot the image rotates every secret and creates a per-VM admin account.

redash.service, nginx.service and docker.service active with the dedicated data disk mounted

Step 5 - Confirm the container stack

The stack is six containers - the web server, the scheduler, two Celery workers, PostgreSQL and Redis:

docker compose -f /opt/redash/docker-compose.yml ps

All six report Up. PostgreSQL and Redis are attached to the private Docker network only and are never published on the host; only nginx on port 80 is reachable from outside.

The six Redash Compose containers running and the health, ping and app endpoints returning 200 through nginx

Step 6 - Confirm the health and ping endpoints

nginx serves a static, unauthenticated /health file for load balancers and probes, and proxies Redash's own /ping liveness endpoint:

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

It returns health=200. Redash's application ping returns PONG:

curl -s http://localhost/ping; echo

Step 7 - Retrieve your admin credentials

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

cat /root/redash-credentials.txt

This file contains REDASH_ADMIN_EMAIL (admin@cloudimg.local), REDASH_ADMIN_PASSWORD and REDASH_ADMIN_API_KEY. Store them somewhere safe.

Step 8 - Sign in to the Redash web UI

Browse to http://<vm-public-ip>/ and sign in as admin@cloudimg.local with the password from Step 7.

The Redash login page

After signing in you land on the Dashboards home, with the left navigation for Dashboards, Queries, Alerts and Create.

The Redash dashboards home after signing in

Open Create -> New Query to reach the query editor, where you write SQL against a connected data source, run it, and turn the result into a visualisation.

The Redash New Query editor

Under Settings -> Data Sources you connect Redash to your databases and APIs - PostgreSQL, MySQL, BigQuery, Redshift, Elasticsearch and many more.

The Redash Data Sources settings page

Step 9 - Verify the REST API with your API key

Every Redash user has an API key that authenticates REST calls without a session. Read the per-VM admin key from the credentials file and call the dashboards endpoint:

API=$(grep '^REDASH_ADMIN_API_KEY=' /root/redash-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'api=%{http_code}\n' -H "Authorization: Key $API" http://localhost/api/dashboards

It returns api=200. A request with a wrong key is rejected. To authenticate as a browser session instead, POST your admin email and password to the login form - for example curl -i -c cookies.txt -d 'email=admin@cloudimg.local' -d 'password=<REDASH_ADMIN_PASSWORD>' http://<vm-public-ip>/login returns a 302 redirect on success.

Step 10 - Confirm data lives on the dedicated disk

The PostgreSQL metadata database (users, queries, dashboards, cached results) and the Redis data live on the dedicated Azure data disk, so they survive OS changes and can be resized independently:

findmnt /var/lib/redash

The mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM. Docker's data-root is relocated under it, so every Redash named volume lands on the resizable disk.

Docker data-root on the dedicated /var/lib/redash disk and the admin API key round-trip returning 200

Inviting your team by email (SMTP setup)

The image does not ship with an outbound email server, because sending mail needs credentials for your own provider (SendGrid, Microsoft 365, Google Workspace, Amazon SES, or your own SMTP). Until you add them, Redash cannot send user invitations or alert emails. Set them once and both start working.

  1. Edit the Redash environment file and add your provider's settings. There is already a REDASH_MAIL_DEFAULT_SENDER line, so update it to a real address on your domain:

bash sudo nano /opt/redash/.env

REDASH_MAIL_SERVER=smtp.sendgrid.net REDASH_MAIL_PORT=587 REDASH_MAIL_USE_TLS=true REDASH_MAIL_USERNAME=apikey REDASH_MAIL_PASSWORD=<your-smtp-password-or-api-key> REDASH_MAIL_DEFAULT_SENDER=redash@yourdomain.com

For Microsoft 365 use smtp.office365.com on port 587 with TLS. For SendGrid the username is the literal word apikey and the password is your API key. If your provider uses SSL on port 465, set REDASH_MAIL_USE_SSL=true instead of the TLS line. Make sure no line has a trailing space after its value, as Docker reads those literally and the login will fail.

  1. Recreate the stack so every container, including the background workers that actually send the mail, picks up the new settings. A plain restart does not always reload them:

bash cd /opt/redash && sudo docker compose up -d --force-recreate

  1. Confirm it works. Invite a user from Settings -> Users, or send a quick test that prints the exact SMTP response (swap in an inbox you can check):

bash cd /opt/redash && sudo docker compose run --rm --entrypoint python server -c " import os, smtplib s = smtplib.SMTP(os.environ['REDASH_MAIL_SERVER'].strip(), int(os.environ['REDASH_MAIL_PORT'])) s.set_debuglevel(1); s.starttls() s.login(os.environ['REDASH_MAIL_USERNAME'].strip(), os.environ['REDASH_MAIL_PASSWORD'].strip()) s.sendmail(os.environ['REDASH_MAIL_DEFAULT_SENDER'].strip(), ['you@yourdomain.com'], 'Subject: Redash SMTP test\n\nWorks!') s.quit(); print('OK') "

Reaching external inboxes (Gmail, Outlook). Verifying a single sender is enough to send, but Gmail and Outlook often junk or reject mail from a domain that is not authenticated at your provider. If internal test mail arrives but invites to external addresses do not, set up domain authentication (in SendGrid: Settings -> Sender Authentication -> Authenticate Your Domain) and add the SPF and DKIM records it gives you to your DNS. Most providers show a per-message delivery log (SendGrid's is the Activity Feed) that tells you whether each invite was delivered, dropped or blocked, and why.

Invite links. The sign-in link in the invitation is built from REDASH_HOST in the same .env file. It is set to your VM's address on first boot; if you move Redash behind a custom domain or HTTPS, update REDASH_HOST to match so the links resolve.

If the test email works but invitations never arrive (and never appear in your provider's send logs). Redash sends the test email directly from the server container, but it sends invitation and alert emails through a background worker on its emails queue. Confirm a worker is assigned that queue. Open /opt/redash/docker-compose.yml, find the adhoc_worker service, and make sure its QUEUES line includes emails:

  adhoc_worker:
    ...
    environment:
      QUEUES: 'queries,emails,default,periodic'

If emails is missing, add it as above, then recreate the stack so the worker picks it up:

cd /opt/redash && sudo docker compose up -d --force-recreate

Resend the invitation and it will now be sent (and show up in your provider's activity log). Any invites you queued before the change may all send at once when the worker starts.

Building with Redash

Connect a data source (Settings -> Data Sources), write a query in the editor, and save it. Add a visualisation to the query - a chart, counter, pivot or table - then pin one or more visualisations onto a dashboard and share it with your team. Queries can be scheduled to refresh on an interval (handled by the scheduler and workers), and alerts can notify you when a value crosses a threshold. See the Redash documentation for the query language, data source options and API reference.

Maintenance

  • Admin users: add users and groups from Settings -> Users and Settings -> Groups in the web UI.
  • Backups: snapshot the /var/lib/redash data disk, or back up the PostgreSQL metadata database inside the postgres container.
  • Data: the metadata database and Redis data live under /var/lib/redash (Docker data-root).
  • Stack control: manage the stack with sudo systemctl restart redash.service, or with docker compose in /opt/redash.
  • TLS: Redash serves plain HTTP on port 80; front it with TLS (e.g. certbot) and your own domain before production use.
  • Upgrades: edit the pinned image tag in /opt/redash/docker-compose.yml, then sudo systemctl restart redash.service.
  • 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.