104 lines
4.5 KiB
Bash
Executable File
104 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# -------------------------------------------------------------
|
|
# Staging Deploy & Orchestration Helper for NexusReader
|
|
# -------------------------------------------------------------
|
|
set -e
|
|
|
|
ENV_FILE=".env.stage"
|
|
TEMPLATE_FILE=".env.stage.template"
|
|
COMPOSE_FILE="docker-compose.stage.yml"
|
|
|
|
echo "🏁 Starting staging environment orchestration..."
|
|
|
|
# 1. Create .env.stage if it doesn't exist
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
if [ -f "$TEMPLATE_FILE" ]; then
|
|
echo "📄 Creating $ENV_FILE from $TEMPLATE_FILE..."
|
|
cp "$TEMPLATE_FILE" "$ENV_FILE"
|
|
else
|
|
echo "❌ Error: Template file $TEMPLATE_FILE not found."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# 2. Check and generate secure random passwords for placeholders
|
|
if grep -q "CHANGE_ME_TO_STRONG_PASSWORD" "$ENV_FILE"; then
|
|
echo "🔐 Generating secure random passwords in $ENV_FILE..."
|
|
PG_PASS=$(openssl rand -hex 16)
|
|
NEO_PASS=$(openssl rand -hex 16)
|
|
# Use standard sed compatible with Linux
|
|
sed -i "s/POSTGRES_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD/POSTGRES_PASSWORD=$PG_PASS/g" "$ENV_FILE"
|
|
sed -i "s/NEO4J_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD/NEO4J_PASSWORD=$NEO_PASS/g" "$ENV_FILE"
|
|
fi
|
|
|
|
if grep -q "CHANGE_ME_TO_SECURE_ADMIN_PASSWORD" "$ENV_FILE"; then
|
|
echo "🔐 Generating secure admin seed password in $ENV_FILE..."
|
|
ADMIN_PASS=$(openssl rand -hex 16)
|
|
sed -i "s/NEXUS_ADMIN_PASSWORD=CHANGE_ME_TO_SECURE_ADMIN_PASSWORD/NEXUS_ADMIN_PASSWORD=$ADMIN_PASS/g" "$ENV_FILE"
|
|
fi
|
|
|
|
# Load staging variables for local execution context (needed for ports/migrations)
|
|
# Clean up carriage returns just in case
|
|
POSTGRES_USER=$(grep "^POSTGRES_USER=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
POSTGRES_PASSWORD=$(grep "^POSTGRES_PASSWORD=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
POSTGRES_DB=$(grep "^POSTGRES_DB=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
POSTGRES_PORT=$(grep "^POSTGRES_PORT=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
WEB_PORT=$(grep "^WEB_PORT=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
QDRANT_HTTP_PORT=$(grep "^QDRANT_HTTP_PORT=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
NEO4J_HTTP_PORT=$(grep "^NEO4J_HTTP_PORT=" "$ENV_FILE" | cut -d'=' -f2- | tr -d '\r')
|
|
|
|
# Fallbacks in case env parsing is empty
|
|
POSTGRES_PORT=${POSTGRES_PORT:-5438}
|
|
WEB_PORT=${WEB_PORT:-5080}
|
|
|
|
# 3. Stop any conflicting Docker Compose environments
|
|
echo "🧹 Stopping existing containers..."
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down --remove-orphans || true
|
|
docker compose down --remove-orphans 2>/dev/null || true
|
|
|
|
# 4. Build and start containers
|
|
echo "🚀 Building and starting staging containers..."
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d --build
|
|
|
|
# 5. Wait for Database to be healthy
|
|
echo "⏳ Waiting for database (nexus-db-stage) to become healthy..."
|
|
MAX_ATTEMPTS=30
|
|
attempt=0
|
|
until [ "$(docker inspect --format='{{json .State.Health.Status}}' nexus-db-stage 2>/dev/null)" == "\"healthy\"" ]; do
|
|
sleep 2
|
|
attempt=$((attempt + 1))
|
|
if [ $attempt -ge $MAX_ATTEMPTS ]; then
|
|
echo "❌ Timeout: Database container never became healthy."
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs db
|
|
exit 1
|
|
fi
|
|
done
|
|
echo "✅ Database is healthy!"
|
|
|
|
# 6. Apply Entity Framework migrations
|
|
echo "🔄 Applying EF Core migrations to staging database on port $POSTGRES_PORT..."
|
|
export ConnectionStrings__PostgresConnection="Host=127.0.0.1;Port=$POSTGRES_PORT;Database=$POSTGRES_DB;Username=$POSTGRES_USER;Password=$POSTGRES_PASSWORD"
|
|
dotnet ef database update --project src/NexusReader.Data --startup-project src/NexusReader.Web --no-build
|
|
|
|
# 7. Wait for Web Application to respond
|
|
echo "⏳ Waiting for Web Application to start on http://localhost:$WEB_PORT..."
|
|
MAX_WEB_ATTEMPTS=45
|
|
web_attempt=0
|
|
until curl -s -f "http://localhost:$WEB_PORT" >/dev/null; do
|
|
sleep 2
|
|
web_attempt=$((web_attempt + 1))
|
|
if [ $web_attempt -ge $MAX_WEB_ATTEMPTS ]; then
|
|
echo "⚠️ Warning: Web app is not responding yet on http://localhost:$WEB_PORT, but let's check logs..."
|
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs web
|
|
break
|
|
fi
|
|
done
|
|
|
|
echo "🎉 Staging environment is ready!"
|
|
echo "--------------------------------------------------------"
|
|
echo "🌐 Web Application: http://localhost:$WEB_PORT"
|
|
echo "🗄️ PostgreSQL Port: $POSTGRES_PORT"
|
|
echo "🔎 Neo4j Console: http://localhost:$NEO4J_HTTP_PORT"
|
|
echo "📊 Qdrant Service: http://localhost:$QDRANT_HTTP_PORT"
|
|
echo "--------------------------------------------------------"
|