mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-02-19 20:18:42 -06:00
- Add organized screenshot sections for better visual presentation - Include all 12 available screenshots from assets/screenshots/ - Group screenshots into logical categories: * Core Application Views (Dashboard, Projects, Tasks, Clients) * Management & Analytics (Reports, Visual Analytics, Task Management, Admin) * Data Entry & Creation (Log Time, New Task, New Client, New Project) - Improve visual layout with proper spacing and responsive design - Enhance user experience by showcasing full application capabilities
282 lines
8.6 KiB
Markdown
282 lines
8.6 KiB
Markdown
# Container Startup with Automatic Migration Detection
|
|
|
|
This document explains how the TimeTracker Docker container automatically detects database state and chooses the correct migration strategy during startup.
|
|
|
|
## 🎯 **Automatic Migration Detection**
|
|
|
|
The container startup system automatically detects the current state of your database and chooses the appropriate migration strategy:
|
|
|
|
### **Database States Detected:**
|
|
|
|
| **State** | **Description** | **Detection Method** | **Migration Strategy** |
|
|
|-----------|----------------|---------------------|------------------------|
|
|
| **Fresh** | No database or empty database | No tables exist | `fresh_init` |
|
|
| **Migrated** | Database already uses Flask-Migrate | `alembic_version` table exists | `check_migrations` |
|
|
| **Legacy** | Database with old custom migrations | Tables exist but no `alembic_version` | `comprehensive_migration` |
|
|
| **Unknown** | Cannot determine state | Detection failed | `comprehensive_migration` (fallback) |
|
|
|
|
## 🚀 **Migration Strategies**
|
|
|
|
### **1. Fresh Initialization (`fresh_init`)**
|
|
- **When Used**: New database, no existing tables
|
|
- **Actions**:
|
|
- Initialize Flask-Migrate
|
|
- Create initial migration
|
|
- Apply migration to create schema
|
|
- **Result**: Complete new database with Flask-Migrate
|
|
|
|
### **2. Migration Check (`check_migrations`)**
|
|
- **When Used**: Database already migrated, check for updates
|
|
- **Actions**:
|
|
- Check current migration revision
|
|
- Apply any pending migrations
|
|
- Verify database integrity
|
|
- **Result**: Database updated to latest migration
|
|
|
|
### **3. Comprehensive Migration (`comprehensive_migration`)**
|
|
- **When Used**: Legacy database with old custom migrations
|
|
- **Actions**:
|
|
- Run enhanced startup script (`startup_with_migration.py`)
|
|
- Fallback to manual migration if script fails
|
|
- Preserve all existing data
|
|
- Create migration baseline
|
|
- **Result**: Legacy database converted to Flask-Migrate
|
|
|
|
## 🔧 **Startup Process Flow**
|
|
|
|
```
|
|
Container Start
|
|
↓
|
|
Wait for Database
|
|
↓
|
|
Detect Database State
|
|
↓
|
|
Choose Migration Strategy
|
|
↓
|
|
Execute Migration
|
|
↓
|
|
Verify Database Integrity
|
|
↓
|
|
Start Application
|
|
```
|
|
|
|
## 📋 **Startup Scripts**
|
|
|
|
### **Primary Entrypoint: `docker/entrypoint.sh`**
|
|
- **Purpose**: Main container entrypoint with migration detection
|
|
- **Features**:
|
|
- Database availability check
|
|
- State detection (PostgreSQL/SQLite)
|
|
- Strategy selection
|
|
- Migration execution
|
|
- Integrity verification
|
|
- **Fallbacks**: Multiple fallback methods for each step
|
|
|
|
### **Enhanced Startup: `docker/startup_with_migration.py`**
|
|
- **Purpose**: Advanced migration handling for complex scenarios
|
|
- **Features**:
|
|
- Comprehensive database analysis
|
|
- Automatic backup creation
|
|
- Schema migration
|
|
- Data preservation
|
|
- Error recovery
|
|
|
|
## 🛡️ **Safety Features**
|
|
|
|
### **Automatic Protection:**
|
|
- ✅ **Database Wait**: Waits for database to be available
|
|
- ✅ **State Detection**: Analyzes existing database structure
|
|
- ✅ **Strategy Selection**: Chooses safest migration approach
|
|
- ✅ **Fallback Methods**: Multiple fallback options for each step
|
|
- ✅ **Integrity Verification**: Confirms database is working after migration
|
|
|
|
### **Error Handling:**
|
|
- ✅ **Graceful Failures**: Detailed error logging and recovery
|
|
- ✅ **Retry Logic**: Automatic retries for database connections
|
|
- ✅ **Fallback Strategies**: Alternative approaches if primary method fails
|
|
- ✅ **Logging**: Comprehensive logging for troubleshooting
|
|
|
|
## 🔍 **Detection Methods**
|
|
|
|
### **PostgreSQL Detection:**
|
|
```bash
|
|
# Check if alembic_version table exists
|
|
SELECT EXISTS (
|
|
SELECT FROM information_schema.tables
|
|
WHERE table_name = 'alembic_version'
|
|
);
|
|
|
|
# Get list of existing tables
|
|
SELECT table_name
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'public'
|
|
ORDER BY table_name;
|
|
```
|
|
|
|
### **SQLite Detection:**
|
|
```bash
|
|
# Check if alembic_version table exists
|
|
SELECT name FROM sqlite_master
|
|
WHERE type='table' AND name='alembic_version';
|
|
|
|
# Get list of existing tables
|
|
SELECT name FROM sqlite_master WHERE type='table';
|
|
```
|
|
|
|
## 📊 **Migration Strategy Selection Logic**
|
|
|
|
```python
|
|
def choose_migration_strategy(db_state):
|
|
if db_state == 'fresh':
|
|
return 'fresh_init' # New database
|
|
elif db_state == 'migrated':
|
|
return 'check_migrations' # Already migrated
|
|
elif db_state == 'legacy':
|
|
return 'comprehensive_migration' # Old system
|
|
else:
|
|
return 'comprehensive_migration' # Fallback
|
|
```
|
|
|
|
## 🚀 **Usage Examples**
|
|
|
|
### **Fresh Database:**
|
|
```bash
|
|
# Container will automatically:
|
|
# 1. Detect no tables exist
|
|
# 2. Choose 'fresh_init' strategy
|
|
# 3. Initialize Flask-Migrate
|
|
# 4. Create and apply initial migration
|
|
# 5. Start application
|
|
```
|
|
|
|
### **Existing Migrated Database:**
|
|
```bash
|
|
# Container will automatically:
|
|
# 1. Detect alembic_version table exists
|
|
# 2. Choose 'check_migrations' strategy
|
|
# 3. Check for pending migrations
|
|
# 4. Apply any updates
|
|
# 5. Start application
|
|
```
|
|
|
|
### **Legacy Database:**
|
|
```bash
|
|
# Container will automatically:
|
|
# 1. Detect tables exist but no alembic_version
|
|
# 2. Choose 'comprehensive_migration' strategy
|
|
# 3. Run enhanced migration script
|
|
# 4. Preserve all existing data
|
|
# 5. Convert to Flask-Migrate
|
|
# 6. Start application
|
|
```
|
|
|
|
## 🔧 **Configuration Options**
|
|
|
|
### **Environment Variables:**
|
|
```bash
|
|
# Required
|
|
DATABASE_URL=postgresql://user:pass@host:port/db
|
|
# or
|
|
DATABASE_URL=sqlite:///path/to/database.db
|
|
|
|
# Optional
|
|
FLASK_APP=/app/app.py
|
|
TZ=Europe/Rome
|
|
```
|
|
|
|
### **Database Connection Settings:**
|
|
- **PostgreSQL**: Full connection string with credentials
|
|
- **SQLite**: File path with write permissions
|
|
- **Connection Retries**: 30 attempts with 2-second delays
|
|
- **Timeout**: 60 seconds total wait time
|
|
|
|
## 📝 **Logging and Monitoring**
|
|
|
|
### **Log Locations:**
|
|
- **Container Logs**: `docker logs <container_name>`
|
|
- **Startup Logs**: `/var/log/timetracker_startup.log`
|
|
- **Application Logs**: `/app/logs/`
|
|
|
|
### **Log Levels:**
|
|
- **INFO**: Normal operation and progress
|
|
- **WARNING**: Non-critical issues
|
|
- **ERROR**: Critical failures and errors
|
|
|
|
### **Key Log Messages:**
|
|
```
|
|
[2025-01-15 10:00:00] === TimeTracker Docker Container Starting ===
|
|
[2025-01-15 10:00:01] Waiting for database to be available...
|
|
[2025-01-15 10:00:02] ✓ PostgreSQL database is available
|
|
[2025-01-15 10:00:03] Analyzing database state...
|
|
[2025-01-15 10:00:04] Detected database state: legacy with 8 tables
|
|
[2025-01-15 10:00:05] Selected migration strategy: comprehensive_migration
|
|
[2025-01-15 10:00:06] Executing migration strategy: comprehensive_migration
|
|
[2025-01-15 10:00:10] ✓ Enhanced startup script completed successfully
|
|
[2025-01-15 10:00:11] Verifying database integrity...
|
|
[2025-01-15 10:00:12] ✓ Database integrity verified
|
|
[2025-01-15 10:00:13] === Startup and Migration Complete ===
|
|
[2025-01-15 10:00:14] Starting TimeTracker application...
|
|
```
|
|
|
|
## 🔍 **Troubleshooting**
|
|
|
|
### **Common Issues:**
|
|
|
|
#### **1. Database Connection Failed:**
|
|
```bash
|
|
# Check environment variables
|
|
echo $DATABASE_URL
|
|
|
|
# Check database service
|
|
docker-compose ps db
|
|
|
|
# Check logs
|
|
docker logs <container_name>
|
|
```
|
|
|
|
#### **2. Migration Strategy Failed:**
|
|
```bash
|
|
# Check migration logs
|
|
docker exec <container_name> cat /var/log/timetracker_startup.log
|
|
|
|
# Check migration status
|
|
docker exec <container_name> flask db current
|
|
|
|
# Check database state manually
|
|
docker exec <container_name> flask db history
|
|
```
|
|
|
|
#### **3. Database Integrity Check Failed:**
|
|
```bash
|
|
# Check if key tables exist
|
|
docker exec <container_name> psql $DATABASE_URL -c "\dt"
|
|
|
|
# Check table structure
|
|
docker exec <container_name> psql $DATABASE_URL -c "\d users"
|
|
```
|
|
|
|
### **Recovery Options:**
|
|
1. **Check Logs**: Review startup and migration logs
|
|
2. **Verify Database**: Ensure database is accessible
|
|
3. **Check Permissions**: Verify database user permissions
|
|
4. **Restart Container**: Restart with fresh migration attempt
|
|
5. **Manual Migration**: Use migration scripts manually if needed
|
|
|
|
## 🎉 **Benefits**
|
|
|
|
### **Automatic Operation:**
|
|
- ✅ **Zero Configuration**: Works with any existing database
|
|
- ✅ **Smart Detection**: Automatically chooses best migration approach
|
|
- ✅ **Data Preservation**: Never loses existing data
|
|
- ✅ **Error Recovery**: Multiple fallback methods
|
|
|
|
### **Production Ready:**
|
|
- ✅ **Safe Migration**: Automatic backups and verification
|
|
- ✅ **Rollback Support**: Can revert to previous state
|
|
- ✅ **Monitoring**: Comprehensive logging and health checks
|
|
- ✅ **Scalability**: Works with any database size
|
|
|
|
---
|
|
|
|
**Result**: Your TimeTracker container will automatically handle any database scenario during startup, ensuring a smooth transition to the new Flask-Migrate system regardless of the existing database state! 🚀
|