#!/usr/bin/env bash set -euo pipefail # Simple setup script to bootstrap the Dockerized dev stack for this project. # - Builds and starts containers (php, nginx, mariadb, mailpit via override) # - Installs composer dependencies # - Ensures APP_SECRET is set (generates if empty) # - Creates and migrates the database # - Installs/imports JS dependencies # - Prints helpful info on success # Usage: # ./docker/setup.sh # full setup # ./docker/setup.sh --no-build # skip image rebuild # ./docker/setup.sh --down # stop and remove containers (down) # ./docker/setup.sh --recreate # force recreate containers ROOT_DIR=$(cd "$(dirname "$0")"/.. && pwd) DOCKER_DIR="$ROOT_DIR/docker" # Determine the docker compose command (V2 'docker compose' or V1 'docker-compose') if docker compose version >/dev/null 2>&1; then DOCKER_COMPOSE="docker compose" elif command -v docker-compose >/dev/null 2>&1; then DOCKER_COMPOSE="docker-compose" else echo "Error: Neither 'docker compose' nor 'docker-compose' was found. Please install Docker Compose." >&2 exit 1 fi # Helper to run docker compose from the docker/ directory dc() { (cd "$DOCKER_DIR" && $DOCKER_COMPOSE -f compose.yaml "$@"); } REBUILD=1 RECREATE=0 DOWN_ONLY=0 for arg in "$@"; do case "$arg" in --no-build) REBUILD=0 ;; --recreate) RECREATE=1 ;; --down) DOWN_ONLY=1 ;; *) echo "Unknown option: $arg" >&2; exit 1 ;; esac done need() { command -v "$1" >/dev/null 2>&1 || { echo "Error: '$1' is required but not installed." >&2; exit 1; }; } need docker if [ "$DOWN_ONLY" -eq 1 ]; then dc down exit 0 fi BUILD_ARGS=() if [ "$REBUILD" -eq 1 ]; then BUILD_ARGS+=("--build") fi if [ "$RECREATE" -eq 1 ]; then BUILD_ARGS+=("--force-recreate") fi # Start stack dc up "${BUILD_ARGS[@]}" # Helper to run commands in php container pexec() { dc exec -T php "$@"; } # Wait for database to be healthy (mariadb) printf "Waiting for database to be healthy..." # Use docker inspect health status DB_HEALTH="" for i in {1..60}; do DB_HEALTH=$(docker inspect -f '{{.State.Health.Status}}' "$(docker ps --filter name=_database_ --format '{{.ID}}' | head -n1)" 2>/dev/null || true) if [ "$DB_HEALTH" = "healthy" ]; then echo " OK" break fi printf "." sleep 2 if [ "$i" -eq 60 ]; then echo "\nWarning: database health check not healthy yet, continuing anyway." fi done # Ensure composer is available and install dependencies pexec composer install --no-interaction # Ensure APP_SECRET is set if grep -q '^APP_SECRET=$' "$ROOT_DIR/.env" 2>/dev/null; then echo "Generating APP_SECRET in .env.local..." mkdir -p "$ROOT_DIR" SECRET=$(openssl rand -hex 16) # Write to .env.local so we don't commit it if [ ! -f "$ROOT_DIR/.env.local" ]; then printf "APP_SECRET=%s\n" "$SECRET" > "$ROOT_DIR/.env.local" elif ! grep -q '^APP_SECRET=' "$ROOT_DIR/.env.local"; then printf "APP_SECRET=%s\n" "$SECRET" >> "$ROOT_DIR/.env.local" fi fi # Prepare DB pexec php bin/console doctrine:database:create --if-not-exists || true pexec php bin/console doctrine:migrations:migrate -n || true # Import JS deps (Importmap/Asset Mapper) pexec php bin/console importmap:install || true APP_URL=http://localhost:8080 MAILPIT_URL=http://localhost:8025 cat <