Add flight comparator web app with full scan pipeline
Full-stack flight price scanner built on fast-flights v3 (SOCS cookie bypass): Backend (FastAPI + SQLite): - REST API with rate limiting, Pydantic v2 validation, paginated responses - Scan pipeline: resolves airports, queries every day in the window, saves individual flights + aggregate route stats to SQLite - Background async scan processor with real-time progress tracking - Airport search endpoint backed by OpenFlights dataset - Daily scan window (all dates, not monthly samples) Frontend (React 19 + TypeScript + Tailwind CSS v4): - Dashboard with live scan status and recent scans - Create scan form: country mode or specific airports (searchable dropdown) - Scan detail page with expandable route rows showing individual flights (date, airline, departure, arrival, price) loaded on demand - AirportSearch component with debounced live search and multi-select Database: - scans → routes → flights schema with FK cascade and auto-update triggers - Migrations for schema evolution (relaxed country constraint) Tests: - 74 tests: unit + integration, isolated per-test SQLite DB - Confirmed flight fixtures in tests/confirmed_flights.json (50 real flights, BDS→FMM Ryanair + BDS→DUS Eurowings, scraped Feb 2026) - Integration tests parametrized from confirmed routes Docker: - Multi-stage builds, Compose orchestration, Nginx reverse proxy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
480
flight-comparator/docs/DEPLOYMENT.md
Normal file
480
flight-comparator/docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,480 @@
|
||||
# Flight Radar Web App - Deployment Guide
|
||||
|
||||
**Complete Docker deployment instructions for production and development environments.**
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Quick Start](#quick-start)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Docker Deployment](#docker-deployment)
|
||||
- [Manual Deployment](#manual-deployment)
|
||||
- [Environment Configuration](#environment-configuration)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Monitoring](#monitoring)
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Docker Compose (Recommended)
|
||||
|
||||
```bash
|
||||
# 1. Clone the repository
|
||||
git clone <repository-url>
|
||||
cd flight-comparator
|
||||
|
||||
# 2. Build and start services
|
||||
docker-compose up -d
|
||||
|
||||
# 3. Access the application
|
||||
# Frontend: http://localhost
|
||||
# Backend API: http://localhost:8000
|
||||
# API Docs: http://localhost:8000/docs
|
||||
```
|
||||
|
||||
That's it! The application is now running.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### For Docker Deployment
|
||||
- Docker Engine 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- 2GB RAM minimum
|
||||
- 5GB disk space
|
||||
|
||||
### For Manual Deployment
|
||||
- Python 3.11+
|
||||
- Node.js 20+
|
||||
- npm or yarn
|
||||
- 4GB RAM recommended
|
||||
|
||||
---
|
||||
|
||||
## Docker Deployment
|
||||
|
||||
### Production Deployment
|
||||
|
||||
#### 1. Configure Environment
|
||||
|
||||
```bash
|
||||
# Copy environment template
|
||||
cp .env.example .env
|
||||
|
||||
# Edit configuration
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Production Environment Variables:**
|
||||
```bash
|
||||
# Backend
|
||||
PORT=8000
|
||||
ALLOWED_ORIGINS=https://yourdomain.com
|
||||
|
||||
# Logging
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# Rate Limits (adjust based on traffic)
|
||||
RATE_LIMIT_SCANS=10
|
||||
RATE_LIMIT_AIRPORTS=100
|
||||
```
|
||||
|
||||
#### 2. Build Images
|
||||
|
||||
```bash
|
||||
# Build both frontend and backend
|
||||
docker-compose build
|
||||
|
||||
# Or build individually
|
||||
docker build -f Dockerfile.backend -t flight-radar-backend .
|
||||
docker build -f Dockerfile.frontend -t flight-radar-frontend .
|
||||
```
|
||||
|
||||
#### 3. Start Services
|
||||
|
||||
```bash
|
||||
# Start in detached mode
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Check status
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
#### 4. Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check backend health
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# Check frontend
|
||||
curl http://localhost/
|
||||
|
||||
# Check API endpoints
|
||||
curl http://localhost:8000/api/v1/scans
|
||||
```
|
||||
|
||||
### Development Deployment
|
||||
|
||||
```bash
|
||||
# Start with logs attached
|
||||
docker-compose up
|
||||
|
||||
# Rebuild after code changes
|
||||
docker-compose up --build
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manual Deployment
|
||||
|
||||
### Backend Deployment
|
||||
|
||||
```bash
|
||||
# 1. Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 2. Initialize database
|
||||
python database/init_db.py
|
||||
|
||||
# 3. Download airport data
|
||||
python -c "from airports import download_and_build_airport_data; download_and_build_airport_data()"
|
||||
|
||||
# 4. Start server
|
||||
python api_server.py
|
||||
```
|
||||
|
||||
Backend runs on: http://localhost:8000
|
||||
|
||||
### Frontend Deployment
|
||||
|
||||
```bash
|
||||
# 1. Navigate to frontend directory
|
||||
cd frontend
|
||||
|
||||
# 2. Install dependencies
|
||||
npm install
|
||||
|
||||
# 3. Build for production
|
||||
npm run build
|
||||
|
||||
# 4. Serve with nginx or static server
|
||||
# Option 1: Preview with Vite
|
||||
npm run preview
|
||||
|
||||
# Option 2: Use a static server
|
||||
npx serve -s dist -l 80
|
||||
```
|
||||
|
||||
Frontend runs on: http://localhost
|
||||
|
||||
---
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
### Backend Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `PORT` | `8000` | Backend server port |
|
||||
| `HOST` | `0.0.0.0` | Server bind address |
|
||||
| `DATABASE_PATH` | `cache.db` | SQLite database path |
|
||||
| `ALLOWED_ORIGINS` | `localhost` | CORS allowed origins |
|
||||
| `LOG_LEVEL` | `INFO` | Logging level |
|
||||
| `RATE_LIMIT_SCANS` | `10` | Scans per minute per IP |
|
||||
| `RATE_LIMIT_LOGS` | `30` | Log requests per minute |
|
||||
| `RATE_LIMIT_AIRPORTS` | `100` | Airport searches per minute |
|
||||
|
||||
### Frontend Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `VITE_API_BASE_URL` | `/api/v1` | API base URL (build time) |
|
||||
|
||||
**Note:** Frontend uses Vite proxy in development, and nginx proxy in production.
|
||||
|
||||
---
|
||||
|
||||
## Docker Commands Reference
|
||||
|
||||
### Managing Services
|
||||
|
||||
```bash
|
||||
# Start services
|
||||
docker-compose up -d
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
|
||||
# Restart services
|
||||
docker-compose restart
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f [service-name]
|
||||
|
||||
# Execute command in container
|
||||
docker-compose exec backend bash
|
||||
docker-compose exec frontend sh
|
||||
```
|
||||
|
||||
### Image Management
|
||||
|
||||
```bash
|
||||
# List images
|
||||
docker images | grep flight-radar
|
||||
|
||||
# Remove images
|
||||
docker rmi flight-radar-backend flight-radar-frontend
|
||||
|
||||
# Prune unused images
|
||||
docker image prune -a
|
||||
```
|
||||
|
||||
### Volume Management
|
||||
|
||||
```bash
|
||||
# List volumes
|
||||
docker volume ls
|
||||
|
||||
# Inspect backend data volume
|
||||
docker volume inspect flight-comparator_backend-data
|
||||
|
||||
# Backup database
|
||||
docker cp flight-radar-backend:/app/cache.db ./backup.db
|
||||
|
||||
# Restore database
|
||||
docker cp ./backup.db flight-radar-backend:/app/cache.db
|
||||
```
|
||||
|
||||
### Health Checks
|
||||
|
||||
```bash
|
||||
# Check container health
|
||||
docker ps
|
||||
|
||||
# Backend health check
|
||||
docker-compose exec backend python -c "import requests; print(requests.get('http://localhost:8000/health').json())"
|
||||
|
||||
# Frontend health check
|
||||
docker-compose exec frontend wget -qO- http://localhost/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Backend Issues
|
||||
|
||||
**Problem:** Backend fails to start
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs backend
|
||||
|
||||
# Common issues:
|
||||
# - Database not initialized: Rebuild image
|
||||
# - Port already in use: Change BACKEND_PORT in .env
|
||||
# - Missing dependencies: Check requirements.txt
|
||||
```
|
||||
|
||||
**Problem:** API returns 500 errors
|
||||
```bash
|
||||
# Check application logs
|
||||
docker-compose logs backend | grep ERROR
|
||||
|
||||
# Check database
|
||||
docker-compose exec backend ls -la cache.db
|
||||
|
||||
# Restart service
|
||||
docker-compose restart backend
|
||||
```
|
||||
|
||||
### Frontend Issues
|
||||
|
||||
**Problem:** Frontend shows blank page
|
||||
```bash
|
||||
# Check nginx logs
|
||||
docker-compose logs frontend
|
||||
|
||||
# Verify build
|
||||
docker-compose exec frontend ls -la /usr/share/nginx/html
|
||||
|
||||
# Check nginx config
|
||||
docker-compose exec frontend cat /etc/nginx/conf.d/default.conf
|
||||
```
|
||||
|
||||
**Problem:** API calls fail from frontend
|
||||
```bash
|
||||
# Check nginx proxy configuration
|
||||
docker-compose exec frontend cat /etc/nginx/conf.d/default.conf | grep proxy_pass
|
||||
|
||||
# Verify backend is accessible from frontend container
|
||||
docker-compose exec frontend wget -qO- http://backend:8000/health
|
||||
|
||||
# Check CORS configuration
|
||||
curl -H "Origin: http://localhost" -v http://localhost:8000/health
|
||||
```
|
||||
|
||||
### Database Issues
|
||||
|
||||
**Problem:** Database locked error
|
||||
```bash
|
||||
# Stop all services
|
||||
docker-compose down
|
||||
|
||||
# Remove database volume
|
||||
docker volume rm flight-comparator_backend-data
|
||||
|
||||
# Restart services (database will be recreated)
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
**Problem:** Database corruption
|
||||
```bash
|
||||
# Backup current database
|
||||
docker cp flight-radar-backend:/app/cache.db ./corrupted.db
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
|
||||
# Remove volume
|
||||
docker volume rm flight-comparator_backend-data
|
||||
|
||||
# Start services (fresh database)
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Application Logs
|
||||
|
||||
```bash
|
||||
# View all logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Backend logs only
|
||||
docker-compose logs -f backend
|
||||
|
||||
# Frontend logs only
|
||||
docker-compose logs -f frontend
|
||||
|
||||
# Last 100 lines
|
||||
docker-compose logs --tail=100
|
||||
|
||||
# Logs since specific time
|
||||
docker-compose logs --since 2024-01-01T00:00:00
|
||||
```
|
||||
|
||||
### Resource Usage
|
||||
|
||||
```bash
|
||||
# Container stats
|
||||
docker stats flight-radar-backend flight-radar-frontend
|
||||
|
||||
# Disk usage
|
||||
docker system df
|
||||
|
||||
# Detailed container info
|
||||
docker inspect flight-radar-backend
|
||||
```
|
||||
|
||||
### Health Monitoring
|
||||
|
||||
```bash
|
||||
# Health check status
|
||||
docker ps --filter "name=flight-radar"
|
||||
|
||||
# Backend API health
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# Check recent scans
|
||||
curl http://localhost:8000/api/v1/scans?limit=5
|
||||
|
||||
# Check logs endpoint
|
||||
curl "http://localhost:8000/api/v1/logs?limit=10"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Production Best Practices
|
||||
|
||||
### Security
|
||||
|
||||
1. **Use HTTPS:** Deploy behind a reverse proxy (nginx, Caddy, Traefik)
|
||||
2. **Environment Variables:** Never commit `.env` files
|
||||
3. **Update CORS:** Set proper `ALLOWED_ORIGINS`
|
||||
4. **Rate Limiting:** Adjust limits based on traffic
|
||||
5. **Secrets Management:** Use Docker secrets or external secret managers
|
||||
|
||||
### Performance
|
||||
|
||||
1. **Resource Limits:** Set memory/CPU limits in docker-compose.yml
|
||||
2. **Volumes:** Use named volumes for persistent data
|
||||
3. **Caching:** Enable nginx caching for static assets
|
||||
4. **CDN:** Consider CDN for frontend assets
|
||||
5. **Database:** Regular backups and optimization
|
||||
|
||||
### Reliability
|
||||
|
||||
1. **Health Checks:** Monitor `/health` endpoint
|
||||
2. **Restart Policy:** Use `restart: unless-stopped`
|
||||
3. **Logging:** Centralized logging (ELK, Loki, CloudWatch)
|
||||
4. **Backups:** Automated database backups
|
||||
5. **Updates:** Regular dependency updates
|
||||
|
||||
---
|
||||
|
||||
## Scaling
|
||||
|
||||
### Horizontal Scaling
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
backend:
|
||||
deploy:
|
||||
replicas: 3
|
||||
|
||||
# Add load balancer (nginx, HAProxy)
|
||||
load-balancer:
|
||||
image: nginx
|
||||
# Configure upstream servers
|
||||
```
|
||||
|
||||
### Vertical Scaling
|
||||
|
||||
```yaml
|
||||
services:
|
||||
backend:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '1'
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For issues and questions:
|
||||
- Check logs: `docker-compose logs`
|
||||
- Review documentation: `/docs` endpoints
|
||||
- Check health: `/health` endpoint
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-02-23
|
||||
**Version:** 2.0
|
||||
Reference in New Issue
Block a user