Voila on Ubuntu 24.04 on Azure User Guide
Overview
Voila turns a Jupyter notebook into a standalone interactive dashboard web app. It executes the notebook with a live Python kernel and serves only the rendered output - charts, tables and interactive widgets - while hiding the code cells, so anyone can open the result in a browser without seeing or editing the source. Because the kernel stays running, ipywidgets controls such as sliders and dropdowns remain fully interactive and re-render the results in real time over a websocket. The cloudimg image installs Voila 0.5.12 in a dedicated Python virtualenv, serves a bundled ipywidgets demo dashboard as a systemd service bound to loopback behind an nginx reverse proxy on port 80 with HTTP Basic auth, and generates a unique login password on the first boot of every VM. Backed by 24/7 cloudimg support.
What is included:
- Voila 0.5.12 in a Python virtualenv at
/opt/voila/venv(with ipywidgets, ipykernel, numpy, matplotlib and pandas) - A bundled interactive demo dashboard at
/opt/voila/demo.ipynb- an ipywidgets notebook whose sliders drive a live matplotlib chart - nginx on
:80fronting the loopback Voila server with HTTP Basic auth and websocket proxying (Voila uses a websocket for the live kernel) voila.service+nginx.serviceas systemd units, enabled and active, with a per-VM Basic-auth password rotated on first boot- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point; scale up for heavier notebooks. NSG inbound: allow 22/tcp from your management network and 80/tcp for the dashboard (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 Voila 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). Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name voila \
--image <marketplace-image-urn> \
--size Standard_B2s \
--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 voila --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 voila.service nginx.service
Both services report active. Voila binds the notebook server to loopback 127.0.0.1:8866 and nginx publishes it on port 80 - the loopback binding means the only public surface is the authenticated nginx proxy.

Step 5 - Retrieve your password
The admin password is generated uniquely on the first boot of your VM and written to a root-only file:
sudo cat /root/voila-credentials.txt
This file contains VOILA_ADMIN_USER (admin) and VOILA_ACCESS_PASSWORD, plus the dashboard URL. Store the password somewhere safe.

Step 6 - Check the health endpoint and the auth wall
nginx serves an unauthenticated health endpoint for load balancers and probes, and requires the per-VM password for everything else:
curl -s http://localhost/health
It returns ok. Requesting the dashboard itself without credentials returns 401; with the per-VM password it returns 200.

Step 7 - Open the interactive dashboard
Browse to http://<vm-public-ip>/ and sign in as admin with the password from Step 5. Voila executes the bundled notebook and serves it as an interactive dashboard - the title, the slider controls and a live chart, with no code cells visible.

Move the Frequency, Amplitude or Noise slider and the chart re-renders instantly - the ipywidgets controls stay live because Voila keeps the Jupyter kernel running behind the scenes.

The chart itself is drawn by matplotlib inside the running kernel and streamed to the browser as it updates.

Step 8 - Confirm the dashboard from the command line
Voila serves the rendered dashboard behind the same Basic auth. Confirm it is serving - substitute your password from Step 5 for <VOILA_ACCESS_PASSWORD>:
curl -s -u admin:<VOILA_ACCESS_PASSWORD> http://localhost/ | grep -oiE 'voila|jupyter-widgets|Interactive Dashboard' | sort | uniq -c
The rendered page carries the Voila runtime, the jupyter-widgets manager and the dashboard title, proving the notebook was executed by a live kernel and served as HTML.

Because Voila has no login of its own, the nginx proxy is the only trust boundary. Without the per-VM password every request is rejected:

Step 9 - Serve your own notebook
Voila serves the single notebook at /opt/voila/demo.ipynb. To publish your own dashboard, replace that file with any Jupyter notebook (.nbconvert-compatible, using ipywidgets for interactivity), then restart the service:
# copy your notebook in, keeping the same path voila serves:
sudo cp my-dashboard.ipynb /opt/voila/demo.ipynb
sudo chown voila:voila /opt/voila/demo.ipynb
sudo systemctl restart voila
Install any extra Python packages your notebook needs into the bundled virtualenv:
sudo /opt/voila/venv/bin/pip install <your-packages>
sudo systemctl restart voila
Voila re-executes the notebook on each page load, so your latest saved version is always what visitors see.
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 use the companion cloudimg nginx-ssl-certbot image as a TLS reverse proxy, or install certbot and extend the existing nginx site with a listen 443 ssl; server block. Keep Voila bound to loopback so the only public surface is the authenticated, TLS-terminated proxy, which already forwards the websocket Voila needs for its live kernel.
Maintenance
- Your dashboard: replace
/opt/voila/demo.ipynb(owned byvoila:voila) andsudo systemctl restart voila. - Packages: install into
/opt/voila/venvwith itspip. - Password: the per-VM password lives in
/root/voila-credentials.txt; to rotate it, regenerate the htpasswd withsudo htpasswd -B /etc/nginx/.htpasswd admin. - Upgrades:
sudo /opt/voila/venv/bin/pip install -U voilathensudo systemctl restart voila. - 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.