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>
481 lines
8.8 KiB
Markdown
481 lines
8.8 KiB
Markdown
# 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
|