Commit ea9f177f authored by Administrator's avatar Administrator

Update 7 files via Son of Anton

parent 992e5541
.git
.gitignore
.env.example
docker/
Dockerfile
captain-definition
*.md
.idea/
.vscode/
storage/logs/*
storage/cache/*
storage/sessions/*
storage/uploads/*
!storage/uploads/.gitkeep
!storage/logs/.gitkeep
\ No newline at end of file
APP_URL=http://localhost/the-club-erp/public APP_URL=http://localhost
APP_DEBUG=true APP_DEBUG=true
APP_ENV=local APP_ENV=local
......
FROM php:8.2-apache
# ── System dependencies ──
RUN apt-get update && apt-get install -y \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libicu-dev \
libzip-dev \
zip \
unzip \
default-mysql-client \
&& rm -rf /var/lib/apt/lists/*
# ── PHP extensions ──
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
pdo_mysql \
bcmath \
mbstring \
gd \
intl \
zip \
opcache \
fileinfo
# ── Apache modules ──
RUN a2enmod rewrite headers
# ── PHP configuration ──
COPY docker/php.ini /usr/local/etc/php/conf.d/99-club-erp.ini
# ── Apache vhost ──
COPY docker/000-default.conf /etc/apache2/sites-available/000-default.conf
# ── Copy application ──
COPY . /var/www/html/
# ── Create storage directories ──
RUN mkdir -p \
/var/www/html/storage/logs \
/var/www/html/storage/uploads/documents \
/var/www/html/storage/uploads/photos \
/var/www/html/storage/uploads/forms \
/var/www/html/storage/cache \
/var/www/html/storage/sessions
# ── Permissions ──
RUN chown -R www-data:www-data /var/www/html/storage \
&& chmod -R 775 /var/www/html/storage \
&& chown -R www-data:www-data /var/www/html/public \
&& chmod -R 755 /var/www/html/public
# ── Default environment (overridable via CapRover env vars) ──
ENV APP_URL=http://localhost
ENV APP_DEBUG=true
ENV APP_ENV=local
ENV DB_HOST=srv-captain--mysql-db
ENV DB_PORT=3306
ENV DB_NAME=the_club_erp
ENV DB_USER=root
ENV DB_PASS=Alarcade123#
ENV SMS_PROVIDER=
ENV SMS_API_KEY=
ENV SMS_SENDER_ID=
# ── Entrypoint ──
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
\ No newline at end of file
{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}
\ No newline at end of file
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/public
<Directory /var/www/html/public>
AllowOverride All
Require all granted
Options -Indexes +FollowSymLinks
# Fallback to index.php for all non-file requests
FallbackResource /index.php
</Directory>
# Block access to sensitive directories
<DirectoryMatch "^/var/www/html/(app|config|database|storage|cron|docker)">
Require all denied
</DirectoryMatch>
# Block .env and .git access
<FilesMatch "^\.">
Require all denied
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
\ No newline at end of file
#!/bin/bash
set -e
echo "╔══════════════════════════════════════════════════╗"
echo "║ THE CLUB ERP — CapRover Deployment Starting ║"
echo "╚══════════════════════════════════════════════════╝"
# ── Resolve DB credentials from environment ──
DB_HOST="${DB_HOST:-srv-captain--mysql-db}"
DB_PORT="${DB_PORT:-3306}"
DB_NAME="${DB_NAME:-the_club_erp}"
DB_USER="${DB_USER:-root}"
DB_PASS="${DB_PASS:-Alarcade123#}"
echo ""
echo "📡 Database: ${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
echo ""
# ── Generate .env from environment variables (so PHP app can read it) ──
cat > /var/www/html/.env <<EOF
APP_URL=${APP_URL:-http://localhost}
APP_DEBUG=${APP_DEBUG:-true}
APP_ENV=${APP_ENV:-local}
DB_HOST=${DB_HOST}
DB_PORT=${DB_PORT}
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASS=${DB_PASS}
SMS_PROVIDER=${SMS_PROVIDER:-}
SMS_API_KEY=${SMS_API_KEY:-}
SMS_SENDER_ID=${SMS_SENDER_ID:-}
EOF
echo "✅ .env generated from environment variables"
# ── Wait for MySQL to be reachable ──
echo ""
echo "⏳ Waiting for MySQL at ${DB_HOST}:${DB_PORT}..."
max_tries=60
count=0
while ! mysqladmin ping -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" --silent 2>/dev/null; do
count=$((count + 1))
if [ $count -ge $max_tries ]; then
echo "❌ FATAL: Could not connect to MySQL after ${max_tries} attempts (2 min)"
echo " Check that srv-captain--mysql-db is running in CapRover"
exit 1
fi
echo " Attempt ${count}/${max_tries} — retrying in 2s..."
sleep 2
done
echo "✅ MySQL is alive!"
# ── Create database if it doesn't exist ──
echo ""
echo "📦 Creating database '${DB_NAME}' if not exists..."
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" --default-character-set=utf8mb4 -e "
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
"
echo "✅ Database '${DB_NAME}' ready"
# ── Create seeds tracking table (not in migrations but needed by SeederRunner) ──
echo ""
echo "📋 Ensuring seeds tracking table exists..."
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" --default-character-set=utf8mb4 -e "
CREATE TABLE IF NOT EXISTS \`seeds\` (
\`id\` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
\`seed\` VARCHAR(255) NOT NULL,
\`executed_at\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY \`uq_seeds_name\` (\`seed\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
"
# ── Create async_event_queue table (in schema.sql but not in migrations) ──
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" --default-character-set=utf8mb4 -e "
CREATE TABLE IF NOT EXISTS \`async_event_queue\` (
\`id\` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
\`event_name\` VARCHAR(200) NOT NULL,
\`event_data_json\` JSON NULL,
\`status\` VARCHAR(30) NOT NULL DEFAULT 'pending',
\`attempts\` INT UNSIGNED NOT NULL DEFAULT 0,
\`max_attempts\` INT UNSIGNED NOT NULL DEFAULT 3,
\`created_at\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
\`processed_at\` TIMESTAMP NULL DEFAULT NULL,
\`failed_at\` TIMESTAMP NULL DEFAULT NULL,
\`error_message\` TEXT NULL,
INDEX \`idx_async_events_status\` (\`status\`),
INDEX \`idx_async_events_created\` (\`created_at\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
"
# ── Create cron_job_log table (in schema.sql but not in migrations) ──
mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" --default-character-set=utf8mb4 -e "
CREATE TABLE IF NOT EXISTS \`cron_job_log\` (
\`id\` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
\`job_name\` VARCHAR(200) NOT NULL,
\`started_at\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
\`finished_at\` TIMESTAMP NULL DEFAULT NULL,
\`status\` VARCHAR(30) NOT NULL DEFAULT 'running',
\`records_processed\` INT UNSIGNED NOT NULL DEFAULT 0,
\`error_message\` TEXT NULL,
\`execution_time_ms\` INT UNSIGNED NULL,
INDEX \`idx_cron_job_name\` (\`job_name\`),
INDEX \`idx_cron_job_started\` (\`started_at\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
"
echo "✅ Infrastructure tables ready"
# ══════════════════════════════════════════
# MIGRATIONS — All 15 Phases in sequence
# ══════════════════════════════════════════
echo ""
echo "╔══════════════════════════════════════════════════╗"
echo "║ RUNNING ALL MIGRATIONS ║"
echo "╚══════════════════════════════════════════════════╝"
echo ""
echo "Migration files to process:"
ls -1 /var/www/html/database/migrations/Phase_*.php 2>/dev/null | wc -l
echo " migration files found"
echo ""
cd /var/www/html
php cli.php migrate 2>&1
MIGRATE_EXIT=$?
if [ $MIGRATE_EXIT -ne 0 ]; then
echo "⚠️ Migration exited with code ${MIGRATE_EXIT}"
echo " Checking if tables were created anyway..."
TABLE_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null)
echo " Tables in database: ${TABLE_COUNT}"
if [ "${TABLE_COUNT}" -lt 5 ]; then
echo "❌ FATAL: Migration failed and database is nearly empty"
exit 1
fi
fi
# Show migration status
echo ""
echo "📊 Migration status:"
php cli.php migrate:status 2>&1 || true
echo ""
# ══════════════════════════════════════════
# SEEDS — All 15 Phases in sequence
# ══════════════════════════════════════════
echo ""
echo "╔══════════════════════════════════════════════════╗"
echo "║ RUNNING ALL SEEDS ║"
echo "╚══════════════════════════════════════════════════╝"
echo ""
echo "Seed files to process:"
ls -1 /var/www/html/database/seeds/Phase_*.php 2>/dev/null | wc -l
echo " seed files found"
echo ""
php cli.php seed 2>&1
SEED_EXIT=$?
if [ $SEED_EXIT -ne 0 ]; then
echo "⚠️ Seeding exited with code ${SEED_EXIT} — some seeds may have already run"
fi
# ── Verify deployment ──
echo ""
echo "╔══════════════════════════════════════════════════╗"
echo "║ DEPLOYMENT VERIFICATION ║"
echo "╚══════════════════════════════════════════════════╝"
echo ""
TABLE_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}';" 2>/dev/null)
echo "📊 Total tables in database: ${TABLE_COUNT}"
EMPLOYEE_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM employees;" 2>/dev/null || echo "0")
echo "👤 Employees (incl. super admin): ${EMPLOYEE_COUNT}"
ROLE_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM roles;" 2>/dev/null || echo "0")
echo "🔐 Roles: ${ROLE_COUNT}"
BRANCH_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM branches;" 2>/dev/null || echo "0")
echo "🏢 Branches: ${BRANCH_COUNT}"
RULE_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM business_rules;" 2>/dev/null || echo "0")
echo "📏 Business rules: ${RULE_COUNT}"
FORM_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM form_schemas;" 2>/dev/null || echo "0")
echo "📝 Form schemas: ${FORM_COUNT}"
WORKFLOW_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM workflow_definitions;" 2>/dev/null || echo "0")
echo "🔄 Workflows: ${WORKFLOW_COUNT}"
GOV_COUNT=$(mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" -N -e "SELECT COUNT(*) FROM governorates;" 2>/dev/null || echo "0")
echo "🗺️ Governorates: ${GOV_COUNT}"
echo ""
echo "╔══════════════════════════════════════════════════╗"
echo "║ ✅ THE CLUB ERP — DEPLOYED SUCCESSFULLY ║"
echo "║ ║"
echo "║ 🔑 Login: admin / ChangeMe123! ║"
echo "║ ⚠️ You'll be forced to change password ║"
echo "╚══════════════════════════════════════════════════╝"
echo ""
# ── Fix final permissions ──
chown -R www-data:www-data /var/www/html/storage 2>/dev/null || true
# ── Start Apache in foreground ──
echo "🚀 Starting Apache on port 80..."
exec apache2-foreground
\ No newline at end of file
; ── THE CLUB ERP — PHP Configuration ──
upload_max_filesize = 20M
post_max_size = 25M
memory_limit = 256M
max_execution_time = 120
max_input_time = 60
max_input_vars = 5000
date.timezone = Africa/Cairo
; Session
session.gc_maxlifetime = 1800
session.cookie_httponly = 1
session.use_strict_mode = 1
; Error handling
display_errors = Off
log_errors = On
error_log = /var/www/html/storage/logs/php_errors.log
; OPcache
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 1
opcache.revalidate_freq = 2
; mbstring
mbstring.internal_encoding = UTF-8
mbstring.http_output = UTF-8
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment