diff --git a/.cursor/rules/dockercompose.mdc b/.cursor/rules/dockercompose.mdc new file mode 100644 index 0000000..ebd9b31 --- /dev/null +++ b/.cursor/rules/dockercompose.mdc @@ -0,0 +1,5 @@ +--- +description: don't forget that you don't normally need to do `npm run dev` to run the dashboard web-app. since it is supposed to be always running with the help of docker compose` so if you need to access the dashboard you can simply curl or wget localhost:8080 +globs: +alwaysApply: true +--- diff --git a/README.md b/README.md index df1c0e0..74fc7e0 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ A unified monorepo combining the camera API service and the web dashboard for US - `camera-management-api/` - Python API service for camera management (USDA-Vision-Cameras) - `management-dashboard-web-app/` - React web dashboard for experiment management (pecan_experiments) -## Quick Start (Docker Compose) +## Quick Start + +### Production Mode (Docker Compose) 1) Copy env template and set values (for web/Supabase): @@ -28,6 +30,48 @@ docker compose up --build To stop: `docker compose down` +### Development Mode (Recommended for Development) + +For development with live logging, debugging, and hot reloading: + +1) Copy env template and set values (for web/Supabase): + +```bash +cp .env.example .env +# set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in .env +``` + +2) Start the development environment: + +```bash +./dev-start.sh +``` + +This will: +- Start containers with debug logging enabled +- Enable hot reloading for both API and web services +- Show all logs in real-time +- Keep containers running for debugging + +**Development URLs:** +- Web: (with hot reloading) +- API: (with debug logging) + +**Development Commands:** +- `./dev-start.sh` - Start development environment +- `./dev-stop.sh` - Stop development environment +- `./dev-logs.sh` - View logs (use `-f` to follow, `-t N` for last N lines) +- `./dev-logs.sh -f api` - Follow API logs only +- `./dev-logs.sh -f web` - Follow web logs only +- `./dev-shell.sh` - Open shell in API container +- `./dev-shell.sh web` - Open shell in web container + +**Debug Features:** +- API runs with `--debug --verbose` flags for maximum logging +- Web runs with Vite dev server for hot reloading +- All containers have `stdin_open: true` and `tty: true` for debugging +- Environment variables set for development mode + ## Services ### API Service (Port 8000) diff --git a/dev-logs.sh b/dev-logs.sh new file mode 100755 index 0000000..f4a6fd2 --- /dev/null +++ b/dev-logs.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# USDA Vision Development Logs Script +# This script shows logs from the development environment + +set -e + +echo "📋 USDA Vision Development Logs" +echo "===============================" + +# Check if docker-compose.dev.yml exists +if [ ! -f "docker-compose.dev.yml" ]; then + echo "❌ Error: docker-compose.dev.yml not found!" + echo "Please make sure you're in the project root directory." + exit 1 +fi + +# Function to show help +show_help() { + echo "Usage: $0 [OPTIONS] [SERVICE]" + echo "" + echo "Options:" + echo " -f, --follow Follow log output (like tail -f)" + echo " -t, --tail N Show last N lines (default: 100)" + echo " -h, --help Show this help message" + echo "" + echo "Services:" + echo " api Show API service logs only" + echo " web Show web service logs only" + echo " (no service) Show logs from all services" + echo "" + echo "Examples:" + echo " $0 # Show last 100 lines from all services" + echo " $0 -f # Follow all logs in real-time" + echo " $0 -f api # Follow API logs only" + echo " $0 -t 50 web # Show last 50 lines from web service" +} + +# Default values +FOLLOW=false +TAIL_LINES=100 +SERVICE="" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + -f|--follow) + FOLLOW=true + shift + ;; + -t|--tail) + TAIL_LINES="$2" + shift 2 + ;; + -h|--help) + show_help + exit 0 + ;; + api|web) + SERVICE="$1" + shift + ;; + *) + echo "❌ Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +# Build docker compose command +COMPOSE_CMD="docker compose -f docker-compose.dev.yml logs" + +if [ "$FOLLOW" = true ]; then + COMPOSE_CMD="$COMPOSE_CMD -f" +fi + +if [ "$TAIL_LINES" != "100" ]; then + COMPOSE_CMD="$COMPOSE_CMD --tail=$TAIL_LINES" +fi + +if [ -n "$SERVICE" ]; then + COMPOSE_CMD="$COMPOSE_CMD $SERVICE" +fi + +echo "Running: $COMPOSE_CMD" +echo "" + +# Execute the command +eval $COMPOSE_CMD diff --git a/dev-shell.sh b/dev-shell.sh new file mode 100755 index 0000000..7d19ba5 --- /dev/null +++ b/dev-shell.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# USDA Vision Development Shell Script +# This script opens a shell in the running development container + +set -e + +echo "🐚 USDA Vision Development Shell" +echo "================================" + +# Check if docker-compose.dev.yml exists +if [ ! -f "docker-compose.dev.yml" ]; then + echo "❌ Error: docker-compose.dev.yml not found!" + echo "Please make sure you're in the project root directory." + exit 1 +fi + +# Function to show help +show_help() { + echo "Usage: $0 [SERVICE]" + echo "" + echo "Services:" + echo " api Open shell in API container (default)" + echo " web Open shell in web container" + echo "" + echo "Examples:" + echo " $0 # Open shell in API container" + echo " $0 api # Open shell in API container" + echo " $0 web # Open shell in web container" +} + +# Default service +SERVICE="api" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_help + exit 0 + ;; + api|web) + SERVICE="$1" + shift + ;; + *) + echo "❌ Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +echo "🔍 Checking if $SERVICE container is running..." + +# Check if the service is running +if ! docker compose -f docker-compose.dev.yml ps $SERVICE | grep -q "Up"; then + echo "❌ Error: $SERVICE container is not running!" + echo "Please start the development environment first with: ./dev-start.sh" + exit 1 +fi + +echo "🚀 Opening shell in $SERVICE container..." +echo "💡 Tip: Use 'exit' to return to your host shell" +echo "" + +# Execute shell in the container +docker compose -f docker-compose.dev.yml exec $SERVICE /bin/bash diff --git a/dev-start.sh b/dev-start.sh new file mode 100755 index 0000000..9960cd5 --- /dev/null +++ b/dev-start.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# USDA Vision Development Startup Script +# This script starts the development environment with proper logging and debugging + +set -e + +echo "🚀 Starting USDA Vision Development Environment" +echo "==============================================" + +# Check if docker-compose.dev.yml exists +if [ ! -f "docker-compose.dev.yml" ]; then + echo "❌ Error: docker-compose.dev.yml not found!" + echo "Please make sure you're in the project root directory." + exit 1 +fi + +# Check if .env file exists for web app +if [ ! -f "management-dashboard-web-app/.env" ]; then + echo "⚠️ Warning: management-dashboard-web-app/.env not found!" + echo "You may need to create it from .env.example" + echo "Continuing anyway..." +fi + +echo "📦 Building and starting development containers..." +echo "" + +# Start the development environment +docker compose -f docker-compose.dev.yml up --build + +echo "" +echo "🛑 Development environment stopped" diff --git a/dev-stop.sh b/dev-stop.sh new file mode 100755 index 0000000..cf78b7b --- /dev/null +++ b/dev-stop.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# USDA Vision Development Stop Script +# This script stops the development environment + +set -e + +echo "🛑 Stopping USDA Vision Development Environment" +echo "==============================================" + +# Check if docker-compose.dev.yml exists +if [ ! -f "docker-compose.dev.yml" ]; then + echo "❌ Error: docker-compose.dev.yml not found!" + echo "Please make sure you're in the project root directory." + exit 1 +fi + +echo "🔄 Stopping development containers..." + +# Stop the development environment +docker compose -f docker-compose.dev.yml down + +echo "" +echo "✅ Development environment stopped successfully" +echo "" +echo "💡 Tip: Use './dev-start.sh' to start the development environment again" +echo "💡 Tip: Use './dev-logs.sh' to view logs from the last run" diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..9c48fbe --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,106 @@ +services: + api: + build: + context: ./camera-management-api + dockerfile: Dockerfile + working_dir: /app + volumes: + - ./camera-management-api:/app + - /storage:/storage + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + environment: + - PYTHONUNBUFFERED=1 + - LD_LIBRARY_PATH=/usr/local/lib:/lib:/usr/lib + - PYTHONPATH=/app:/app/camera_sdk + - TZ=America/New_York + # Development-specific environment variables + - FLASK_ENV=development + - FLASK_DEBUG=1 + - PYTHONDONTWRITEBYTECODE=1 + command: > + sh -lc " + apt-get update && apt-get install -y libusb-1.0-0-dev; + + # Install camera SDK if not already installed + if [ ! -f /lib/libMVSDK.so ] && [ -f 'camera_sdk/linuxSDK_V2.1.0.49(250108)/install.sh' ]; then + echo 'Installing camera SDK...'; + cd 'camera_sdk/linuxSDK_V2.1.0.49(250108)'; + chmod +x install.sh; + ./install.sh; + cd /app; + echo 'Camera SDK installed successfully'; + else + echo 'Camera SDK already installed or install script not found'; + fi; + + # Install Python dependencies + if [ -f requirements.txt ]; then + pip install --no-cache-dir -r requirements.txt; + else + pip install --no-cache-dir -e .; + fi; + + # Start the application in development mode with verbose logging + echo 'Starting API in development mode...'; + python main.py --config config.compose.json --debug --verbose + " + network_mode: host + # Keep container running for debugging + stdin_open: true + tty: true + # Add labels for easier identification + labels: + - "com.usda-vision.service=api" + - "com.usda-vision.environment=development" + + web: + image: node:20-alpine + working_dir: /app + env_file: + - ./management-dashboard-web-app/.env + volumes: + - ./management-dashboard-web-app:/app + environment: + - CHOKIDAR_USEPOLLING=true + - TZ=America/New_York + # Development-specific environment variables + - NODE_ENV=development + - VITE_DEV_SERVER_HOST=0.0.0.0 + - VITE_DEV_SERVER_PORT=8080 + command: > + sh -lc " + echo 'Installing dependencies...'; + npm ci; + echo 'Starting web development server...'; + npm run dev -- --host 0.0.0.0 --port 8080 --verbose + " + # Ensure the web container can resolve host.docker.internal on Linux + extra_hosts: + - "host.docker.internal:host-gateway" + ports: + - "8080:8080" + # Keep container running for debugging + stdin_open: true + tty: true + # Add labels for easier identification + labels: + - "com.usda-vision.service=web" + - "com.usda-vision.environment=development" + # Optional: Add a development database if needed + # db: + # image: postgres:15-alpine + # environment: + # POSTGRES_DB: usda_vision_dev + # POSTGRES_USER: dev + # POSTGRES_PASSWORD: dev + # volumes: + # - postgres_dev_data:/var/lib/postgresql/data + # ports: + # - "5432:5432" + # labels: + # - "com.usda-vision.service=database" + # - "com.usda-vision.environment=development" + + # volumes: + # postgres_dev_data: