Plotly Dash
Overview
Plotly Dash is the popular open source Python framework for building interactive, data-driven web applications and analytical dashboards without writing any JavaScript. You describe a dashboard's layout and interactive behavior entirely in Python: Plotly charts, controls such as dropdowns, sliders and date pickers, and callbacks that recompute the charts and tables whenever a user changes an input. Dash serves the result as a browsable analytics application that updates live in the browser.
This SecureAnyCloud image ships Dash as a finished, ready-to-run dashboard server, not a bare framework. A sample dashboard, the Global Development Explorer, is bundled and live on the first boot of every VM. It combines a Plotly bubble chart, a ranked bar chart and a data table, driven by a metric dropdown, a region dropdown and a year slider over the Gapminder development-indicators dataset.
The dashboard listens only on loopback and is never exposed directly. nginx fronts it on port 80. The unauthenticated /health probe stays open for load balancers, and everything else requires the admin password.
What you get:
- Dash 4.4.0, Plotly 6.9.0 and pandas 2.2.3 in a Python 3.12 virtual environment at /opt/plotly-dash/venv, under
/opt/plotly-dash, run by an unprivilegedplotlydashsystem account - A bundled, interactive sample dashboard at
/opt/plotly-dash/app/dashboard.py(the Global Development Explorer) - gunicorn (three workers, the WSGI app.server), not the Flask development server, serving the Dash app in production on loopback
:5000(127.0.0.1:5000) and managed byplotly-dash.service - An nginx reverse proxy on
:80(TCP 80) with HTTP Basic Authentication in front of the dashboard, and an open/healthprobe - A unique per-VM admin password, generated at first boot and stored in a root-only file
plotly-dash.serviceandnginx.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region
- Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. Scale up for heavier dashboards or more concurrent users.
- NSG inbound rules: allow
22/tcpfrom your management network and80/tcpfrom the browsers that reach the dashboard. For public exposure, front port 80 with TLS (see Enabling HTTPS).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Plotly Dash by SecureAnyCloud, and select Create.
On the Basics tab, 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 select Review + create and Create.
Step 2 - Deploy from the Azure CLI
Accept the Marketplace terms once per subscription, then create the VM and open port 80:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:plotly-dash-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name plotly-dash \
--image sac1647283583153:plotly-dash-ubuntu-24-04:default:latest \
--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 plotly-dash --port 80 --priority 1010Step 3 - Connect to your VM
Connect to the VM over SSH:
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Check both services and the health endpoint:
systemctl is-active plotly-dash.service nginx.service curl -s http://127.0.0.1/healthBoth services report active, and the /health endpoint returns ok. gunicorn serves the dashboard on loopback 127.0.0.1:5000, and it is reachable only through nginx on port 80.
Step 5 - Retrieve your admin password
The password is generated uniquely on the first boot of your VM and written to a root-only file. Read it:
sudo cat /root/plotly-dash-credentials.txtThe DASH_ADMIN_PASSWORD value is the password. Sign in as admin with it. Without credentials, the dashboard returns 401. With them, it returns 200.
Step 6 - Open the dashboard
Browse to http://<vm-public-ip>/ and sign in as admin with the password from Step 5. The bundled Global Development Explorer loads immediately. It shows a Plotly bubble chart of life expectancy versus GDP per capita, with summary tiles above it.
Step 7 - Explore interactively
Every control on the dashboard fires a Dash callback that recomputes the charts server-side and updates them live. Change the Region dropdown to a single continent. The bubble chart filters to that region, and its title updates:
Drag the Year slider back to 1952. The same chart redraws with the historical data, where life expectancy and GDP per capita were far lower:
Step 8 - The ranked view
Scroll down to the ranked bar chart and the top-10 data table. Both are driven by the same Metric, Region and Year controls:
Step 9 - Confirm the runtime and interactivity
Confirm the pinned versions and that gunicorn serves the app in production:
for p in dash plotly pandas gunicorn; do printf '%-10s %s\n' "$p" "$(/opt/plotly-dash/venv/bin/pip show $p | awk '/^Version:/{print $2}')"; doneThis prints dash 4.4.0, plotly 6.9.0, pandas 2.2.3 and gunicorn 23.0.0.
You can also call the interactive callback endpoint directly with the admin credentials. Two different inputs return two different figures, which shows that the dashboard reacts to input:
PASS=$(sudo grep '^DASH_ADMIN_PASSWORD=' /root/plotly-dash-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'authenticated dashboard: HTTP %{http_code}\n' -u "admin:$PASS" http://127.0.0.1/
curl -s -u "admin:$PASS" http://127.0.0.1/_dash-layout | head -c 80; echoShip your own dashboard
The image is a production Dash host, so you can replace the bundled sample with your own application. Edit /opt/plotly-dash/app/dashboard.py, or drop in your own module and point gunicorn at it. Keep a module-level server = app.server so gunicorn can serve the app. Then install any extra packages and restart:
sudo -u plotlydash /opt/plotly-dash/venv/bin/pip install <your-extra-packages>
sudo systemctl restart plotly-dash.serviceThe systemd unit runs gunicorn --workers 3 --bind 127.0.0.1:5000 dashboard:server from /opt/plotly-dash/app. To match your app, adjust the worker count or module name in /etc/systemd/system/plotly-dash.service, then run sudo systemctl daemon-reload && sudo systemctl restart plotly-dash.service.
Pass environment variables to your app through /etc/plotly-dash/plotly-dash.env.
Enabling HTTPS
For production, terminate TLS at nginx with a real domain that points at the VM's public IP. Install certbot and request a certificate, replacing the domain with your own:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comcertbot edits the nginx site at /etc/nginx/sites-available/sac-plotly-dash to add the TLS listener, and it arranges automatic renewal.
Backup and maintenance
The admin password lives in the nginx htpasswd file /etc/nginx/.plotly-dash.htpasswd. Rotate it with sudo htpasswd /etc/nginx/.plotly-dash.htpasswd admin.
Your dashboard code and any data live under /opt/plotly-dash/app. Back that directory up if you customize it.
Keep the OS patched with sudo apt update && sudo apt upgrade. Unattended security upgrades are enabled by default. Restart the server cleanly with sudo systemctl restart plotly-dash.service, and read its logs with sudo journalctl -u plotly-dash.service.
Support
24/7 SecureAnyCloud support backs this image. Contact us by email or chat for help with building and serving Dash dashboards, production tuning, authentication, TLS and maintenance.
All product and company names are trademarks or registered trademarks of their respective holders. Their use does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Plotly Dash on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com