From 1cb54be01ead3014a27fb02a16bb0c7b146fc5f3 Mon Sep 17 00:00:00 2001 From: Quality System Admin Date: Mon, 3 Nov 2025 23:04:44 +0200 Subject: [PATCH] updated --- .env.example | 40 ++++-- DOCKER_QUICK_START.md | 314 ++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 222 +++++++++++------------------ 3 files changed, 421 insertions(+), 155 deletions(-) create mode 100644 DOCKER_QUICK_START.md diff --git a/.env.example b/.env.example index ff78461..55af6d5 100644 --- a/.env.example +++ b/.env.example @@ -24,10 +24,10 @@ DB_MAX_RETRIES=60 DB_RETRY_INTERVAL=2 # Data persistence paths -DB_DATA_PATH=/srv/docker-test/mariadb -LOGS_PATH=/srv/docker-test/logs -INSTANCE_PATH=/srv/docker-test/instance -BACKUP_PATH=/srv/docker-test/backups +DB_DATA_PATH=/srv/quality_app/mariadb +LOGS_PATH=/srv/quality_app/logs +INSTANCE_PATH=/srv/quality_app/py_app/instance +BACKUP_PATH=/srv/quality_app/backups # ============================================================================ # APPLICATION CONFIGURATION @@ -50,8 +50,8 @@ APP_PORT=8781 # Worker class (sync, gevent, gthread) GUNICORN_WORKER_CLASS=sync -# Request timeout in seconds -GUNICORN_TIMEOUT=120 +# Request timeout in seconds (increased for large database operations) +GUNICORN_TIMEOUT=1800 # Bind address GUNICORN_BIND=0.0.0.0:8781 @@ -72,11 +72,11 @@ GUNICORN_MAX_REQUESTS=1000 # ============================================================================ # INITIALIZATION FLAGS # ============================================================================ -# Initialize database schema on first run -INIT_DB=true +# Initialize database schema on first run (set to false after first deployment) +INIT_DB=false -# Seed database with default data -SEED_DB=true +# Seed database with default data (set to false after first deployment) +SEED_DB=false # Continue on database initialization errors IGNORE_DB_INIT_ERRORS=false @@ -105,6 +105,26 @@ VCS_REF= # ============================================================================ NETWORK_SUBNET=172.20.0.0/16 +# ============================================================================ +# RESOURCE LIMITS +# ============================================================================ +# Database resource limits +DB_CPU_LIMIT=2.0 +DB_CPU_RESERVATION=0.5 +DB_MEMORY_LIMIT=1G +DB_MEMORY_RESERVATION=256M + +# Application resource limits +APP_CPU_LIMIT=2.0 +APP_CPU_RESERVATION=0.5 +APP_MEMORY_LIMIT=1G +APP_MEMORY_RESERVATION=256M + +# Logging configuration +LOG_MAX_SIZE=10m +LOG_MAX_FILES=5 +DB_LOG_MAX_FILES=3 + # ============================================================================ # NOTES: # ============================================================================ diff --git a/DOCKER_QUICK_START.md b/DOCKER_QUICK_START.md new file mode 100644 index 0000000..d4dff64 --- /dev/null +++ b/DOCKER_QUICK_START.md @@ -0,0 +1,314 @@ +# Docker Compose - Quick Reference + +## Simplified Structure + +The Docker Compose configuration has been simplified with most settings moved to the `.env` file for easier management. + +## File Structure + +``` +quality_app/ +├── docker-compose.yml # Main Docker configuration (171 lines, simplified) +├── .env.example # Template with all available settings +├── .env # Your configuration (copy from .env.example) +├── Dockerfile # Application container definition +├── docker-entrypoint.sh # Container startup script +└── init-db.sql # Database initialization +``` + +## Quick Start + +### 1. Initial Setup + +```bash +# Navigate to project directory +cd /srv/quality_app + +# Create .env file from template +cp .env.example .env + +# Edit .env with your settings +nano .env +``` + +### 2. Configure .env File + +**Required changes for first deployment:** +```bash +# Set these to true for first run only +INIT_DB=true +SEED_DB=true + +# Change these in production +SECRET_KEY=your-secure-random-key-here +MYSQL_ROOT_PASSWORD=your-secure-root-password +DB_PASSWORD=your-secure-db-password +``` + +### 3. Create Required Directories + +```bash +sudo mkdir -p /srv/quality_app/{mariadb,logs,backups} +sudo chown -R $USER:$USER /srv/quality_app +``` + +### 4. Start Services + +```bash +# Start in detached mode +docker-compose up -d + +# Watch logs +docker-compose logs -f web +``` + +### 5. After First Successful Start + +```bash +# Edit .env and set: +INIT_DB=false +SEED_DB=false + +# Restart to apply changes +docker-compose restart web +``` + +## Common Commands + +### Service Management + +```bash +# Start services +docker-compose up -d + +# Stop services +docker-compose down + +# Restart specific service +docker-compose restart web +docker-compose restart db + +# View service status +docker-compose ps + +# Remove all containers and volumes +docker-compose down -v +``` + +### Logs and Monitoring + +```bash +# Follow all logs +docker-compose logs -f + +# Follow specific service logs +docker-compose logs -f web +docker-compose logs -f db + +# View last 100 lines +docker-compose logs --tail=100 web + +# Check resource usage +docker stats quality-app quality-app-db +``` + +### Updates and Rebuilds + +```bash +# Rebuild after code changes +docker-compose up -d --build + +# Pull latest images +docker-compose pull + +# Rebuild specific service +docker-compose up -d --build web +``` + +### Database Operations + +```bash +# Access database CLI +docker-compose exec db mysql -u trasabilitate -p trasabilitate + +# Backup database +docker-compose exec db mysqldump -u root -p trasabilitate > backup.sql + +# Restore database +docker-compose exec -T db mysql -u root -p trasabilitate < backup.sql + +# View database logs +docker-compose logs db +``` + +### Container Access + +```bash +# Access web application shell +docker-compose exec web bash + +# Access database shell +docker-compose exec db bash + +# Run one-off command +docker-compose exec web python -c "print('Hello')" +``` + +## Environment Variables Reference + +### Critical Settings (.env) + +| Variable | Default | Description | +|----------|---------|-------------| +| `APP_PORT` | 8781 | Application port | +| `DB_PASSWORD` | Initial01! | Database password | +| `SECRET_KEY` | change-this | Flask secret key | +| `INIT_DB` | false | Initialize database on startup | +| `SEED_DB` | false | Seed default data on startup | + +### Volume Paths + +| Variable | Default | Purpose | +|----------|---------|---------| +| `DB_DATA_PATH` | /srv/quality_app/mariadb | Database files | +| `LOGS_PATH` | /srv/quality_app/logs | Application logs | +| `BACKUP_PATH` | /srv/quality_app/backups | Database backups | +| `INSTANCE_PATH` | /srv/quality_app/py_app/instance | Config files | + +### Performance Tuning + +| Variable | Default | Description | +|----------|---------|-------------| +| `GUNICORN_WORKERS` | auto | Number of workers | +| `GUNICORN_TIMEOUT` | 1800 | Request timeout (seconds) | +| `MYSQL_BUFFER_POOL` | 256M | Database buffer size | +| `MYSQL_MAX_CONNECTIONS` | 150 | Max DB connections | +| `APP_CPU_LIMIT` | 2.0 | CPU limit for app | +| `APP_MEMORY_LIMIT` | 1G | Memory limit for app | + +## Configuration Changes + +To change configuration: + +1. Edit `.env` file +2. Restart affected service: + ```bash + docker-compose restart web + # or + docker-compose restart db + ``` + +### When to Restart vs Rebuild + +**Restart only** (changes in .env): +- Environment variables +- Resource limits +- Port mappings + +**Rebuild required** (code/Dockerfile changes): +```bash +docker-compose up -d --build +``` + +## Troubleshooting + +### Application won't start + +```bash +# Check logs +docker-compose logs web + +# Check database health +docker-compose ps +docker-compose exec db mysqladmin ping -u root -p + +# Verify .env file +cat .env | grep -v "^#" | grep -v "^$" +``` + +### Database connection issues + +```bash +# Check database is running +docker-compose ps db + +# Test database connection +docker-compose exec web python -c " +import mysql.connector +conn = mysql.connector.connect( + host='db', user='trasabilitate', + password='Initial01!', database='trasabilitate' +) +print('Connected OK') +" +``` + +### Port already in use + +```bash +# Check what's using the port +sudo netstat -tlnp | grep 8781 + +# Change APP_PORT in .env +echo "APP_PORT=8782" >> .env +docker-compose up -d +``` + +### Reset everything + +```bash +# Stop and remove all +docker-compose down -v + +# Remove data (CAUTION: destroys database!) +sudo rm -rf /srv/quality_app/mariadb/* + +# Restart fresh +INIT_DB=true SEED_DB=true docker-compose up -d +``` + +## Production Checklist + +Before deploying to production: + +- [ ] Change `SECRET_KEY` in .env +- [ ] Change `MYSQL_ROOT_PASSWORD` in .env +- [ ] Change `DB_PASSWORD` in .env +- [ ] Set `INIT_DB=false` after first run +- [ ] Set `SEED_DB=false` after first run +- [ ] Set `FLASK_ENV=production` +- [ ] Verify backup paths are correct +- [ ] Test backup and restore procedures +- [ ] Set up external monitoring +- [ ] Configure firewall rules +- [ ] Set up SSL/TLS certificates +- [ ] Review resource limits +- [ ] Set up log rotation + +## Comparison: Before vs After + +### Before (242 lines) +- Many inline default values +- Extensive comments in docker-compose.yml +- Hard to find and change settings +- Difficult to maintain multiple environments + +### After (171 lines) +- Clean, readable docker-compose.yml (29% reduction) +- All settings in .env file +- Easy to customize per environment +- Simple to version control (just .env.example) +- Better separation of concerns + +## Related Documentation + +- [PRODUCTION_STARTUP_GUIDE.md](./documentation/PRODUCTION_STARTUP_GUIDE.md) - Application management +- [DATABASE_BACKUP_GUIDE.md](./documentation/DATABASE_BACKUP_GUIDE.md) - Backup procedures +- [DATABASE_RESTORE_GUIDE.md](./documentation/DATABASE_RESTORE_GUIDE.md) - Restore procedures +- [DATABASE_STRUCTURE.md](./documentation/DATABASE_STRUCTURE.md) - Database schema + +--- + +**Last Updated**: November 3, 2025 +**Docker Compose Version**: 3.8 +**Configuration Style**: Environment-based (simplified) diff --git a/docker-compose.yml b/docker-compose.yml index 5786a61..6f95ea5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.8' # ============================================================================ # Recticel Quality Application - Docker Compose Configuration -# Production-ready setup with health checks, logging, and resource limits +# Simplified configuration - most settings are in .env file # ============================================================================ services: @@ -11,39 +11,27 @@ services: # ========================================================================== db: image: mariadb:11.3 - container_name: trasabilitate-db + container_name: quality-app-db restart: unless-stopped environment: - # Root credentials - MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword} - - # Application database and user - MYSQL_DATABASE: ${DB_NAME:-trasabilitate} - MYSQL_USER: ${DB_USER:-trasabilitate} - MYSQL_PASSWORD: ${DB_PASSWORD:-Initial01!} - - # Performance tuning - MYSQL_INNODB_BUFFER_POOL_SIZE: ${MYSQL_BUFFER_POOL:-256M} - MYSQL_MAX_CONNECTIONS: ${MYSQL_MAX_CONNECTIONS:-150} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${DB_NAME} + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASSWORD} + MYSQL_INNODB_BUFFER_POOL_SIZE: ${MYSQL_BUFFER_POOL} + MYSQL_MAX_CONNECTIONS: ${MYSQL_MAX_CONNECTIONS} ports: - - "${DB_PORT:-3306}:3306" + - "${DB_PORT}:3306" volumes: - # Persistent database storage - - ${DB_DATA_PATH:-/srv/docker-test/mariadb}:/var/lib/mysql - - # Custom initialization scripts + - ${DB_DATA_PATH}:/var/lib/mysql - ./init-db.sql:/docker-entrypoint-initdb.d/01-init.sql:ro - - # Custom MariaDB configuration (optional) - # - ./my.cnf:/etc/mysql/conf.d/custom.cnf:ro networks: - - recticel-network + - quality-app-network - # Comprehensive health check healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s @@ -51,22 +39,20 @@ services: retries: 5 start_period: 30s - # Resource limits (adjust based on your server capacity) deploy: resources: limits: - cpus: '2.0' - memory: 1G + cpus: ${DB_CPU_LIMIT} + memory: ${DB_MEMORY_LIMIT} reservations: - cpus: '0.5' - memory: 256M + cpus: ${DB_CPU_RESERVATION} + memory: ${DB_MEMORY_RESERVATION} - # Logging configuration logging: - driver: "json-file" + driver: json-file options: - max-size: "10m" - max-file: "3" + max-size: ${LOG_MAX_SIZE} + max-file: ${DB_LOG_MAX_FILES} # ========================================================================== # Flask Web Application Service @@ -76,101 +62,67 @@ services: context: . dockerfile: Dockerfile args: - BUILD_DATE: ${BUILD_DATE:-} - VERSION: ${VERSION:-1.0.0} - VCS_REF: ${VCS_REF:-} + BUILD_DATE: ${BUILD_DATE} + VERSION: ${VERSION} + VCS_REF: ${VCS_REF} - image: recticel-quality-app:${VERSION:-latest} - container_name: recticel-app + image: trasabilitate-quality-app:${VERSION} + container_name: quality-app restart: unless-stopped - # Wait for database to be healthy before starting depends_on: db: condition: service_healthy environment: - # ====================================================================== - # Database Connection Settings - # ====================================================================== - DB_HOST: db - DB_PORT: ${DB_PORT:-3306} - DB_NAME: ${DB_NAME:-trasabilitate} - DB_USER: ${DB_USER:-trasabilitate} - DB_PASSWORD: ${DB_PASSWORD:-Initial01!} + # Database connection + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + DB_NAME: ${DB_NAME} + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + DB_MAX_RETRIES: ${DB_MAX_RETRIES} + DB_RETRY_INTERVAL: ${DB_RETRY_INTERVAL} - # Database connection tuning - DB_MAX_RETRIES: ${DB_MAX_RETRIES:-60} - DB_RETRY_INTERVAL: ${DB_RETRY_INTERVAL:-2} - - # ====================================================================== - # Flask Application Settings - # ====================================================================== - FLASK_ENV: ${FLASK_ENV:-production} + # Flask settings + FLASK_ENV: ${FLASK_ENV} FLASK_APP: run.py - SECRET_KEY: ${SECRET_KEY:-change-this-in-production} + SECRET_KEY: ${SECRET_KEY} - # ====================================================================== - # Gunicorn Configuration (override defaults) - # ====================================================================== - GUNICORN_WORKERS: ${GUNICORN_WORKERS:-} - GUNICORN_WORKER_CLASS: ${GUNICORN_WORKER_CLASS:-sync} - GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-120} - GUNICORN_BIND: ${GUNICORN_BIND:-0.0.0.0:8781} - GUNICORN_LOG_LEVEL: ${GUNICORN_LOG_LEVEL:-info} - GUNICORN_PRELOAD_APP: ${GUNICORN_PRELOAD_APP:-true} - GUNICORN_MAX_REQUESTS: ${GUNICORN_MAX_REQUESTS:-1000} + # Gunicorn settings + GUNICORN_WORKERS: ${GUNICORN_WORKERS} + GUNICORN_WORKER_CLASS: ${GUNICORN_WORKER_CLASS} + GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT} + GUNICORN_BIND: ${GUNICORN_BIND} + GUNICORN_LOG_LEVEL: ${GUNICORN_LOG_LEVEL} + GUNICORN_PRELOAD_APP: ${GUNICORN_PRELOAD_APP} + GUNICORN_MAX_REQUESTS: ${GUNICORN_MAX_REQUESTS} - # For Docker logging to stdout/stderr, set these to "-" - # GUNICORN_ACCESS_LOG: "-" - # GUNICORN_ERROR_LOG: "-" + # Initialization flags + INIT_DB: ${INIT_DB} + SEED_DB: ${SEED_DB} + IGNORE_DB_INIT_ERRORS: ${IGNORE_DB_INIT_ERRORS} + IGNORE_SEED_ERRORS: ${IGNORE_SEED_ERRORS} + SKIP_HEALTH_CHECK: ${SKIP_HEALTH_CHECK} - # ====================================================================== - # Initialization Flags - # ====================================================================== - # Set to "false" after first successful deployment - INIT_DB: ${INIT_DB:-true} - SEED_DB: ${SEED_DB:-true} + # Localization + TZ: ${TZ} + LANG: ${LANG} - # Error handling - IGNORE_DB_INIT_ERRORS: ${IGNORE_DB_INIT_ERRORS:-false} - IGNORE_SEED_ERRORS: ${IGNORE_SEED_ERRORS:-false} - - # Skip health check (for faster startup in dev) - SKIP_HEALTH_CHECK: ${SKIP_HEALTH_CHECK:-false} - - # ====================================================================== - # Timezone and Locale - # ====================================================================== - TZ: ${TZ:-Europe/Bucharest} - LANG: ${LANG:-en_US.UTF-8} - - # ====================================================================== - # Backup Configuration - # ====================================================================== - BACKUP_PATH: ${BACKUP_PATH:-/srv/quality_recticel/backups} + # Backup path + BACKUP_PATH: ${BACKUP_PATH} ports: - - "${APP_PORT:-8781}:8781" + - "${APP_PORT}:8781" volumes: - # Persistent logs directory - - ${LOGS_PATH:-/srv/docker-test/logs}:/srv/quality_recticel/logs - - # Instance configuration directory - - ${INSTANCE_PATH:-/srv/docker-test/instance}:/app/instance - - # Database backups directory - - ${BACKUP_PATH:-/srv/docker-test/backups}:/srv/quality_recticel/backups - - # ⚠️ DEVELOPMENT ONLY: Mount application code for live updates - # DISABLE IN PRODUCTION - causes configuration and security issues - # - ./py_app:/app + - ${LOGS_PATH}:/srv/quality_app/logs + - ${INSTANCE_PATH}:/app/instance + - ${BACKUP_PATH}:/srv/quality_app/backups networks: - - recticel-network + - quality-app-network - # Application health check healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8781/"] interval: 30s @@ -178,62 +130,42 @@ services: retries: 3 start_period: 60s - # Resource limits (adjust based on your application needs) deploy: resources: limits: - cpus: '2.0' - memory: 1G + cpus: ${APP_CPU_LIMIT} + memory: ${APP_MEMORY_LIMIT} reservations: - cpus: '0.5' - memory: 256M + cpus: ${APP_CPU_RESERVATION} + memory: ${APP_MEMORY_RESERVATION} - # Logging configuration logging: - driver: "json-file" + driver: json-file options: - max-size: "10m" - max-file: "5" + max-size: ${LOG_MAX_SIZE} + max-file: ${LOG_MAX_FILES} compress: "true" # ============================================================================ # Network Configuration # ============================================================================ networks: - recticel-network: + quality-app-network: driver: bridge ipam: config: - - subnet: ${NETWORK_SUBNET:-172.20.0.0/16} + - subnet: ${NETWORK_SUBNET} # ============================================================================ -# NOTES: +# USAGE NOTES # ============================================================================ -# 1. Environment Variables: -# - Create a .env file in the same directory for custom configuration -# - See .env.example for available options -# -# 2. First-Time Setup: -# - Set INIT_DB=true and SEED_DB=true for initial deployment -# - After successful setup, set them to false to avoid re-initialization -# -# 3. Volumes: -# - Using bind mounts to /srv/docker-test/ for easy access -# - Ensure the host directories exist and have proper permissions -# -# 4. Security: -# - Change default passwords in production -# - Set a secure SECRET_KEY -# - Use secrets management for sensitive data -# -# 5. Scaling: -# - Adjust resource limits based on your server capacity -# - Use 'docker-compose up --scale web=3' to run multiple app instances -# (requires load balancer setup) -# -# 6. Commands: -# - Start: docker-compose up -d -# - Stop: docker-compose down -# - Logs: docker-compose logs -f web -# - Rebuild: docker-compose up -d --build +# 1. Copy .env.example to .env and customize all values +# 2. Set INIT_DB=true and SEED_DB=true for first deployment only +# 3. Change default passwords and SECRET_KEY in production +# 4. Ensure all volume paths exist with proper permissions: +# mkdir -p /srv/quality_app/{mariadb,logs,backups} +# 5. Start: docker-compose up -d +# 6. Stop: docker-compose down +# 7. Logs: docker-compose logs -f web +# 8. Rebuild: docker-compose up -d --build # ============================================================================