trip-planner/docker/entrypoint.sh
2025-11-16 15:53:52 +01:00

141 lines
4.7 KiB
Bash

#!/bin/bash
set -e
# Configuration
MYSQL_WAIT_ATTEMPTS=15
MYSQL_WAIT_INTERVAL=2
REDIS_WAIT_ATTEMPTS=10
echo "========================================="
echo "[INIT] Trip Planner - Production Container Init"
echo "========================================="
# Validate required environment variables
if [ -z "$APP_KEY" ]; then
echo "[INIT] ERROR: APP_KEY is not set!"
exit 1
fi
# Laravel APP_KEY must be base64: prefix + minimum 44 chars (32 bytes base64-encoded)
if [[ ! "$APP_KEY" =~ ^base64:.{44,}$ ]]; then
echo "[INIT] ERROR: APP_KEY format is invalid! Must be base64:xxxxx (generated with 'php artisan key:generate')"
exit 1
fi
if [ -z "$DB_PASSWORD" ]; then
echo "[INIT] ERROR: DB_PASSWORD is not set!"
exit 1
fi
if [ -z "$MYSQL_ROOT_PASSWORD" ]; then
echo "[INIT] ERROR: MYSQL_ROOT_PASSWORD is not set!"
exit 1
fi
# Start MariaDB in background
echo "[INIT] Starting MariaDB..."
mysqld --user=mysql --datadir=/var/lib/mysql --bind-address=127.0.0.1 &
MYSQL_PID=$!
# Start Redis in background
echo "[INIT] Starting Redis..."
redis-server --bind 127.0.0.1 --port 6379 --dir /data/redis --appendonly yes --daemonize yes
# Wait for MariaDB to be ready
echo "[INIT] Waiting for MariaDB to be ready..."
for i in $(seq 1 $MYSQL_WAIT_ATTEMPTS); do
if mysqladmin ping --socket=/run/mysqld/mysqld.sock --silent 2>/dev/null; then
echo "[INIT] MariaDB is up! (took ${i} attempts)"
break
fi
if [ $i -eq $MYSQL_WAIT_ATTEMPTS ]; then
echo "[INIT] ERROR: MariaDB failed to start within $((MYSQL_WAIT_ATTEMPTS * MYSQL_WAIT_INTERVAL)) seconds"
kill $MYSQL_PID 2>/dev/null || true
exit 1
fi
sleep $MYSQL_WAIT_INTERVAL
done
# Wait for Redis to be ready
echo "[INIT] Waiting for Redis to be ready..."
for i in $(seq 1 $REDIS_WAIT_ATTEMPTS); do
if redis-cli ping 2>/dev/null | grep -q PONG; then
echo "[INIT] Redis is up! (took ${i} attempts)"
break
fi
if [ $i -eq $REDIS_WAIT_ATTEMPTS ]; then
echo "[INIT] ERROR: Redis failed to start within ${REDIS_WAIT_ATTEMPTS} seconds"
exit 1
fi
sleep 1
done
# Check if database needs initialization
echo "[INIT] Checking database initialization..."
if ! mysql --socket=/run/mysqld/mysqld.sock -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1" &>/dev/null; then
echo "[INIT] Setting root password for first-time setup..."
mysqladmin --socket=/run/mysqld/mysqld.sock -u root password "${MYSQL_ROOT_PASSWORD}"
fi
# Create database and user if they don't exist
echo "[INIT] Ensuring database and user exist..."
# Escape single quotes in password for SQL safety
DB_PASSWORD_ESCAPED=$(echo "${DB_PASSWORD}" | sed "s/'/''/g")
mysql --socket=/run/mysqld/mysqld.sock -u root -p"${MYSQL_ROOT_PASSWORD}" <<EOSQL
CREATE DATABASE IF NOT EXISTS \`${DB_DATABASE}\`;
CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'localhost' IDENTIFIED BY '${DB_PASSWORD_ESCAPED}';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON \`${DB_DATABASE}\`.* TO '${DB_USERNAME}'@'localhost';
FLUSH PRIVILEGES;
EOSQL
echo "[INIT] Database setup verified"
# Fix permissions for persistent volumes
echo "[INIT] Fixing permissions..."
chown -R redis:redis /data/redis 2>/dev/null || true
chown -R appuser:appuser /var/www/html/storage 2>/dev/null || true
chmod -R 775 /var/www/html/storage 2>/dev/null || true
# Run Laravel migrations
echo "[INIT] Running Laravel migrations..."
cd /var/www/html
php artisan migrate --force
# Ensure storage link exists
if [ ! -L /var/www/html/public/storage ]; then
echo "[INIT] Creating storage link..."
php artisan storage:link
fi
# Stop background services gracefully (supervisor will manage them)
echo "[INIT] Stopping temporary database services..."
# Stop Redis first (faster shutdown)
echo "[INIT] Stopping temporary Redis..."
redis-cli shutdown 2>/dev/null || true
# Gracefully stop MariaDB
echo "[INIT] Stopping temporary MariaDB..."
mysqladmin --socket=/run/mysqld/mysqld.sock -u root -p"${MYSQL_ROOT_PASSWORD}" shutdown 2>/dev/null || kill $MYSQL_PID 2>/dev/null || true
# Wait for processes to actually terminate
echo "[INIT] Waiting for services to fully stop..."
for i in {1..15}; do
if ! pgrep -x mysqld >/dev/null && ! pgrep -x redis-server >/dev/null; then
echo "[INIT] All temporary services stopped successfully"
break
fi
if [ $i -eq 15 ]; then
echo "[INIT] WARNING: Services took too long to stop, forcing..."
pkill -9 mysqld || true
pkill -9 redis-server || true
sleep 1
fi
sleep 1
done
echo "========================================="
echo "[INIT] Initialization complete! Starting services..."
echo "========================================="
# Execute the main command (supervisord)
exec "$@"