# Email Reports - Dockerized Container Unified Docker container for automated daily order email reports for **both Crew Sportswear and MerchBay**. ## Overview This container runs cron jobs daily at **23:55 CT** to: 1. Query orders from both Crew and MerchBay databases 2. Generate separate CSV reports for each brand 3. Email reports to recipients via SMTP **Cron Schedule:** - **23:55** - Crew Sportswear report - **23:56** - MerchBay report ## Quick Start ### 1. Create `.env` file ```bash cp .env.example .env vim .env ``` Configure your environment variables: ```env # Crew Database DB_HOST_CREW=mysql DB_NAME_CREW=custom_design DB_USER_CREW=crew_user DB_PASS_CREW=your_password # MerchBay Database DB_HOST_MERCHBAY=mysql DB_NAME_MERCHBAY=merchbay_laravel DB_USER_MERCHBAY=merchbay_user DB_PASS_MERCHBAY=your_password # SMTP SMTP_PASS_CREW=crew_gmail_app_password SMTP_PASS_MERCHBAY=merchbay_gmail_app_password ``` ### 2. Build and Run ```bash # Build image docker-compose build # Start container docker-compose up -d # Check logs docker logs -f email_reports_crew ``` ### 3. Test Manually ```bash # Test Crew report docker exec email_reports_unified BRAND=crew php /app/send_report.php # Test MerchBay report docker exec email_reports_unified BRAND=merchbay php /app/send_report.php # Check cron log docker exec email_reports_unified tail -f /var/log/cron.log # Check email log (shows both brands) docker exec email_reports_unified tail -f /app/email.log ``` ┌──────────────────────────────────────────┐ │ Email Reports Container (Unified) │ │ │ │ ┌────────────────────────────────────┐ │ │ │ Cron Jobs: │ │ │ │ 23:55 → BRAND=crew │ │ │ │ 23:56 → BRAND=merchbay │ │ │ │ │ │ │ │ send_report.php │ │ │ │ └─ PHPMailer │ │ │ └────────────────────────────────────┘ │ │ │ │ └─────────────┼────────────────────────────┘ │ ├──> MySQL: custom_design (Crew) ├──> MySQL: merchbay_laravel (MerchBay) └──> SMTP: Gmail (2 accounts) │ ├──────> MySQL (crew-app-net) └──────> SMTP (smtp.gmail.com) ``` ## Fsend_report.php** - Unified report generator (handles both brands) - **index.php** - Legacy Crew report (kept for backward compatibility) - **dbconfig.php** - Database connection (env-aware) - **phpmailer/** - Email library ## Cron Schedule ```cron 55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1 56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1 ``` **23:55 CT** - Crew Sportswear **23:56 CT** - MerchBay Both run daily, 1 minute apart. 55 23 * * * cd /app && php index.php >> /var/log/cron.log 2>&1 ``` Runs daily at **11:55 PM Central Time** ## Environment Variables ### Crew Sportswear | Variable | Default | Description | |----------|---------|-------------| | DB_HOST_CREW | mysql | MySQL host for Crew | | DB_PORT_CREW | 3306 | MySQL port | | DB_NAME_CREW | custom_design | Crew database name | | DB_USER_CREW | crew_user | Crew database username | | DB_PASS_CREW | - | Crew database password | | SMTP_PASS_CREW | - | Gmail app password for mail@crewsportswear.com | ### MerchBay | Variable | Default | Description | |----------|---------|-------------| | DB_HOST_MERCHBAY | mysql | MySQL host for MerchBay | | DB_PORT_MERCHBAY | 3306 | MySQL port | | DB_NAME_MERCHBAY | merchbay_laravel | MerchBay database name | | DB_USER_MERCHBAY | merchbay_user | MerchBay database username | | DB_PASS_MERCHBAY | - | MerchBay database password | | SMTP_PASS_MERCHBAY | - | Gmail app password for support@merchbay.com | ### Shared | Variable | Default | Description | |----------|---------|-------------| | SMTP_HOST | smtp.gmail.com | SMTP server | | SMTP_PORT | 587 | SMTP port | ## Brand Configuration The unified container handles both brands using the `BRAND` environment variable: **Crew Sportswear (`BRAND=crew`)**: - Database: `custom_design` - SMTP: `mail@crewsportswear.com` - From: `orders@crewsportswear.com` - To: `graphics@crewsportswear.com` - BCC: webmaster, angelo, production @crewsportswear.com - Admin: https://admin.crewsportswear.app - CSV: `daily_order_reports_crew/` **MerchBay (`BRAND=merchbay`)**: - Database: `merchbay_laravel` - SMTP: `support@merchbay.com` - From: `orders@merchbay.com` - To: `graphics@crewsportswear.com` - BCC: webmaster, production @crewsportswear.com - Admin: https://merchbay.app - CSV: `daily_order_reports_merchbay/` **Note**: Each brand uses its own Gmail account for SMTP authentication. ## Networks Container must be on **crew-app-net** to access MySQL: ```yaml networks: - crew-app-net networks: crew-app-net: external: true ``` Create network if it doesn't exist: ```bash docker network create crew-app-net ``` ## Volumes ```yaml volumes: - ./daily_order_reports_crew:/app/daily_order_reports_crew # Crew CSV archives - ./daily_order_reports_merchbay:/app/daily_order_reports_merchbay # MerchBay CSV archives - ./email.log:/app/email.log # Combined execution log ``` Both brands write to the same `email.log` with prefixes `[CREW]` and `[MERCHBAY]`. ## Deployment ### Automated Deployment (Gitea Actions) **Production deployment** is automated via Gitea Actions when pushing to `main` or `master` branch. ```bash # Trigger deployment git add . git commit -m "Update email reports" git push origin main ``` The workflow will: 1. Build Docker image 2. Transfer to production server via SSH 3. Deploy to `/var/www/apps/email_reports` 4. Start container with cron 5. Verify container is running **Registry build** is triggered by version tags: ```bash # Create version tag git tag v1.0.0 git push origin v1.0.0 ``` This builds and pushes to your Docker registry. ### Manual Deployment ```bash # Deploy via docker-compose docker-compose up -d --build # Or build specific image version docker build -t email-reports:1.0.0 . docker tag email-reports:1.0.0 your-registry/email-reports:1.0.0 docker push your-registry/email-reports:1.0.0 ``` ### Required Gitea Secrets Configure in your repository settings: - `DEPLOY_SSH_KEY` - SSH private key for deployment server - `DEPLOY_HOST` - Deployment server hostname/IP - `DEPLOY_USER` - SSH username - `REGISTRY_URL` - Docker registry URL (for version tags) - `REGISTRY_USER` - Registry username - `REGISTRY_PASSWORD` - Registry password ### Server Setup (First Time) On your production server, create the deployment directory and `.env` file: ```bash # Create directory sudo mkdir -p /var/www/apps/email_reports sudo chown $USER:$USER /var/www/apps/email_reports cd /var/www/apps/email_reports # Create .env file cat > .env << 'EOL' DB_HOST=mysql DB_PORT=3306 DB_NAME=custom_design DB_USER=crew_user DB_PASS=your_secure_password SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=mail@crewsportswear.com SMTP_PASS=your_gmail_app_password EMAIL_TO=graphics@crewsportswear.com EMAIL_BCC=webmaster@crewsportswear.com,angelo@crewsportswear.com,production@crewsportswear.com APP_URL=https://www.crewsportswear.com ADMIN_URL=https://admin.crewsportswear.app EOL chmod 600 .env # Create data directories mkdir -p daily_order_reports touch email.log chmod 666 email.log # Ensure network exists docker network create crew-app-net || true ``` Now push to trigger the first deployment! ### Multiple Instances For MerchBay, create similar setup in `email_reports_merchbay/`: ```yaml # docker-compose.yml in email_reports_merchbay/ services: email-reports-merchbay: build: . container_name: email_reports_merchbay environment: - DB_NAME=merchbay_db - EMAIL_TO=orders@merchbay.com # ... other env vars ``` ## Monitoring ### Check Container Health ```bash # Container status docker ps | grep email_reports # Should show email_reports_unified # Health check docker inspect email_reports_unified | grep -A 5 Health ``` ### View Logs ```bash # Real-time cron logs (both brands) docker exec email_reports_unified tail -f /var/log/cron.log # Email execution logs (prefixed by brand) docker exec email_reports_unified tail -f /app/email.log # Example log output: # 2026-01-02 23:55:00 [CREW] successfully sent (5 orders) # 2026-01-02 23:56:00 [MERCHBAY] No order for today # Last 50 lines docker logs --tail 50 email_reports_unified # Filter by brand docker exec email_reports_unified grep "\[CREW\]" /app/email.log | tail -10 docker exec email_reports_unified grep "\[MERCHBAY\]" /app/email.log | tail -10 ``` ### Verify Cron Schedule ```bash # View active crontab (should show both jobs) docker exec email_reports_unified crontab -l # Expected: # 55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1 # 56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1 # Check if cron is running docker exec email_reports_unified ps aux | grep crond ``` ## Troubleshooting ### Database Connection Failed ```bash # Test MySQL connectivity docker exec email_reports_crew ping mysql # Test database connection docker exec email_reports_crew php -r "new PDO('mysql:host=mysql;dbname=custom_design', 'user', 'pass');" # Check network docker network inspect crew-app-net ``` ### Email Not Sending ```bash # Enable debug mode docker exec email_reports_crew sed -i 's|// \$mail->SMTPDebug|\$mail->SMTPDebug|' /app/index.php # Run manually with debug docker exec email_reports_crew php /app/index.php # Check SMTP credentials in .env ``` ### Cron Not Running ```bash # Check cron daemon docker exec email_reports_crew ps aux | grep crond # Restart container docker restart email_reports_crew # View crontab docker exec email_reports_crew cat /etc/crontabs/root ``` ### Wrong Timezone ```bash # Verify timezone docker exec email_reports_crew date docker exec email_reports_crew cat /etc/timezone # Should show: America/Chicago ``` ### Permissions Issues ```bash # Fix CSV directory permissions docker exec email_reports_crew chmod 755 /app/daily_order_reports # Fix log file docker exec email_reports_crew chmod 666 /app/email.log ``` ## Maintenance ### Update Cron Schedule Edit Dockerfile and rebuild: ```dockerfile RUN echo "30 22 * * * cd /app && php index.php" > /etc/crontabs/root ``` ### Rotate Logs ```bash # Manually clear logs (optional) docker exec email_reports_crew truncate -s 0 /var/log/cron.log docker exec email_reports_crew truncate -s 0 /app/email.log ``` ### Backup Reports ```bash # Archive old CSV files tar -czf daily_reports_backup_$(date +%Y%m%d).tar.gz daily_order_reports/ # Or sync to S3/backup location ``` ## Security 1. **Never commit `.env`** - Use `.env.example` only 2. **Use Gmail App Passwords** - Not your main password 3. **Restrict network access** - Only join necessary networks 4. **Rotate credentials** - Change passwords regularly 5. **Monitor logs** - Check for unauthorized access ## Advantages of Separate Container ✅ **Isolation** - Reports run independently of web apps ✅ **Reusability** - Can serve multiple apps (Crew + MerchBay) ✅ **Simple Deployment** - Single purpose, easy to update ✅ **Resource Control** - Limit CPU/memory for cron jobs ✅ **Independent Scaling** - Restart without affecting web traffic ✅ **Clean Separation** - No coupling with Laravel/framework ## Next Steps 1. Test database connectivity 2. Verify SMTP credentials 3. Run manual test: `docker exec email_reports_crew php /app/index.php` 4. Wait for 23:55 or adjust cron for testing 5. Monitor logs for first automated run 6. Set up similar container for MerchBay reports