95 lines
2.7 KiB
Bash
Executable File
95 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -Eeuo pipefail
|
|
|
|
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
COMPOSE_FILE="$ROOT_DIR/docker/docker-compose.yml"
|
|
|
|
die() {
|
|
echo "[local] $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || die "'$1' command not found"
|
|
}
|
|
|
|
ensure_port_free() {
|
|
local port="$1"
|
|
|
|
if lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
|
|
echo "[local] port $port is already in use:" >&2
|
|
lsof -nP -iTCP:"$port" -sTCP:LISTEN >&2 || true
|
|
die "stop the process using port $port, then rerun start-local.sh"
|
|
fi
|
|
}
|
|
|
|
wait_for_mysql() {
|
|
local service="$1"
|
|
local password="$2"
|
|
local attempts=60
|
|
|
|
echo "[local] waiting for $service..."
|
|
for ((attempt = 1; attempt <= attempts; attempt++)); do
|
|
if docker compose -f "$COMPOSE_FILE" exec -T "$service" \
|
|
mysqladmin ping -h 127.0.0.1 -uroot "-p$password" --silent \
|
|
>/dev/null 2>&1; then
|
|
echo "[local] $service is ready"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
docker compose -f "$COMPOSE_FILE" logs --tail=40 "$service" >&2 || true
|
|
die "$service did not become ready within ${attempts}s"
|
|
}
|
|
|
|
require_command docker
|
|
require_command curl
|
|
require_command lsof
|
|
require_command pnpm
|
|
|
|
docker info >/dev/null 2>&1 || die "Docker daemon is not running or is not accessible"
|
|
|
|
[[ -x "$ROOT_DIR/apps/secretary-api/.venv/bin/uvicorn" ]] || \
|
|
die "Secretary API virtualenv is missing: apps/secretary-api/.venv/bin/uvicorn"
|
|
|
|
# The development processes use these host ports. Never kill an existing process
|
|
# implicitly; report the owner so the developer can decide what to stop.
|
|
ensure_port_free 3100
|
|
ensure_port_free 4000
|
|
ensure_port_free 8010
|
|
|
|
cd "$ROOT_DIR"
|
|
|
|
# The API runs directly on the host while Secretary API runs in Docker and is
|
|
# published on localhost:8010. The staging compose file overrides this with
|
|
# the service DNS name (secretary-api:8010).
|
|
export SUPPORT_API_BASE_URL="${SUPPORT_API_BASE_URL:-http://127.0.0.1:8010}"
|
|
|
|
echo "[local] starting local infrastructure (MySQL x2, smtp4dev)..."
|
|
docker compose -f "$COMPOSE_FILE" up -d mysql mysql-secretary smtp4dev
|
|
|
|
wait_for_mysql mysql userfeedback
|
|
wait_for_mysql mysql-secretary baron_support
|
|
|
|
if ! curl -fsS --max-time 5 http://127.0.0.1:5080/ >/dev/null 2>&1; then
|
|
echo "[local] warning: smtp4dev UI is not responding on http://127.0.0.1:5080" >&2
|
|
fi
|
|
|
|
cat <<'EOF'
|
|
|
|
[local] infrastructure is ready.
|
|
[local] starting development servers...
|
|
- Web: http://127.0.0.1:3100
|
|
- API Docs: http://127.0.0.1:4000/docs
|
|
- Secretary API Docs: http://127.0.0.1:8010/docs
|
|
- SMTP Test Inbox: http://127.0.0.1:5080
|
|
- ABC MySQL: 127.0.0.1:13306 / userfeedback
|
|
- Secretary MySQL: 127.0.0.1:13308 / baron_support
|
|
|
|
Press Ctrl-C to stop the development servers.
|
|
EOF
|
|
|
|
exec pnpm dev:local
|