# E-Voting System - Docker Setup Guide Complete guide to running the e-voting system with Docker Compose. ## Prerequisites - Docker (20.10 or later) - Docker Compose (2.0 or later) - Git Verify installation: ```bash docker --version docker-compose --version ``` ## Quick Start ### 1. Clone and Navigate ```bash cd /path/to/e-voting-system ``` ### 2. Create Environment File Copy the example environment file: ```bash cp .env.example .env ``` Configure as needed in `.env`: ```env DB_HOST=mariadb DB_PORT=3306 DB_NAME=evoting_db DB_USER=evoting_user DB_PASSWORD=evoting_pass123 DB_ROOT_PASSWORD=rootpass123 BACKEND_PORT=8000 FRONTEND_PORT=3000 SECRET_KEY=your-secret-key-change-in-production DEBUG=true PYTHONUNBUFFERED=1 NEXT_PUBLIC_API_URL=http://localhost:8000 ``` ### 3. Start the Application ```bash docker-compose up -d ``` This will: - ✅ Build the backend (FastAPI) - ✅ Build the frontend (Next.js) - ✅ Start MariaDB database - ✅ Start all services with proper networking ### 4. Wait for Services to Be Ready Check service status: ```bash docker-compose ps ``` Expected output: ``` NAME STATUS PORTS evoting_db Up (healthy) 0.0.0.0:3306->3306/tcp evoting_backend Up (healthy) 0.0.0.0:8000->8000/tcp evoting_frontend Up (healthy) 0.0.0.0:3000->3000/tcp evoting_adminer Up 0.0.0.0:8080->8080/tcp ``` ### 5. Access the Application - **Frontend**: http://localhost:3000 - **Backend API**: http://localhost:8000 - **API Docs**: http://localhost:8000/docs - **Database Admin**: http://localhost:8080 ## Services ### MariaDB (Database) - **Container**: `evoting_db` - **Port**: 3306 (internal), 3306 (exposed) - **Database**: `evoting_db` - **User**: `evoting_user` - **Password**: `evoting_pass123` - **Volume**: `evoting_data` (persistent) Tables created automatically: - `voters` - User accounts - `elections` - Election definitions - `candidates` - Election candidates - `votes` - Cast votes - `blockchain_blocks` - Blockchain records (if applicable) ### Backend (FastAPI) - **Container**: `evoting_backend` - **Port**: 8000 (internal), 8000 (exposed) - **Framework**: FastAPI (Python 3.12) - **Volume**: `./backend` (live reload) - **Dependencies**: Installed via Poetry Available endpoints: - GET `/health` - Health check - GET `/docs` - Swagger UI - GET `/redoc` - ReDoc documentation - POST `/api/auth/register` - User registration - POST `/api/auth/login` - User login - GET/POST `/api/votes/*` - Voting endpoints - GET `/api/elections` - Election list - GET `/api/elections/{id}` - Election details ### Frontend (Next.js) - **Container**: `evoting_frontend` - **Port**: 3000 (internal), 3000 (exposed) - **Framework**: Next.js 15 (Node.js 20) - **Build**: Production build with optimizations - **API URL**: Configured to `http://localhost:8000` Routes: - `/` - Home page - `/auth/login` - Login - `/auth/register` - Registration - `/dashboard` - Voter dashboard - `/dashboard/votes/active` - Active elections - `/dashboard/votes/upcoming` - Upcoming elections - `/dashboard/votes/history` - Vote history - `/dashboard/blockchain` - Blockchain viewer ### Adminer (Optional Database UI) - **Container**: `evoting_adminer` - **Port**: 8080 - **Access**: http://localhost:8080 - **System**: MariaDB - **Server**: `mariadb` - **Username**: `evoting_user` - **Password**: `evoting_pass123` ## Common Commands ### Start Services ```bash # Start in foreground (see logs) docker-compose up # Start in background docker-compose up -d # Start specific service docker-compose up -d backend ``` ### Stop Services ```bash # Stop all services docker-compose stop # Stop and remove containers docker-compose down # Stop and remove all data docker-compose down -v ``` ### View Logs ```bash # View all logs docker-compose logs -f # View specific service logs docker-compose logs -f backend docker-compose logs -f frontend docker-compose logs -f mariadb # View last 50 lines docker-compose logs --tail 50 ``` ### Rebuild Services ```bash # Rebuild all services docker-compose build # Rebuild specific service docker-compose build --no-cache backend # Rebuild and restart docker-compose up -d --build ``` ### Access Container Shell ```bash # Backend shell docker-compose exec backend bash # Frontend shell docker-compose exec frontend sh # Database shell docker-compose exec mariadb bash ``` ### Database Operations ```bash # Connect to database docker-compose exec mariadb mysql -u evoting_user -p evoting_db # Password: evoting_pass123 # Backup database docker-compose exec mariadb mysqldump -u evoting_user -p evoting_db > backup.sql # Password: evoting_pass123 # Restore database docker-compose exec -T mariadb mysql -u evoting_user -p evoting_db < backup.sql # Password: evoting_pass123 ``` ### Health Check ```bash # Check service health docker-compose exec backend curl http://localhost:8000/health # View health in ps docker-compose ps # Manual database check docker-compose exec mariadb mariadb-admin ping -h localhost -u evoting_user -p # Password: evoting_pass123 ``` ## Troubleshooting ### Services Won't Start 1. **Check logs**: ```bash docker-compose logs ``` 2. **Check ports are available**: ```bash lsof -i :3000 lsof -i :8000 lsof -i :3306 ``` 3. **Remove conflicting containers**: ```bash docker-compose down docker container prune docker system prune ``` 4. **Rebuild services**: ```bash docker-compose build --no-cache docker-compose up -d ``` ### Database Connection Error 1. **Check database is healthy**: ```bash docker-compose ps mariadb # Should show "Up (healthy)" ``` 2. **Check database logs**: ```bash docker-compose logs mariadb ``` 3. **Wait longer for startup**: - MariaDB can take 30-60 seconds to fully initialize - Check health status with `docker-compose ps` 4. **Verify credentials in .env**: ```bash cat .env | grep DB_ ``` ### Backend Can't Reach Database 1. **Check network**: ```bash docker-compose exec backend ping mariadb ``` 2. **Check environment variables**: ```bash docker-compose exec backend env | grep DB_ ``` 3. **Verify connection string**: ```bash docker-compose exec backend python -c "from backend.config import settings; print(settings.database_url)" ``` ### Frontend Can't Reach Backend 1. **Check API URL configuration**: ```bash docker-compose logs frontend | grep API ``` 2. **Test backend availability**: ```bash docker-compose exec frontend curl http://backend:8000/health ``` 3. **Check NEXT_PUBLIC_API_URL**: - For Docker: `http://backend:8000` - For browser: `http://localhost:8000` ## Development Workflow ### Edit Code and Reload ```bash # Changes to backend are auto-reloaded (uvicorn with --reload) # Edit files in backend/ vim backend/routes/votes.py # Changes to frontend require rebuild # Edit files in frontend/ vim frontend/components/blockchain-viewer.tsx # Rebuild frontend only docker-compose build frontend docker-compose up -d frontend ``` ### Access Development Tools ```bash # Backend interactive Python docker-compose exec backend python # Frontend package management docker-compose exec frontend npm install package-name # Run frontend build docker-compose exec frontend npm run build ``` ### Database Initialization The database is automatically initialized on first run with: - `docker/init.sql` - Schema and tables - `docker/populate_past_elections.sql` - Sample data To reinitialize: ```bash docker-compose down -v docker-compose up -d mariadb # Wait for database to be healthy docker-compose up ``` ## Production Deployment ### Environment Configuration Create `.env` with production values: ```env # Change all sensitive values DB_PASSWORD=strong-random-password DB_ROOT_PASSWORD=strong-random-password SECRET_KEY=strong-random-secret-key # Disable debug DEBUG=false # Set production API URL NEXT_PUBLIC_API_URL=https://yourdomain.com # Change ports if needed BACKEND_PORT=8000 FRONTEND_PORT=3000 ``` ### Production Build ```bash # Pull latest code git pull origin main # Build images docker-compose build --no-cache # Start services docker-compose up -d # Verify docker-compose ps ``` ### Backup Strategy ```bash # Automated daily backup 0 2 * * * docker-compose exec -T mariadb mysqldump -u evoting_user -p"$PASSWORD" evoting_db > /backups/evoting_$(date +\%Y\%m\%d).sql # Manual backup docker-compose exec mariadb mysqldump -u evoting_user -p evoting_db > backup.sql ``` ### Monitoring ```bash # View resource usage docker stats # View all logs docker-compose logs -f --tail 100 # Check health status watch -n 5 docker-compose ps ``` ## Networking ### Service Discovery Services can communicate within the network: - Database: `mysql://evoting_user:evoting_pass123@mariadb:3306/evoting_db` - Backend API: `http://backend:8000` - Frontend: `http://frontend:3000` ### External Access From outside Docker: - Frontend: `http://localhost:3000` - Backend: `http://localhost:8000` - Database: `mysql://evoting_user:evoting_pass123@localhost:3306/evoting_db` - Adminer: `http://localhost:8080` ## Performance Tuning ### Database ```yaml # In docker-compose.yml, adjust mariadb service environment: MYSQL_MAX_CONNECTIONS: 100 INNODB_BUFFER_POOL_SIZE: 256M ``` ### Backend ```yaml # Increase Python process command: uvicorn backend.main:app --host 0.0.0.0 --port 8000 --workers 4 ``` ### Frontend ```yaml # Increase Node memory if needed environment: NODE_OPTIONS: --max-old-space-size=4096 ``` ## Security Recommendations 1. **Change default passwords** in `.env` 2. **Use strong SECRET_KEY** (generate with `openssl rand -hex 32`) 3. **Enable HTTPS** with reverse proxy (nginx) 4. **Restrict database access** (bind to local network only) 5. **Use secrets management** (Docker Secrets, HashiCorp Vault) 6. **Regular backups** with offsite storage 7. **Keep images updated** with `docker-compose pull && docker-compose up -d --build` ## Additional Resources - Docker Compose Docs: https://docs.docker.com/compose/ - FastAPI Docs: https://fastapi.tiangolo.com/ - Next.js Docs: https://nextjs.org/docs - MariaDB Docs: https://mariadb.com/docs/ ## Support For issues, check: 1. Docker logs: `docker-compose logs` 2. Service health: `docker-compose ps` 3. Network connectivity: `docker-compose exec service-name ping other-service` 4. Environment variables: `docker-compose config` --- **Version**: 1.0.0 **Last Updated**: 2025-11-07 **Maintainer**: E-Voting Team