setup setup

This commit is contained in:
Kevin Carter 2025-11-19 20:02:34 +00:00
parent f4b433fbc1
commit a07626e422
7 changed files with 505 additions and 11 deletions

30
.env
View File

@ -2,6 +2,20 @@
# CLASSROOM COPILOT - ENVIRONMENT CONFIGURATION # CLASSROOM COPILOT - ENVIRONMENT CONFIGURATION
############################################################# #############################################################
## =====================================================
## DOCKER INITIALIZATION CONFIGURATION
## =====================================================
# Set RUN_INIT=true to run initialization tasks on container startup
# Set to false or remove to skip initialization (for subsequent deployments)
RUN_INIT=true
# INIT_MODE options:
# - infra: Infrastructure only (Neo4j schema, calendar, Supabase buckets)
# - full: Full setup including demo school and users (infra → demo-school → demo-users → gais-data)
# - infra,demo-school,demo-users: Custom combination (comma-separated)
# - infra,gais-data: Infrastructure + GAIS data import
INIT_MODE=full
## ===================================================== ## =====================================================
## APP INFORMATION & METADATA ## APP INFORMATION & METADATA
## ===================================================== ## =====================================================
@ -35,7 +49,7 @@ ADMIN_WORKER_EMAIL=kcar@kevlarai.com
## ===================================================== ## =====================================================
## SUPABASE DATABASE CONFIGURATION ## SUPABASE DATABASE CONFIGURATION
## ===================================================== ## =====================================================
SUPABASE_URL=http://supa.classroomcopilot.ai SUPABASE_URL=https://supa.classroomcopilot.ai
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0 ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
@ -56,7 +70,7 @@ PORT_NEO4J_HTTPS=7473
## ===================================================== ## =====================================================
## OLLAMA AI SERVICE CONFIGURATION ## OLLAMA AI SERVICE CONFIGURATION
## ===================================================== ## =====================================================
HOST_OLLAMA=http://localhost HOST_OLLAMA=http://ollama.kevlarai.com
PORT_OLLAMA=11434 PORT_OLLAMA=11434
OLLAMA_MODEL=qwen2.5-coder:32b OLLAMA_MODEL=qwen2.5-coder:32b
@ -77,7 +91,7 @@ GOOGLE_CLIENT_SECRETS_FILE=Users/kcar/ClassroomCopilot/backend/app/secrets/googl
## DOCUMENT PROCESSING SERVICES ## DOCUMENT PROCESSING SERVICES
## ===================================================== ## =====================================================
# External Service Endpoints # External Service Endpoints
TIKA_URL=http://ubuntu-ct-tika:9998 TIKA_URL=https://tika.kevlarai.com
TIKA_TIMEOUT=300 TIKA_TIMEOUT=300
DOCLING_URL=http://ubuntu-server:5001 DOCLING_URL=http://ubuntu-server:5001
@ -184,10 +198,10 @@ DOCLING_VLM_DO_PICTURE_DESCRIPTION=true
## ===================================================== ## =====================================================
## APPLICATION DOMAINS & URLS ## APPLICATION DOMAINS & URLS
## ===================================================== ## =====================================================
VITE_APP_URL=http://localhost:3000 VITE_APP_URL=https://app.classroomcopilot.ai
APP_API_URL=http://localhost:{UVICORN_PORT} APP_API_URL=https://api.classroomcopilot.ai
APP_GRAPH_URL=http://localhost:7474 APP_GRAPH_URL=https://graph.classroomcopilot.ai
APP_BOLT_URL=bolt://localhost:7687 APP_BOLT_URL=bolt://bolt.classroomcopilot.ai
## ===================================================== ## =====================================================
## REDIS CONFIGURATION & ENVIRONMENT ISOLATION ## REDIS CONFIGURATION & ENVIRONMENT ISOLATION
@ -234,7 +248,7 @@ UPLOAD_STATUS_POLLING_INTERVAL=5 # Status polling interval (seconds)
## ===================================================== ## =====================================================
## CORS & SECURITY SETTINGS ## CORS & SECURITY SETTINGS
## ===================================================== ## =====================================================
CORS_SITE_URL=http://localhost:5173,http://localhost:8000,http://127.0.0.1:8000 CORS_SITE_URL=https://app.classroomcopilot.ai,https://api.classroomcopilot.ai,https://graph.classroomcopilot.ai
CORS_GRAPH_URL={APP_GRAPH_URL} CORS_GRAPH_URL={APP_GRAPH_URL}
CORS_API_URL={APP_API_URL} CORS_API_URL={APP_API_URL}

View File

@ -13,8 +13,9 @@ RUN pip install --no-cache-dir -r requirements.txt
# Copy application code # Copy application code
COPY . . COPY . .
# Make startup script executable # Make startup scripts executable
RUN chmod +x start.sh RUN chmod +x start.sh
RUN chmod +x docker-entrypoint.sh
# Set environment variables # Set environment variables
ENV PYTHONPATH=/app ENV PYTHONPATH=/app
@ -24,8 +25,8 @@ ENV UVICORN_WORKERS=4
# Expose port # Expose port
EXPOSE 8000 EXPOSE 8000
# Use the new startup script in production mode # Use the production entrypoint script (supports initialization)
CMD ["./start.sh", "prod"] ENTRYPOINT ["./docker-entrypoint.sh"]
# Alternative: Run initialization first, then production server # Alternative: Run initialization first, then production server
# CMD ["sh", "-c", "./start.sh init && ./start.sh prod"] # CMD ["sh", "-c", "./start.sh init && ./start.sh prod"]

128
FIRST_RUN_SETUP.md Normal file
View File

@ -0,0 +1,128 @@
# First Run Setup Guide
This guide shows how to enable full initialization including demo users and schools on first deployment.
## Quick Start: Full Setup with Demo Data
### Option 1: Using .env file (Recommended)
Add these lines to your `.env` file:
```bash
RUN_INIT=true
INIT_MODE=full
```
Then start:
```bash
docker compose up --build
```
This will run:
1. ✅ Infrastructure setup (Neo4j schema, calendar, Supabase buckets)
2. ✅ Demo school creation (KevlarAI)
3. ✅ Demo users creation
4. ✅ GAIS data import (Edubase, etc.)
### Option 2: Environment Variable Override
```bash
RUN_INIT=true INIT_MODE=full docker compose up --build
```
### Option 3: Custom Combination
If you want infrastructure + demo data but skip GAIS import:
```bash
# In .env or as environment variable
RUN_INIT=true
INIT_MODE=infra,demo-school,demo-users
```
## Available INIT_MODE Options
| Mode | What It Does |
|------|-------------|
| `infra` | Infrastructure only (Neo4j schema, calendar, Supabase buckets) |
| `demo-school` | Creates demo school (KevlarAI) |
| `demo-users` | Creates demo users |
| `gais-data` | Imports GAIS data (Edubase, etc.) |
| `full` | **All of the above** (infra → demo-school → demo-users → gais-data) |
| `infra,demo-school,demo-users` | Custom: Infrastructure + demo data (no GAIS) |
| `infra,gais-data` | Infrastructure + GAIS data (no demo data) |
## Examples
### Full setup with everything (recommended for first run)
```bash
RUN_INIT=true
INIT_MODE=full
```
### Infrastructure + demo data only (no GAIS import)
```bash
RUN_INIT=true
INIT_MODE=infra,demo-school,demo-users
```
### Infrastructure only (production, no demo data)
```bash
RUN_INIT=true
INIT_MODE=infra
```
### Infrastructure + GAIS data (production with public school data)
```bash
RUN_INIT=true
INIT_MODE=infra,gais-data
```
## After First Run
Once initialization is complete, you can disable automatic initialization for subsequent deployments:
```bash
# In .env file
RUN_INIT=false
```
Or simply remove/comment out the `RUN_INIT` line. The backend will start normally without running initialization tasks.
## Manual Re-initialization
If you need to re-run initialization later:
```bash
# Run specific mode
docker compose exec backend python3 main.py --mode infra
docker compose exec backend python3 main.py --mode demo-school
docker compose exec backend python3 main.py --mode demo-users
# Or use the helper script
docker compose exec backend ./init-production.sh full
```
## Troubleshooting
### Check if initialization ran
```bash
docker compose logs backend | grep -i "initialization\|infra\|demo"
```
### Re-run initialization
If initialization failed or you need to re-run it:
```bash
# Set in .env temporarily
RUN_INIT=true
INIT_MODE=full
# Rebuild and start
docker compose up --build
```
### Skip initialization on startup
```bash
RUN_INIT=false docker compose up --build
```

173
PRODUCTION_INIT.md Normal file
View File

@ -0,0 +1,173 @@
# Production Initialization Guide
This guide explains how to run initialization tasks (Supabase table setup, Neo4j schema, etc.) in production environments.
## Overview
In development, you use `./start.sh` to run initialization tasks. In production (Docker), you have several options:
## Option 1: Automatic Initialization on Startup (Recommended for First Deploy)
Set environment variables to run initialization when the container starts:
```bash
# In your .env file or docker-compose.yml
RUN_INIT=true
INIT_MODE=infra # or: infra,gais-data or full
```
Then start normally:
```bash
docker compose up --build
```
The backend container will:
1. Run the specified initialization tasks
2. Start the production server
**Note:** This runs init every time the container starts. For subsequent deployments, use Option 2 or 3.
## Option 2: Run Initialization as Separate Service (One-Time)
Use the dedicated init service:
```bash
# Run infrastructure setup
docker compose --profile init up init
# Or run multiple tasks
INIT_MODE=infra,gais-data docker compose --profile init up init
```
This runs once and exits. The backend service doesn't depend on it, so you can run it independently.
## Option 3: Manual Initialization (Recommended for Updates)
Run initialization tasks manually using the helper script:
```bash
# On the host machine
./init-production.sh infra
# Or using Docker Compose directly
docker compose run --rm backend python3 main.py --mode infra
```
### Available Initialization Modes
- **`infra`** - Essential setup:
- Neo4j schema and constraints
- Calendar structure
- Supabase storage buckets
- **`demo-school`** - Creates demo school (KevlarAI)
- Usually only needed for development/demo environments
- **`demo-users`** - Creates demo users
- Usually only needed for development/demo environments
- **`gais-data`** - Imports GAIS data (Edubase, etc.)
- Public school database imports
- May be needed in production
- **`full`** - Runs all initialization tasks in order
- infra → demo-school → demo-users → gais-data
## Option 4: Run Inside Running Container
If your container is already running:
```bash
# Execute init command inside running container
docker compose exec backend python3 main.py --mode infra
# Or use the helper script
docker compose exec backend ./init-production.sh infra
```
## Recommended Production Workflow
### First Deployment
1. **Initial Setup:**
```bash
# Set in .env or docker-compose.yml
RUN_INIT=true
INIT_MODE=infra
# Start services
docker compose up --build
```
2. **Import Data (if needed):**
```bash
docker compose exec backend python3 main.py --mode gais-data
```
### Subsequent Deployments
1. **Normal startup (no init):**
```bash
# Ensure RUN_INIT is false or not set
docker compose up --build
```
2. **Run init only when needed:**
```bash
# When schema changes or new buckets needed
docker compose exec backend python3 main.py --mode infra
```
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `RUN_INIT` | `false` | Set to `true` to run initialization on container startup |
| `INIT_MODE` | `infra` | Comma-separated list of modes: `infra`, `demo-school`, `demo-users`, `gais-data`, or `full` |
## Examples
### Run only infrastructure setup
```bash
INIT_MODE=infra docker compose up --build
```
### Run infrastructure and GAIS data import
```bash
INIT_MODE=infra,gais-data docker compose up --build
```
### Run full initialization (including demo data)
```bash
INIT_MODE=full docker compose up --build
```
### Run init separately before starting backend
```bash
# Run init
INIT_MODE=infra docker compose --profile init up init
# Start backend (init already done)
docker compose up backend
```
## Troubleshooting
### Init fails on startup
If initialization fails, the container will exit. Check logs:
```bash
docker compose logs backend
```
### Need to re-run init
Simply run the init command again - most tasks are idempotent:
```bash
docker compose exec backend python3 main.py --mode infra
```
### Skip init on startup
Ensure `RUN_INIT` is not set or is `false`:
```bash
RUN_INIT=false docker compose up --build
```

View File

@ -15,6 +15,28 @@ services:
timeout: 3s timeout: 3s
retries: 5 retries: 5
# Initialization service - runs setup tasks before backend starts
init:
build:
context: .
dockerfile: Dockerfile
container_name: api-init
env_file:
- .env
environment:
- REDIS_HOST=redis
- RUN_INIT=true
- INIT_MODE=${INIT_MODE:-infra} # Set via .env or override: INIT_MODE=infra,gais-data
- INIT_ONLY=true # Exit after init, don't start server
command: ["./docker-entrypoint.sh", "init-only"]
depends_on:
redis:
condition: service_healthy
networks:
- kevlarai-network
profiles:
- init # Only run when explicitly requested: docker compose --profile init up
backend: backend:
container_name: api container_name: api
build: build:
@ -24,6 +46,8 @@ services:
- .env - .env
environment: environment:
- REDIS_HOST=redis - REDIS_HOST=redis
- RUN_INIT=${RUN_INIT:-false} # Set to 'true' to run init on startup
- INIT_MODE=${INIT_MODE:-infra} # Which init tasks to run
ports: ports:
- 8000:8000 - 8000:8000
depends_on: depends_on:

108
docker-entrypoint.sh Executable file
View File

@ -0,0 +1,108 @@
#!/bin/bash
# Production entrypoint script for ClassroomCopilot API
# Supports running initialization tasks before starting the server
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if we should run initialization
RUN_INIT="${RUN_INIT:-false}"
INIT_MODE="${INIT_MODE:-infra}" # Default to 'infra', can be 'infra', 'full', or comma-separated list
# If RUN_INIT is true, run initialization tasks
if [ "$RUN_INIT" = "true" ]; then
print_status "Running initialization tasks (mode: $INIT_MODE)..."
# Split INIT_MODE by comma if it contains multiple modes
IFS=',' read -ra MODES <<< "$INIT_MODE"
for mode in "${MODES[@]}"; do
mode=$(echo "$mode" | xargs) # Trim whitespace
print_status "Running initialization mode: $mode"
case "$mode" in
"infra")
print_status "Setting up infrastructure (Neo4j schema, calendar, Supabase buckets)..."
python3 main.py --mode infra || {
print_error "Infrastructure setup failed!"
exit 1
}
print_success "Infrastructure setup completed"
;;
"demo-school")
print_status "Creating demo school..."
python3 main.py --mode demo-school || {
print_error "Demo school creation failed!"
exit 1
}
print_success "Demo school creation completed"
;;
"demo-users")
print_status "Creating demo users..."
python3 main.py --mode demo-users || {
print_error "Demo users creation failed!"
exit 1
}
print_success "Demo users creation completed"
;;
"gais-data")
print_status "Importing GAIS data..."
python3 main.py --mode gais-data || {
print_error "GAIS data import failed!"
exit 1
}
print_success "GAIS data import completed"
;;
"full")
print_status "Running full initialization..."
python3 main.py --mode infra || exit 1
python3 main.py --mode demo-school || exit 1
python3 main.py --mode demo-users || exit 1
python3 main.py --mode gais-data || exit 1
print_success "Full initialization completed"
;;
*)
print_warning "Unknown initialization mode: $mode (skipping)"
;;
esac
done
print_success "All initialization tasks completed"
# If this is the init service (not backend), exit after init
if [ "$1" = "init-only" ] || [ -n "$INIT_ONLY" ]; then
print_status "Initialization complete - exiting (init-only mode)"
exit 0
fi
fi
# Start the production server (unless init-only mode)
if [ "$1" != "init-only" ] && [ -z "$INIT_ONLY" ]; then
print_status "Starting production server..."
exec ./start.sh prod
else
print_status "Init-only mode - not starting server"
fi

46
init-production.sh Executable file
View File

@ -0,0 +1,46 @@
#!/bin/bash
# Helper script to run initialization tasks in production
# Usage: ./init-production.sh [mode]
# Modes: infra, demo-school, demo-users, gais-data, full
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
MODE=${1:-infra}
print_status "Running production initialization: $MODE"
# Check if running in Docker
if [ -f /.dockerenv ] || [ -n "$DOCKER_CONTAINER" ]; then
print_status "Running inside Docker container"
python3 main.py --mode "$MODE"
else
print_status "Running on host - using Docker Compose"
# Run init using docker compose
docker compose run --rm \
-e RUN_INIT=true \
-e INIT_MODE="$MODE" \
backend python3 main.py --mode "$MODE"
fi
print_success "Initialization completed: $MODE"