Forecasts for snorkeling conditions worldwide. Django backend, Tailwind UI, and a lightweight Docker deploy.
Live
- Website: https://snorkelforecast.com
Quick Start
- Install deps:
uv sync - Run dev server:
uv run python snorkelforecast/manage.py runserver - Tailwind (dev):
npm run tailwind:watch
Project Layout
- Django project:
snorkelforecast/(settings, manage.py) - App:
conditions/(views, urls, templates) - Static:
snorkelforecast/static/(Tailwind input/output, UI CSS); rootstatic/for shared assets - Templates:
conditions/templates/conditions/(base + views)
Environment
- Copy
.env.exampleto your runtime environment and set:SECRET_KEY: required for productionDEBUG:falsein productionALLOWED_HOSTS: comma-separated hostnamesCSRF_TRUSTED_ORIGINS: comma-separated origins (https URLs)PRODUCTION: set to enable/persistent/db.sqlite3CACHE_TTL: seconds for view cacheENABLE_OSM_IMPORT:trueto enable automatic OSM location discoveryUSE_POSTGIS:trueto use PostGIS instead of SQLite (production)
Common Commands
- Install:
uv sync - Lint:
uv run ruff check . - Format:
uv run ruff format . - Migrate:
uv run python snorkelforecast/manage.py makemigrations && uv run python snorkelforecast/manage.py migrate - Test:
uv run python snorkelforecast/manage.py test - Run:
uv run python snorkelforecast/manage.py runserver
Tailwind
- Dev:
npm run tailwind:watch - Build (CI/Docker):
npm run tailwind:build- Dockerfile also downloads the Tailwind standalone binary and builds
snorkelforecast/static/css/output.css.
- Dockerfile also downloads the Tailwind standalone binary and builds
Docker
- Build:
docker build -t snorkelforecast . - Run:
docker run -p 8000:8000 --env-file .env snorkelforecast - The container runs migrations, collects static, and starts Gunicorn via
startup.sh. - Development with OSM import:
docker-compose -f docker-compose.dev.yml up
OSM Import System
- Automatic Discovery: Discovers snorkeling spots worldwide from OpenStreetMap
- Tile-Based: Processes the globe in Web Mercator tiles for scalability
- Confidence Scoring: Rates locations by snorkeling suitability (0-1)
- Multiple Endpoints: Round-robin between Overpass API mirrors
- Docker Ready: Fully integrated with container deployment
OSM Commands:
- Create tile queue:
uv run python snorkelforecast/manage.py import_osm_tiles --create-tiles --zoom 8 --country-bbox "35,-10,45,5" - Import locations:
uv run python snorkelforecast/manage.py import_osm_tiles --batch-size 10 - Health check: Visit
/health/for system status including OSM import progress
Deployment
- GitHub Actions runs lint and tests on
master/mainpushes.
-
Environment Setup:
cp .env.example .env # Edit .env with your production values -
Required Environment Variables:
SECRET_KEY="your-production-secret-key-here" DEBUG="false" ALLOWED_HOSTS="yourdomain.com,www.yourdomain.com" CSRF_TRUSTED_ORIGINS="https://yourdomain.com,https://www.yourdomain.com" PRODUCTION="true"
-
Deploy with Docker Compose:
docker-compose up -d
-
Initial Data Migration:
docker-compose exec snorkelforecast uv run python snorkelforecast/manage.py migrate_popular_locations -
Health Check:
curl https://yourdomain.com/health/
- Lazy Loading: Locations are discovered and cached on-demand
- OpenStreetMap Integration: Access to worldwide snorkeling locations
- 6-Hour Weather Caching: Reduced API calls and rate limit handling
- Smart Search: Find locations by name, type, or region
- Persistent Database: SQLite with persistent volume in production
- Health Checks: Docker health monitoring endpoint
- Configurable Caching: Environment-based cache TTL settings
- Error Handling: Graceful degradation with stale data fallbacks
- Health check endpoint:
/health/ - Database and cache status monitoring
- Automatic migration of popular locations
- Background scheduler for data updates
- Coolify (or similar) can watch the repo and deploy on push. Ensure env vars are set in the platform.
Security
- Do not commit real secrets.
SECRET_KEYmust be provided via environment in production. DEBUG=falseand a strictALLOWED_HOSTS/CSRF_TRUSTED_ORIGINSin production.- WhiteNoise serves static files; run
collectstaticin builds. .gitignoreincludes.env,*.sqlite*, andstaticfiles/.- If
db.sqlite3is tracked locally, avoid using it for real data; prefer ephemeral dev data only.
Contributing
- Keep changes small and focused. Run Ruff before pushing.
- Write tests in
conditions/tests/for new functionality. - Conventional commits (e.g.,
feat: ...,fix: ...) encouraged.
License
- See repository license or contact maintainers if unspecified.
