#!/bin/bash # scripts/docker-init.sh # ============================================================================ # CONTAINER INITIALIZATION SCRIPT # ============================================================================ # Purpose: # This script is run when the dev container is created for the first time. # It handles all first-run setup tasks to ensure a fully working environment. # # Tasks performed: # 1. Install npm dependencies (if not already done) # 2. Wait for PostgreSQL to be ready # 3. Wait for Redis to be ready # 4. Initialize the database schema # 5. Seed the database with development data # # Usage: # This script is called automatically by devcontainer.json's postCreateCommand. # It can also be run manually: ./scripts/docker-init.sh # ============================================================================ set -e # Exit immediately on error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # ============================================================================ # 1. Install npm dependencies # ============================================================================ log_info "Step 1/5: Installing npm dependencies..." if [ -d "node_modules" ] && [ -f "node_modules/.package-lock.json" ]; then log_info "node_modules exists, running npm install to sync..." fi npm install log_success "npm dependencies installed." # ============================================================================ # 2. Wait for PostgreSQL to be ready # ============================================================================ log_info "Step 2/5: Waiting for PostgreSQL to be ready..." POSTGRES_HOST="${DB_HOST:-postgres}" POSTGRES_PORT="${DB_PORT:-5432}" POSTGRES_USER="${DB_USER:-postgres}" POSTGRES_DB="${DB_NAME:-flyer_crawler_dev}" MAX_RETRIES=30 RETRY_COUNT=0 until PGPASSWORD="${DB_PASSWORD:-postgres}" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "postgres" -c '\q' 2>/dev/null; do RETRY_COUNT=$((RETRY_COUNT + 1)) if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then log_error "PostgreSQL did not become ready after $MAX_RETRIES attempts. Exiting." exit 1 fi log_warning "PostgreSQL is not ready yet (attempt $RETRY_COUNT/$MAX_RETRIES). Waiting 2 seconds..." sleep 2 done log_success "PostgreSQL is ready." # ============================================================================ # 3. Wait for Redis to be ready # ============================================================================ log_info "Step 3/5: Waiting for Redis to be ready..." REDIS_HOST="${REDIS_HOST:-redis}" REDIS_PORT="${REDIS_PORT:-6379}" MAX_RETRIES=30 RETRY_COUNT=0 # Extract host from REDIS_URL if set if [ -n "$REDIS_URL" ]; then # Parse redis://host:port format REDIS_HOST=$(echo "$REDIS_URL" | sed -E 's|redis://([^:]+):?.*|\1|') fi until redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" ping 2>/dev/null | grep -q PONG; do RETRY_COUNT=$((RETRY_COUNT + 1)) if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then log_error "Redis did not become ready after $MAX_RETRIES attempts. Exiting." exit 1 fi log_warning "Redis is not ready yet (attempt $RETRY_COUNT/$MAX_RETRIES). Waiting 2 seconds..." sleep 2 done log_success "Redis is ready." # ============================================================================ # 4. Check if database needs initialization # ============================================================================ log_info "Step 4/5: Checking database state..." # Check if the users table exists (indicator of initialized schema) TABLE_EXISTS=$(PGPASSWORD="${DB_PASSWORD:-postgres}" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -t -c "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'users');" 2>/dev/null | tr -d '[:space:]' || echo "f") if [ "$TABLE_EXISTS" = "t" ]; then log_info "Database schema already exists. Skipping initialization." log_info "To reset the database, run: npm run db:reset:dev" else log_info "Database schema not found. Initializing..." # ============================================================================ # 5. Initialize and seed the database # ============================================================================ log_info "Step 5/5: Running database initialization and seed..." # The db:reset:dev script handles both schema creation and seeding npm run db:reset:dev log_success "Database initialized and seeded successfully." fi # ============================================================================ # Done! # ============================================================================ echo "" log_success "==========================================" log_success "Container initialization complete!" log_success "==========================================" echo "" log_info "Default test accounts:" echo " Admin: admin@example.com / adminpass" echo " User: user@example.com / userpass" echo "" log_info "To start the development server, run:" echo " npm run dev:container" echo ""