de9cb41d8b6b35cfa385f0666ac570f7cdb089a8
Publish Container / publish (push) Successful in 2m55s
The alert history log was only populated inside the subscriber loop, so it stayed empty when no push subscriptions existed. Now the cron always checks and logs active NWS alerts for the dashboard location before the subscriber early-return. Co-Authored-By: Claude Sonnet 4.6 <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%