114386a1b2e5e02021293cc8b0f0eb5477a7c9e0
Publish Container / publish (push) Successful in 3m33s
- Plain-language meaning for common NWS products, shown in the row and expanded view - Details column: reason, area, severity, effective window; click for full text/instructions - New alerts log area, severity, urgency, certainty and sender - Older entries are filled in from NWS by alert id (cached in data/alert-details.json); alerts NWS no longer serves fall back to the built-in meaning Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Weather App
Self-hosted weather app with animated radar. No API keys required.
Data Sources
- Weather: Open-Meteo — free, no key
- Radar: RainViewer — free, no key
- Map tiles: CartoDB Dark Matter (free, no key)
Features
- Current conditions (temp, feels-like, wind, humidity, pressure, visibility, UV, clouds)
- 24-hour hourly forecast
- 7-day daily forecast
- Embedded radar panel on the conditions page
- Full-page radar tab with animated past frames + nowcast
- Animated radar timeline with play/pause controls
- City search with autocomplete + GPS geolocation
- Auto-pans radar to searched city
- Dark mode (follows system preference)
- Responsive / mobile-friendly
Quick Start
docker compose up -d
App runs at http://localhost:3000
Pull prebuilt image
docker pull ghcr.io/nmemmert/weather:latest
docker run -d --name weather-app -p 3000:3000 ghcr.io/nmemmert/weather:latest
If the package is private, log in first:
echo "<GITHUB_PAT>" | docker login ghcr.io -u nmemmert --password-stdin
Change the port
Edit docker-compose.yml:
ports:
- "8080:3000"
Run without Docker
cd app
npm install
node server.js
Project structure
weather-app/
├── docker-compose.yml
└── app/
├── Dockerfile
├── package.json
├── server.js # Express — proxies Open-Meteo, RainViewer
└── public/
├── index.html
├── style.css
└── app.js # Weather render + dual Leaflet radar
Nginx reverse proxy
server {
listen 80;
server_name weather.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Languages
JavaScript
55.3%
HTML
26.4%
CSS
18.3%