Web application for visualizing WHOI Spray autonomous underwater glider deployments. Built with Dash, Plotly, and Flask. Displays real-time and archived glider tracks, sensor profiles, and research publications.
The canonical production site is https://gliders.whoi.edu/. The Dash app is served at the site root behind Apache, while the legacy static /data/ tree is still served directly by Apache from /var/www/gliders.whoi.edu/data.
For host setup, Apache configuration, and deploy operations, see DEPLOYMENT.md. For the JSON-to-NetCDF ingest/cache layout, see DATA_SCHEMA.md.
The app runs in Docker on racing at /opt/gliderapp.
ssh racing
cd /opt/gliderapp
git fetch && git pull
docker compose up --build --force-recreate -dThis builds a Python 3.12 image, installs dependencies, starts the Dash app with gunicorn on port 8050, runs the data-watcher ingest process, and starts the GoatCounter analytics service. The containers restart automatically unless explicitly stopped.
If the codebase changes, these are also the steps needed to deploy the code changes.
Apache serves https://gliders.whoi.edu/ publicly and proxies Dash requests to the gliderapp container on localhost port 8050.
- Port: 8050
- WSGI server: gunicorn
- Volumes:
gliderappmounts/srv/dataat/app/dataread-only and./configat/app/configread-only.data-watchermounts/srv/data/syncread-only and/srv/data/netcdfread-write so it can maintain the NetCDF cache.goatcounterstores analytics data in/srv/data/analytics. - Environment:
gliderappanddata-watcherload required production settings fromprod.env
Config files live in config/ and are mounted into the container at runtime. Changes take effect after restarting the container (docker compose up --force-recreate -d).
| File | Purpose |
|---|---|
config/homepage.html |
Home page content (rendered as sanitized HTML) |
config/datapage.html |
Data page content (rendered as sanitized HTML) |
config/people.yml |
Team members — names, roles, emails, websites, and portrait image filenames |
config/assets/people-imgs/ |
Portrait images referenced by people.yml |
config/map_config.yml |
Map region definitions (labels, enable flags, glider marker image) |
config/publications.html |
Publications list (generated by the bibtex module — see below) |
The app's data flow is documented in DATA_SCHEMA.md. In production, /srv/data/sync contains source *_web.json files, and data-watcher maintains generated NetCDF cache files in /srv/data/netcdf. The gliderapp container reads /srv/data read-only at /app/data.
Historical static pages, generated plot images, and directory indexes under https://gliders.whoi.edu/data/ are not served by Dash. Apache serves that legacy tree directly from /var/www/gliders.whoi.edu/data, and those files are updated by external processing outside this repo. Several app links intentionally point into that /data/ tree.
Production settings are committed in prod.env and loaded by gliderapp and data-watcher. Update prod.env when deployment defaults change.
| Variable | Default | Description |
|---|---|---|
PROD |
1 |
Enables production Dash routing settings |
DEBUG |
0 |
Debug mode |
SUBPATH |
empty | External URL prefix used for Dash requests, nav links, and static HTML asset paths. Empty means the app is served at the site root. |
PORTRAITS_DEFAULT |
default.jpg |
Fallback portrait image |
PUBLICATIONS_HTML_PATH |
config/publications.html |
Path to publications HTML |
HOME_HTML_PATH |
config/homepage.html |
Path to home page HTML |
DATAPAGE_HTML_PATH |
config/datapage.html |
Path to data page HTML |
DATA_DIR |
/app/data/sync |
Source *_web.json directory for data-watcher; defaults to ./data/sync for the app when unset |
NETCDF_DIR |
/app/data/netcdf |
Generated NetCDF cache directory for data-watcher and the app |
TRACKS_NETCDF |
tracks.nc |
Aggregate tracks-only NetCDF used for map loading |
POLL_INTERVAL |
300 |
Seconds between data-watcher source scans |
ANALYTICS_ENDPOINT |
https://analytics.gliders.whoi.edu |
GoatCounter endpoint. Leave unset to disable analytics injection. |
Install dependencies, then run the app directly with Python:
python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
PROD=0 DEBUG=1 python src/app.pyThe app will be available at http://localhost:8050. By default, local runs look for source data in ./data/sync and NetCDF cache files in ./data/netcdf; set DATA_DIR and NETCDF_DIR if your local data lives elsewhere.
A fresh clone does not include local glider data. To exercise map/profile pages locally, point DATA_DIR and NETCDF_DIR at a copied or mounted data tree with the CSV metadata files and generated NetCDF cache described in DATA_SCHEMA.md.
The bibtex/ directory contains a pipeline for converting a BibTeX bibliography into formatted HTML for the publications page.
- pandoc — install with
sudo apt install pandoc pandoc-citeproc(Debian/Ubuntu) - Python 3 environment with
beautifulsoup4andlxml
./bibtex/bib2html.sh bibtex/input/refs.bibThis generates bibtex/output/publications.html. To write directly to config:
./bibtex/bib2html.sh bibtex/input/refs.bib config/publications.html- pandoc converts the
.bibfile to HTML using the AGU citation style (american-geophysical-union.csl). Thefrontmatter.mdfile includesnocite: '@*'so all entries are rendered. - reformat.py post-processes the HTML:
- Groups references under year headings (newest first)
- Cleans up DOI links (
https://doi.org/10.xxxx/yyy→doi: 10.xxxx/yyy) - Bolds author names listed in
bibtex/input/bold_authors.txt - Strips
<html>/<body>tags for embedding
bibtex/
├── input/
│ ├── refs.bib # Main bibliography
│ └── bold_authors.txt # Authors to bold (one per line, e.g. "Todd, R. E.")
├── output/
│ └── publications.html # Generated output
├── american-geophysical-union.csl # Citation style
├── frontmatter.md # Pandoc frontmatter
├── bib2html.sh # Conversion script
└── reformat.py # Post-processing script
- Edit
bibtex/input/refs.bib(add/remove BibTeX entries) - Run
./bibtex/bib2html.sh bibtex/input/refs.bib config/publications.html - Commit and deploy
docker compose up --force-recreate -d