# MANG Service - Deployment Guide ## Overview MANG is a geolocation-aware RSS news aggregator built with Go, SQLite, and Docker. **Features:** - Automated RSS ingestion (configurable interval) - Automatic geocoding based on location keywords - RESTful API for news retrieval - Health checks for monitoring - Persistent data storage with SQLite --- ## Local Development ### Prerequisites - Docker & Docker Compose - Go 1.21+ (if building locally) ### Environment Configuration 1. Copy `.env.example` to `.env` and customize: ```bash cp .env.example .env ``` 2. Edit `.env` with your settings: ```env DB_PATH=/data/mang.db RSS_FEED_URL=https://news.ycombinator.com/rss INGEST_INTERVAL_MINUTES=5 LOCATIONS_PATH=/app/data/locations.json PORT=8080 ``` ### Running Locally with Docker Compose ```bash # Build and start the service docker compose up -d --build # View logs docker compose logs -f # Check health curl http://localhost:8080/health # Get latest news curl http://localhost:8080/news # Stop the service docker compose down ``` ### Building Manually ```bash # Build the Go binary go mod tidy CGO_ENABLED=0 go build -o mang-service . # Run locally export DB_PATH=./test.db export RSS_FEED_URL=https://news.ycombinator.com/rss export INGEST_INTERVAL_MINUTES=5 export LOCATIONS_PATH=./data/locations.json export PORT=8080 ./mang-service ``` --- ## Production Deployment (j4bitzs.cloud) ### Prerequisites - Traefik reverse proxy running - Traefik network: `docker network create traefik` - DNS A record: `mang.j4bitzs.cloud` → server IP ### Deployment Steps 1. **Clone/upload the repository to the server:** ```bash scp -r mang-service/ user@j4bitzs.cloud:/opt/mang-service/ ``` 2. **Ensure the `data/` directory exists with `locations.json`:** ```bash cd /opt/mang-service ls -la data/locations.json ``` 3. **Deploy with Traefik:** ```bash docker compose -f docker-compose.prod.yml up -d --build ``` 4. **Verify deployment:** ```bash # Check container status docker ps | grep mang-service # Check logs docker logs -f mang-service # Test health endpoint curl https://mang.j4bitzs.cloud/health # Test news endpoint curl https://mang.j4bitzs.cloud/news ``` ### Expected Health Response ```json { "status": "healthy", "database": "ok", "locations_loaded": 42, "locations_status": "ok" } ``` **Status codes:** - `healthy` - All systems operational - `degraded` - DB accessible but no locations loaded - `unhealthy` - Database connection failed (returns 503) --- ## Environment Variables Reference | Variable | Default | Description | |----------|---------|-------------| | `DB_PATH` | `/data/mang.db` | SQLite database file path | | `RSS_FEED_URL` | `https://news.ycombinator.com/rss` | RSS feed to ingest | | `INGEST_INTERVAL_MINUTES` | `5` | Minutes between RSS updates | | `LOCATIONS_PATH` | `/app/data/locations.json` | Path to locations keywords file | | `PORT` | `8080` | HTTP server port | --- ## API Endpoints ### `GET /health` Health check endpoint. **Response:** ```json { "status": "healthy", "database": "ok", "locations_loaded": 42, "locations_status": "ok" } ``` ### `GET /news` Get latest 20 news items with geocoded locations. **Response:** ```json [ { "id": 1, "title": "Example News Title", "link": "https://example.com/article", "published_at": "2026-04-05T14:30:00Z", "created_at": "2026-04-05T14:35:00Z", "latitude": 40.7128, "longitude": -74.0060, "location_name": "New York" } ] ``` --- ## Monitoring ### Docker Health Checks The container includes a built-in healthcheck that runs every 30 seconds: ```bash # Check health status docker inspect mang-service | grep -A 10 Health ``` ### Traefik Dashboard Access Traefik dashboard to monitor: - TLS certificate status - Request metrics - Backend health --- ## Troubleshooting ### Container won't start ```bash # Check logs docker logs mang-service # Verify volume permissions docker exec mang-service ls -la /data ``` ### Health check fails ```bash # Test from inside container docker exec mang-service wget -O- http://localhost:8080/health # Check database docker exec mang-service ls -la /data/mang.db ``` ### No locations loaded Verify `data/locations.json` exists and is mounted correctly: ```bash docker exec mang-service cat /app/data/locations.json ``` --- ## Updating the Service ```bash # Pull latest code git pull # Rebuild and restart docker compose -f docker-compose.prod.yml up -d --build # Clean up old images docker image prune -f ``` --- ## Backup & Recovery ### Backup Database ```bash # Copy database from volume docker cp mang-service:/data/mang.db ./backup-$(date +%Y%m%d).db ``` ### Restore Database ```bash # Stop service docker compose -f docker-compose.prod.yml down # Restore database docker run --rm -v mang-data:/data -v $(pwd):/backup alpine \ cp /backup/backup-20260405.db /data/mang.db # Start service docker compose -f docker-compose.prod.yml up -d ``` --- ## Production Checklist - [ ] DNS record `mang.j4bitzs.cloud` points to server - [ ] Traefik network exists: `docker network create traefik` - [ ] `data/locations.json` file is present - [ ] Environment variables configured (if needed) - [ ] Container deployed: `docker compose -f docker-compose.prod.yml up -d --build` - [ ] Health check passes: `curl https://mang.j4bitzs.cloud/health` - [ ] TLS certificate issued (check Traefik logs) - [ ] News endpoint works: `curl https://mang.j4bitzs.cloud/news` --- ## Support For issues or questions, check: - Container logs: `docker logs -f mang-service` - Traefik logs: `docker logs -f traefik` - Database integrity: `docker exec mang-service sqlite3 /data/mang.db "PRAGMA integrity_check;"`