Some checks failed
Deploy Production Email Reports (Unified) / deploy (push) Failing after 23s
472 lines
12 KiB
Markdown
472 lines
12 KiB
Markdown
# 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
|