Projects/3BIT/winter-semester/IIS/xnecasr00/docker/app-entrypoint.sh
2026-04-14 19:28:46 +02:00

161 lines
4.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
APP_DIR=${APP_DIR:-/var/www}
cd "$APP_DIR"
DB_HOST=${DB_HOST:-mysql}
DB_PORT=${DB_PORT:-3306}
DB_USERNAME=${DB_USERNAME:-winary_user}
DB_PASSWORD=${DB_PASSWORD:-winary_password}
DB_DATABASE=${DB_DATABASE:-laravel_winary}
APP_PORT=${APP_PORT:-8741}
NPM_INSTALL_ARGS=${NPM_INSTALL_ARGS:---no-fund --no-audit --no-progress}
prepare_cache_dirs() {
mkdir -p bootstrap/cache \
storage/logs \
storage/framework/cache \
storage/framework/views \
storage/framework/sessions \
storage/framework/testing
}
clear_cached_artifacts() {
rm -f bootstrap/cache/*.php
}
ensure_php_dependencies() {
if [ -f vendor/autoload.php ]; then
return
fi
echo "Installing PHP dependencies..."
composer install --no-dev --optimize-autoloader --no-interaction --no-progress
}
wait_for_database() {
local attempt=0
while true; do
if php -r "
\$host = getenv('DB_HOST') ?: 'mysql';
\$port = getenv('DB_PORT') ?: '3306';
\$db = getenv('DB_DATABASE') ?: 'laravel_winary';
\$user = getenv('DB_USERNAME') ?: 'winary_user';
\$pass = getenv('DB_PASSWORD') ?: 'winary_password';
\$dsn = \"mysql:host=\$host;port=\$port;dbname=\$db\";
try {
new PDO(\$dsn, \$user, \$pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
} catch (Exception \$e) {
fwrite(STDERR, \$e->getMessage());
exit(1);
}
"; then
echo "Database is ready."
break
else
attempt=$((attempt + 1))
echo "Database not ready (attempt ${attempt}), retrying in 2s..."
sleep 2
fi
done
}
install_node_dependencies() {
if [ -d node_modules ]; then
echo "Node dependencies already installed, skipping npm install."
else
echo "Installing Node dependencies..."
npm ci $NPM_INSTALL_ARGS
fi
}
build_assets() {
echo "Building frontend assets..."
npm run build
}
ensure_storage_symlink() {
local link_path="public/storage"
local desired_target="../storage/app/public"
mkdir -p storage/app/public
if [ -L "$link_path" ]; then
local current_target
current_target=$(readlink "$link_path")
if [ "$current_target" = "$desired_target" ] || [ "$current_target" = "/var/www/storage/app/public" ]; then
return
fi
echo "Updating storage symlink (was pointing to $current_target)..."
rm "$link_path"
elif [ -e "$link_path" ]; then
echo "Removing existing public/storage to recreate symlink..."
rm -rf "$link_path"
fi
if php artisan storage:link --relative >/dev/null 2>&1; then
return
fi
ln -s "$desired_target" "$link_path"
}
ensure_docs_symlink() {
local source_path="doc.html"
local link_path="public/doc.html"
if [ ! -f "$source_path" ]; then
echo "doc.html not found at $source_path, skipping docs symlink."
return
fi
mkdir -p public
if [ -L "$link_path" ]; then
local current_target
current_target=$(readlink "$link_path")
if [ "$current_target" = "../doc.html" ] || [ "$current_target" = "/var/www/doc.html" ]; then
return
fi
echo "Updating doc.html symlink (was pointing to $current_target)..."
rm "$link_path"
elif [ -e "$link_path" ]; then
echo "Removing existing public/doc.html to recreate symlink..."
rm -rf "$link_path"
fi
ln -s ../doc.html "$link_path"
}
fix_permissions() {
# Ensure runtime-writable dirs are accessible even on bind mounts
chown -R www-data:www-data storage bootstrap/cache public/storage || true
chmod -R ug+rwX storage bootstrap/cache public/storage || true
}
prepare_cache_dirs
clear_cached_artifacts
wait_for_database
ensure_php_dependencies
php artisan migrate:fresh --seed --force
install_node_dependencies
build_assets
ensure_storage_symlink
ensure_docs_symlink
fix_permissions
# Normalize command to always serve on configured APP_PORT when using artisan serve
if [ "$#" -eq 0 ]; then
set -- php artisan serve --host=0.0.0.0 --port="${APP_PORT}"
elif [ "$1" = "php" ] && [ "${2:-}" = "artisan" ] && [ "${3:-}" = "serve" ]; then
shift 3
set -- php artisan serve --host=0.0.0.0 --port="${APP_PORT}" "$@"
fi
exec "$@"