#!/usr/bin/env bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Get script directory and project root SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # Detect Docker or Podman CONTAINER_CLI="" # Check if docker is actually podman in disguise if command -v docker &> /dev/null && docker --version 2>&1 | grep -q "podman"; then CONTAINER_CLI="podman" echo -e "${GREEN}Using Podman (via docker alias)${NC}" elif command -v docker &> /dev/null && docker info &> /dev/null; then CONTAINER_CLI="docker" echo -e "${GREEN}Using Docker${NC}" elif command -v podman &> /dev/null; then CONTAINER_CLI="podman" echo -e "${GREEN}Using Podman${NC}" else echo -e "${RED}✗ Neither Docker nor Podman found. Please install one of them first.${NC}" echo -e "${YELLOW}Install Docker: https://docs.docker.com/get-docker/${NC}" echo -e "${YELLOW}Install Podman: https://podman.io/getting-started/installation${NC}" exit 1 fi echo -e "${GREEN}=== Dish Planner Development Setup ===${NC}\n" # Check if .env exists in backend if [ ! -f "$PROJECT_ROOT/backend/.env" ]; then echo -e "${YELLOW}Creating backend/.env from .env.example...${NC}" cp "$PROJECT_ROOT/backend/.env.example" "$PROJECT_ROOT/backend/.env" echo -e "${GREEN}✓ Created backend/.env${NC}\n" fi # Ensure APP_PORT is set for Podman (can't use privileged port 80) if [ "$CONTAINER_CLI" = "podman" ] && ! grep -q "^APP_PORT=" "$PROJECT_ROOT/backend/.env"; then echo -e "${YELLOW}Setting APP_PORT=8000 for Podman (non-privileged port)...${NC}" echo "APP_PORT=8000" >> "$PROJECT_ROOT/backend/.env" fi # Backend setup echo -e "${GREEN}=== Backend Setup ===${NC}" cd "$PROJECT_ROOT/backend" # Install dependencies if vendor doesn't exist if [ ! -d "vendor" ]; then echo -e "${YELLOW}No vendor directory found. Installing dependencies with Docker...${NC}" # Use a standalone PHP/Composer Docker image to install dependencies # This is the recommended Laravel approach for first-time setup # Configure for Docker or Podman VOLUME_OPTS="$PROJECT_ROOT/backend:/var/www/html" USER_OPTS="-u $(id -u):$(id -g)" EXTRA_OPTS="" if [ "$CONTAINER_CLI" = "podman" ]; then # Podman on SELinux systems needs :Z and --userns=keep-id to maintain user ID VOLUME_OPTS="$VOLUME_OPTS:Z" USER_OPTS="" EXTRA_OPTS="--userns=keep-id" fi $CONTAINER_CLI run --rm \ $USER_OPTS \ $EXTRA_OPTS \ -v "$VOLUME_OPTS" \ -w /var/www/html \ docker.io/laravelsail/php84-composer:latest \ composer install --ignore-platform-reqs echo -e "${GREEN}✓ Backend dependencies installed${NC}\n" else echo -e "${GREEN}✓ Backend dependencies already installed${NC}\n" fi # Check if database volume exists - if not, we're doing fresh initialization FRESH_DB=false if ! $CONTAINER_CLI volume inspect sail-mysql &>/dev/null && ! $CONTAINER_CLI volume inspect backend_sail-mysql &>/dev/null; then FRESH_DB=true echo -e "${YELLOW}Fresh database initialization detected${NC}" fi # Start containers using compose directly (docker-compose.override.yml is automatically used) echo -e "${YELLOW}Starting backend containers...${NC}" if $CONTAINER_CLI compose up -d 2>&1 | tee /tmp/compose-up.log; then echo -e "${GREEN}✓ Containers started${NC}\n" else echo -e "${RED}✗ Failed to start containers. Check /tmp/compose-up.log for details${NC}" exit 1 fi # Wait for database to be ready echo -e "${YELLOW}Waiting for database to be ready...${NC}" MAX_ATTEMPTS=30 ATTEMPT=0 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do if $CONTAINER_CLI compose exec mysql mysqladmin ping -h localhost --silent 2>/dev/null; then echo -e "${GREEN}✓ Database is ready${NC}" break fi ATTEMPT=$((ATTEMPT + 1)) echo -e "${YELLOW}Waiting for database... (attempt $ATTEMPT/$MAX_ATTEMPTS)${NC}" sleep 2 done if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then echo -e "${RED}✗ Database failed to become ready${NC}" exit 1 fi # Give MySQL extra time on fresh initialization to create users if [ "$FRESH_DB" = true ]; then echo -e "${YELLOW}Waiting for fresh database to complete initialization...${NC}" sleep 10 else sleep 3 fi # Run migrations echo -e "${YELLOW}Running database migrations...${NC}" $CONTAINER_CLI compose exec backend php artisan migrate --force # Check if database has data echo -e "${YELLOW}Checking if database needs seeding...${NC}" TABLE_COUNT=$($CONTAINER_CLI compose exec backend php artisan tinker --execute="echo \DB::table('users')->count();" 2>/dev/null | tail -1 | tr -d '[:space:]' || echo "0") # Default to 0 if not a number if ! [[ "$TABLE_COUNT" =~ ^[0-9]+$ ]]; then TABLE_COUNT=0 fi if [ "$TABLE_COUNT" -eq "0" ]; then echo -e "${YELLOW}Database is empty. Run seeders? (y/n)${NC}" read -r response if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then $CONTAINER_CLI compose exec backend php artisan db:seed echo -e "${GREEN}✓ Database seeded${NC}\n" fi fi echo -e "${GREEN}✓ Backend setup complete${NC}" echo -e "${GREEN}Backend API running at: http://localhost:8000${NC}\n" # Display summary echo -e "${GREEN}=== Development Environment Ready ===${NC}" echo -e "${GREEN}Backend API:${NC} http://localhost:8000" echo -e "${GREEN}Frontend:${NC} http://localhost:5173" echo -e "${GREEN}Database:${NC} MySQL on localhost:3306" echo -e "" echo -e "${YELLOW}Note:${NC} Frontend container will install dependencies and start automatically." echo -e "${YELLOW}To view frontend logs:${NC}" echo -e " cd backend && $CONTAINER_CLI compose logs -f frontend" echo -e "" echo -e "${YELLOW}To stop all services:${NC}" echo -e " cd backend && $CONTAINER_CLI compose down"