# Quick Reference - Docker Deployment ## 🎯 What Was Analyzed & Improved ### Database Configuration Flow **Current Setup:** ``` .env file → docker-compose.yml → Container ENV → docker-entrypoint.sh → Creates /app/instance/external_server.conf → App reads config file → MariaDB connection ``` **Key Finding:** Application uses `external_server.conf` file created from environment variables instead of reading env vars directly. ### Docker Deployment Database **What Docker Creates:** 1. **MariaDB Container** (from init-db.sql): - Database: `trasabilitate` - User: `trasabilitate` - Password: `Initial01!` 2. **Application Container** runs: - `docker-entrypoint.sh` → Wait for DB + Create config - `setup_complete_database.py` → Create 11 tables + triggers - `seed.py` → Create superadmin user 3. **Tables Created:** - scan1_orders, scanfg_orders (quality scans) - order_for_labels (production orders) - warehouse_locations (warehouse) - users, roles (authentication) - permissions, role_permissions, role_hierarchy (access control) - permission_audit_log (audit trail) ## 🔧 Improvements Made ### 1. gunicorn.conf.py - ✅ All settings configurable via environment variables - ✅ Docker-friendly (no daemon mode) - ✅ Enhanced logging with lifecycle hooks - ✅ Increased timeout to 120s (for long operations) - ✅ Worker management and auto-restart ### 2. docker-entrypoint.sh - ✅ Robust error handling (set -e, -u, -o pipefail) - ✅ Comprehensive logging functions - ✅ Environment variable validation - ✅ Smart database waiting (configurable retries) - ✅ Health checks before startup - ✅ Graceful shutdown handlers ### 3. Dockerfile - ✅ Multi-stage build (smaller image) - ✅ Non-root user (security) - ✅ Virtual environment isolation - ✅ Better layer caching - ✅ Health check included ### 4. docker-compose.yml - ✅ 30+ environment variables - ✅ Resource limits (CPU/memory) - ✅ Advanced health checks - ✅ Log rotation - ✅ Network configuration ### 5. Documentation - ✅ DATABASE_DOCKER_SETUP.md (comprehensive DB guide) - ✅ DOCKER_IMPROVEMENTS.md (all changes explained) - ✅ .env.example (complete configuration template) ## ⚠️ Issues Found ### Issue 1: Hardcoded SQLite in __init__.py ```python # Current (BAD for Docker): app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' # Should be (GOOD for Docker): app.config['SQLALCHEMY_DATABASE_URI'] = ( f'mysql+mariadb://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}' ) ``` **Fix Available:** `py_app/app/__init__.py.improved` **To Apply:** ```bash cd /srv/quality_app/py_app/app cp __init__.py __init__.py.backup cp __init__.py.improved __init__.py ``` ### Issue 2: Dual Database Connection Methods - SQLAlchemy ORM (for User model) - Direct mariadb.connect() (for everything else) **Recommendation:** Standardize on one approach ### Issue 3: external_server.conf Redundancy - ENV vars → config file → app reads file - Better: App reads ENV vars directly ## 🚀 Deploy Commands ### First Time ```bash cd /srv/quality_app # 1. Configure environment cp .env.example .env nano .env # Edit passwords! # 2. Build and start docker-compose build docker-compose up -d # 3. Check logs docker-compose logs -f web # 4. Test curl http://localhost:8781/ ``` ### After First Deployment ```bash # Edit .env: INIT_DB=false # Don't recreate tables SEED_DB=false # Don't recreate superadmin # Restart docker-compose restart ``` ### Rebuild After Code Changes ```bash docker-compose up -d --build ``` ### View Logs ```bash # All logs docker-compose logs -f # Just web app docker-compose logs -f web # Just database docker-compose logs -f db ``` ### Access Database ```bash # From host docker-compose exec db mysql -utrasabilitate -pInitial01! trasabilitate # From app container docker-compose exec web python3 -c " from app.settings import get_external_db_connection conn = get_external_db_connection() cursor = conn.cursor() cursor.execute('SHOW TABLES') print(cursor.fetchall()) " ``` ## 📋 Environment Variables Reference ### Required ```bash DB_HOST=db DB_PORT=3306 DB_NAME=trasabilitate DB_USER=trasabilitate DB_PASSWORD=Initial01! # CHANGE THIS! MYSQL_ROOT_PASSWORD=rootpassword # CHANGE THIS! ``` ### Optional (Gunicorn) ```bash GUNICORN_WORKERS=5 # CPU cores * 2 + 1 GUNICORN_TIMEOUT=120 # Request timeout GUNICORN_LOG_LEVEL=info # debug|info|warning|error ``` ### Optional (Initialization) ```bash INIT_DB=true # Create database schema SEED_DB=true # Create superadmin user IGNORE_DB_INIT_ERRORS=false # Continue on init errors IGNORE_SEED_ERRORS=false # Continue on seed errors ``` ## 🔐 Default Credentials **Superadmin:** - Username: `superadmin` - Password: `superadmin123` - **⚠️ CHANGE IMMEDIATELY IN PRODUCTION!** **Database:** - User: `trasabilitate` - Password: `Initial01!` - **⚠️ CHANGE IMMEDIATELY IN PRODUCTION!** ## 📊 Monitoring ### Check Container Status ```bash docker-compose ps ``` ### Resource Usage ```bash docker stats ``` ### Application Health ```bash curl http://localhost:8781/ # Should return 200 OK ``` ### Database Health ```bash docker-compose exec db healthcheck.sh --connect --innodb_initialized ``` ## 🔄 Backup & Restore ### Backup Database ```bash docker-compose exec db mysqldump -utrasabilitate -pInitial01! trasabilitate > backup_$(date +%Y%m%d).sql ``` ### Restore Database ```bash docker-compose exec -T db mysql -utrasabilitate -pInitial01! trasabilitate < backup_20251103.sql ``` ### Backup Volumes ```bash # Backup persistent data sudo tar -czf backup_volumes_$(date +%Y%m%d).tar.gz \ /srv/docker-test/mariadb \ /srv/docker-test/logs \ /srv/docker-test/instance ``` ## 🐛 Troubleshooting ### Container Won't Start ```bash # Check logs docker-compose logs web # Check if database is ready docker-compose logs db | grep "ready for connections" # Restart services docker-compose restart ``` ### Database Connection Failed ```bash # Test from app container docker-compose exec web python3 -c " import mariadb conn = mariadb.connect( user='trasabilitate', password='Initial01!', host='db', port=3306, database='trasabilitate' ) print('✅ Connection successful!') " ``` ### Tables Not Created ```bash # Run setup script manually docker-compose exec web python3 /app/app/db_create_scripts/setup_complete_database.py # Verify tables docker-compose exec db mysql -utrasabilitate -pInitial01! trasabilitate -e "SHOW TABLES;" ``` ### Application Not Responding ```bash # Check if Gunicorn is running docker-compose exec web ps aux | grep gunicorn # Check port binding docker-compose exec web netstat -tulpn | grep 8781 # Restart application docker-compose restart web ``` ## 📁 Important Files | File | Purpose | |------|---------| | `docker-compose.yml` | Service orchestration | | `.env` | Environment configuration | | `Dockerfile` | Application image build | | `docker-entrypoint.sh` | Container initialization | | `py_app/gunicorn.conf.py` | Web server config | | `init-db.sql` | Database initialization | | `py_app/app/db_create_scripts/setup_complete_database.py` | Schema creation | | `py_app/seed.py` | Data seeding | | `py_app/app/__init__.py` | Application factory | | `py_app/app/settings.py` | Database connection helper | ## 📚 Documentation Files | File | Description | |------|-------------| | `DATABASE_DOCKER_SETUP.md` | Database configuration guide | | `DOCKER_IMPROVEMENTS.md` | All improvements explained | | `DOCKER_QUICK_REFERENCE.md` | This file - quick commands | | `.env.example` | Environment variable template | ## ✅ Production Checklist - [ ] Change `MYSQL_ROOT_PASSWORD` - [ ] Change `DB_PASSWORD` - [ ] Change superadmin password - [ ] Set strong `SECRET_KEY` - [ ] Set `INIT_DB=false` - [ ] Set `SEED_DB=false` - [ ] Set `FLASK_ENV=production` - [ ] Configure backup strategy - [ ] Set up monitoring - [ ] Configure firewall rules - [ ] Enable HTTPS/SSL - [ ] Review resource limits - [ ] Test disaster recovery - [ ] Document access procedures ## 🎓 Next Steps 1. **Apply SQLAlchemy fix** (recommended) ```bash cp py_app/app/__init__.py.improved py_app/app/__init__.py ``` 2. **Test the deployment** ```bash docker-compose up -d --build docker-compose logs -f web ``` 3. **Access the application** - URL: http://localhost:8781 - Login: superadmin / superadmin123 4. **Review documentation** - Read `DATABASE_DOCKER_SETUP.md` - Read `DOCKER_IMPROVEMENTS.md` 5. **Production hardening** - Change all default passwords - Set up SSL/HTTPS - Configure monitoring - Implement backups