Compare commits
8 Commits
388d02051f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a857d2bfa | ||
|
|
2eeec4377f | ||
|
|
1c19c86205 | ||
|
|
0ccda81dd7 | ||
|
|
c2ed5efab5 | ||
|
|
3dcc7c4c6e | ||
|
|
afa05d272e | ||
|
|
0f75206307 |
10
.env.example
10
.env.example
@@ -16,8 +16,10 @@ DB_PASS_MERCHBAY=your_merchbay_password
|
|||||||
SMTP_HOST=smtp.gmail.com
|
SMTP_HOST=smtp.gmail.com
|
||||||
SMTP_PORT=587
|
SMTP_PORT=587
|
||||||
|
|
||||||
# Crew SMTP (mail@crewsportswear.com)
|
# Crew SMTP Account (mail@crewsportswear.com)
|
||||||
SMTP_PASS_CREW=your_crew_gmail_app_password
|
# Gmail App Password for: mail@crewsportswear.com
|
||||||
|
SMTP_PASS_CREW=
|
||||||
|
|
||||||
# MerchBay SMTP (support@merchbay.com)
|
# MerchBay SMTP Account (support@merchbay.com)
|
||||||
SMTP_PASS_MERCHBAY=your_merchbay_gmail_app_password
|
# Gmail App Password for: support@merchbay.com
|
||||||
|
SMTP_PASS_MERCHBAY=
|
||||||
|
|||||||
@@ -105,8 +105,21 @@ jobs:
|
|||||||
echo "Starting unified container (env vars from .env file)"
|
echo "Starting unified container (env vars from .env file)"
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|
||||||
echo "Waiting for container to start"
|
echo "Waiting for container to start (30 seconds)..."
|
||||||
sleep 10
|
sleep 5
|
||||||
|
|
||||||
|
# Check if container is running or restarting
|
||||||
|
CONTAINER_STATE=$(docker inspect --format='{{.State.Status}}' email_reports_unified 2>/dev/null || echo "not_found")
|
||||||
|
echo "Container state: $CONTAINER_STATE"
|
||||||
|
|
||||||
|
if [ "$CONTAINER_STATE" = "restarting" ]; then
|
||||||
|
echo "Container is restarting - showing logs:"
|
||||||
|
docker logs email_reports_unified
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait a bit more for initialization
|
||||||
|
sleep 25
|
||||||
|
|
||||||
if docker ps --format '{{.Names}}' | grep -q email_reports_unified; then
|
if docker ps --format '{{.Names}}' | grep -q email_reports_unified; then
|
||||||
echo "✓ Container is running"
|
echo "✓ Container is running"
|
||||||
@@ -146,7 +159,8 @@ jobs:
|
|||||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||||
run: |
|
run: |
|
||||||
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
|
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
|
||||||
echo "Container status:"unified --format "table {{.Names}}\t{{.Status}}\t{{.State}}"
|
echo "Container status:"
|
||||||
|
docker ps --filter "name=email_reports_unified" --format "table {{.Names}}\t{{.Status}}\t{{.State}}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Recent logs:"
|
echo "Recent logs:"
|
||||||
@@ -163,6 +177,5 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Filter by brand:"
|
echo "Filter by brand:"
|
||||||
echo " docker exec email_reports_unified grep '[CREW]' /app/email.log"
|
echo " docker exec email_reports_unified grep '[CREW]' /app/email.log"
|
||||||
echo " docker exec email_reports_unified grep '[MERCHBAY]'
|
echo " docker exec email_reports_unified grep '[MERCHBAY]' /app/email.log"
|
||||||
echo " docker exec email_reports_crew tail -f /app/email.log"
|
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ COPY . /app/
|
|||||||
RUN mkdir -p /app/daily_order_reports_crew /app/daily_order_reports_merchbay && \
|
RUN mkdir -p /app/daily_order_reports_crew /app/daily_order_reports_merchbay && \
|
||||||
chmod 755 /app/daily_order_reports_crew /app/daily_order_reports_merchbay
|
chmod 755 /app/daily_order_reports_crew /app/daily_order_reports_merchbay
|
||||||
|
|
||||||
|
# Copy entrypoint script
|
||||||
|
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
|
RUN chmod +x /docker-entrypoint.sh
|
||||||
|
|
||||||
# Create crontab with both reports
|
# Create crontab with both reports
|
||||||
RUN echo "55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1" > /etc/crontabs/root && \
|
RUN echo "55 23 * * * BRAND=crew php /app/send_report.php >> /var/log/cron.log 2>&1" > /etc/crontabs/root && \
|
||||||
echo "56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1" >> /etc/crontabs/root && \
|
echo "56 23 * * * BRAND=merchbay php /app/send_report.php >> /var/log/cron.log 2>&1" >> /etc/crontabs/root && \
|
||||||
@@ -35,5 +39,5 @@ RUN touch /var/log/cron.log && \
|
|||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD ps aux | grep -v grep | grep -q crond || exit 1
|
CMD ps aux | grep -v grep | grep -q crond || exit 1
|
||||||
|
|
||||||
# Start cron in foreground
|
# Use entrypoint script
|
||||||
CMD crond -f -l 2
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ The unified container handles both brands using the `BRAND` environment variable
|
|||||||
|
|
||||||
**Crew Sportswear (`BRAND=crew`)**:
|
**Crew Sportswear (`BRAND=crew`)**:
|
||||||
- Database: `custom_design`
|
- Database: `custom_design`
|
||||||
|
- SMTP: `mail@crewsportswear.com`
|
||||||
- From: `orders@crewsportswear.com`
|
- From: `orders@crewsportswear.com`
|
||||||
- To: `graphics@crewsportswear.com`
|
- To: `graphics@crewsportswear.com`
|
||||||
- BCC: webmaster, angelo, production @crewsportswear.com
|
- BCC: webmaster, angelo, production @crewsportswear.com
|
||||||
@@ -158,12 +159,15 @@ The unified container handles both brands using the `BRAND` environment variable
|
|||||||
|
|
||||||
**MerchBay (`BRAND=merchbay`)**:
|
**MerchBay (`BRAND=merchbay`)**:
|
||||||
- Database: `merchbay_laravel`
|
- Database: `merchbay_laravel`
|
||||||
|
- SMTP: `support@merchbay.com`
|
||||||
- From: `orders@merchbay.com`
|
- From: `orders@merchbay.com`
|
||||||
- To: `graphics@crewsportswear.com`
|
- To: `graphics@crewsportswear.com`
|
||||||
- BCC: webmaster, production @crewsportswear.com
|
- BCC: webmaster, production @crewsportswear.com
|
||||||
- Admin: https://merchbay.app
|
- Admin: https://merchbay.app
|
||||||
- CSV: `daily_order_reports_merchbay/`
|
- CSV: `daily_order_reports_merchbay/`
|
||||||
|
|
||||||
|
**Note**: Each brand uses its own Gmail account for SMTP authentication.
|
||||||
|
|
||||||
## Networks
|
## Networks
|
||||||
|
|
||||||
Container must be on **crew-app-net** to access MySQL:
|
Container must be on **crew-app-net** to access MySQL:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
email-reports:
|
email-reports:
|
||||||
build: .
|
image: email_reports_unified:latest
|
||||||
container_name: email_reports_unified
|
container_name: email_reports_unified
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
90
docker-entrypoint.sh
Normal file
90
docker-entrypoint.sh
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Email Reports Container Starting..."
|
||||||
|
echo "Current time: $(date)"
|
||||||
|
echo "Timezone: $(date +%Z)"
|
||||||
|
|
||||||
|
# Verify crontab is configured
|
||||||
|
echo ""
|
||||||
|
echo "Cron schedule:"
|
||||||
|
crontab -l || echo "Warning: No crontab found"
|
||||||
|
|
||||||
|
# Create log file if it doesn't exist
|
||||||
|
touch /var/log/cron.log
|
||||||
|
chmod 666 /var/log/cron.log
|
||||||
|
|
||||||
|
# Create email log if it doesn't exist
|
||||||
|
touch /app/email.log
|
||||||
|
chmod 666 /app/email.log
|
||||||
|
|
||||||
|
# Test PHP
|
||||||
|
echo ""
|
||||||
|
echo "Testing PHP..."
|
||||||
|
php -v || { echo "PHP test failed"; exit 1; }
|
||||||
|
|
||||||
|
# Test database connectivity (optional - won't fail if not reachable)
|
||||||
|
echo ""
|
||||||
|
echo "Environment variables loaded:"
|
||||||
|
echo " DB_HOST_CREW: ${DB_HOST_CREW:-not set}"
|
||||||
|
echo " DB_NAME_CREW: ${DB_NAME_CREW:-not set}"
|
||||||
|
echo " DB_USER_CREW: ${DB_USER_CREW:-not set}"
|
||||||
|
echo " DB_HOST_MERCHBAY: ${DB_HOST_MERCHBAY:-not set}"
|
||||||
|
echo " DB_NAME_MERCHBAY: ${DB_NAME_MERCHBAY:-not set}"
|
||||||
|
echo " DB_USER_MERCHBAY: ${DB_USER_MERCHBAY:-not set}"
|
||||||
|
echo " SMTP_HOST: ${SMTP_HOST:-not set}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test DNS resolution for database hosts
|
||||||
|
echo "Testing database host DNS resolution..."
|
||||||
|
if [ -n "${DB_HOST_CREW}" ]; then
|
||||||
|
echo -n " Crew DB (${DB_HOST_CREW}): "
|
||||||
|
getent hosts "${DB_HOST_CREW}" > /dev/null 2>&1 && echo "✓ Resolved" || echo "✗ Cannot resolve"
|
||||||
|
fi
|
||||||
|
if [ -n "${DB_HOST_MERCHBAY}" ]; then
|
||||||
|
echo -n " MerchBay DB (${DB_HOST_MERCHBAY}): "
|
||||||
|
getent hosts "${DB_HOST_MERCHBAY}" > /dev/null 2>&1 && echo "✓ Resolved" || echo "✗ Cannot resolve"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Start crond in background
|
||||||
|
echo ""
|
||||||
|
echo "Starting cron daemon..."
|
||||||
|
echo "Logs will be written to:"
|
||||||
|
echo " - Cron output: /var/log/cron.log"
|
||||||
|
echo " - Email logs: /app/email.log"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Start crond in background
|
||||||
|
crond -l 2
|
||||||
|
|
||||||
|
# Verify crond started
|
||||||
|
sleep 2
|
||||||
|
if ! ps aux | grep -v grep | grep -q crond; then
|
||||||
|
echo "ERROR: crond failed to start"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Cron daemon is running"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Send test emails for both brands
|
||||||
|
echo "Sending test emails to verify configuration..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "[Testing Crew Sportswear]"
|
||||||
|
TEST_EMAIL=true BRAND=crew php /app/send_report.php
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "[Testing MerchBay]"
|
||||||
|
TEST_EMAIL=true BRAND=merchbay php /app/send_report.php
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "✓ Test emails sent to webmaster@crewsportswear.com"
|
||||||
|
echo ""
|
||||||
|
echo "Container is ready. Tailing logs..."
|
||||||
|
echo "Press Ctrl+C to stop (but don't - this keeps the container alive!)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Keep container alive by tailing logs
|
||||||
|
tail -f /var/log/cron.log /app/email.log
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
include 'dbconfig.php';
|
// dbconfig.php not needed - using environment variables directly
|
||||||
require("phpmailer/class.phpmailer.php");
|
require("phpmailer/class.phpmailer.php");
|
||||||
date_default_timezone_set('America/Chicago');
|
date_default_timezone_set('America/Chicago');
|
||||||
$dateToday = date('Y-m-d');
|
$dateToday = date('Y-m-d');
|
||||||
@@ -8,12 +8,14 @@ $dateTimeToday = date("Y-m-d H:i:s");
|
|||||||
|
|
||||||
// Determine which brand to process
|
// Determine which brand to process
|
||||||
$brand = getenv('BRAND') ?: 'crew'; // 'crew' or 'merchbay'
|
$brand = getenv('BRAND') ?: 'crew'; // 'crew' or 'merchbay'
|
||||||
|
$is_test = getenv('TEST_EMAIL') === 'true';
|
||||||
|
|
||||||
// Brand-specific configuration
|
// Brand-specific configuration
|
||||||
$config = [
|
$config = [
|
||||||
'crew' => [
|
'crew' => [
|
||||||
'db_name' => getenv('DB_NAME_CREW') ?: 'custom_design',
|
'db_name' => getenv('DB_NAME_CREW') ?: 'custom_design',
|
||||||
'db_host' => getenv('DB_HOST_CREW') ?: getenv('DB_HOST') ?: 'mysql',
|
'db_host' => getenv('DB_HOST_CREW') ?: getenv('DB_HOST') ?: 'mysql',
|
||||||
|
'db_port' => getenv('DB_PORT_CREW') ?: '3306',
|
||||||
'db_user' => getenv('DB_USER_CREW') ?: 'crew_user',
|
'db_user' => getenv('DB_USER_CREW') ?: 'crew_user',
|
||||||
'db_pass' => getenv('DB_PASS_CREW') ?: getenv('DB_PASS'),
|
'db_pass' => getenv('DB_PASS_CREW') ?: getenv('DB_PASS'),
|
||||||
'smtp_user' => 'mail@crewsportswear.com',
|
'smtp_user' => 'mail@crewsportswear.com',
|
||||||
@@ -30,6 +32,7 @@ $config = [
|
|||||||
'merchbay' => [
|
'merchbay' => [
|
||||||
'db_name' => getenv('DB_NAME_MERCHBAY') ?: 'merchbay_laravel',
|
'db_name' => getenv('DB_NAME_MERCHBAY') ?: 'merchbay_laravel',
|
||||||
'db_host' => getenv('DB_HOST_MERCHBAY') ?: getenv('DB_HOST') ?: 'mysql',
|
'db_host' => getenv('DB_HOST_MERCHBAY') ?: getenv('DB_HOST') ?: 'mysql',
|
||||||
|
'db_port' => getenv('DB_PORT_MERCHBAY') ?: '3306',
|
||||||
'db_user' => getenv('DB_USER_MERCHBAY') ?: 'merchbay_user',
|
'db_user' => getenv('DB_USER_MERCHBAY') ?: 'merchbay_user',
|
||||||
'db_pass' => getenv('DB_PASS_MERCHBAY') ?: getenv('DB_PASS'),
|
'db_pass' => getenv('DB_PASS_MERCHBAY') ?: getenv('DB_PASS'),
|
||||||
'smtp_user' => 'support@merchbay.com',
|
'smtp_user' => 'support@merchbay.com',
|
||||||
@@ -50,7 +53,7 @@ $cfg = $config[$brand];
|
|||||||
// Connect to brand-specific database
|
// Connect to brand-specific database
|
||||||
try {
|
try {
|
||||||
$conn = new PDO(
|
$conn = new PDO(
|
||||||
"mysql:host={$cfg['db_host']};dbname={$cfg['db_name']}",
|
"mysql:host={$cfg['db_host']};port={$cfg['db_port']};dbname={$cfg['db_name']}",
|
||||||
$cfg['db_user'],
|
$cfg['db_user'],
|
||||||
$cfg['db_pass']
|
$cfg['db_pass']
|
||||||
);
|
);
|
||||||
@@ -127,10 +130,16 @@ if($result > 0){
|
|||||||
$mail->Password = $cfg['smtp_pass'];
|
$mail->Password = $cfg['smtp_pass'];
|
||||||
|
|
||||||
$mail->SetFrom($cfg['email_from'], $cfg['email_from_name']);
|
$mail->SetFrom($cfg['email_from'], $cfg['email_from_name']);
|
||||||
$mail->addAddress($cfg['email_to']);
|
|
||||||
|
|
||||||
foreach ($cfg['email_bcc'] as $bcc) {
|
// Check if this is a test email (override recipients)
|
||||||
$mail->addBCC($bcc);
|
$test_mode = getenv('TEST_EMAIL') === 'true';
|
||||||
|
if ($test_mode) {
|
||||||
|
$mail->addAddress('webmaster@crewsportswear.com');
|
||||||
|
} else {
|
||||||
|
$mail->addAddress($cfg['email_to']);
|
||||||
|
foreach ($cfg['email_bcc'] as $bcc) {
|
||||||
|
$mail->addBCC($bcc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$mail->addAttachment($filename);
|
$mail->addAttachment($filename);
|
||||||
@@ -141,14 +150,17 @@ if($result > 0){
|
|||||||
$mail->IsHTML(true);
|
$mail->IsHTML(true);
|
||||||
|
|
||||||
if(!$mail->Send()){
|
if(!$mail->Send()){
|
||||||
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} Mailer Error: " . $mail->ErrorInfo . "\n";
|
$test_label = $is_test ? ' [TEST]' : ' [CRON]';
|
||||||
|
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']}{$test_label} Mailer Error: " . $mail->ErrorInfo . "\n";
|
||||||
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
||||||
} else {
|
} else {
|
||||||
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} successfully sent ({$result} orders)\n";
|
$test_label = $is_test ? ' [TEST]' : ' [CRON]';
|
||||||
|
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']}{$test_label} successfully sent ({$result} orders)\n";
|
||||||
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']} No order for today\n";
|
$test_label = $is_test ? ' [TEST]' : ' [CRON]';
|
||||||
|
$msg = $dateTimeToday . "\t\t\t{$cfg['log_prefix']}{$test_label} No order for today\n";
|
||||||
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
file_put_contents('email.log', print_r($msg, true), FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user