From fc1d82ad81f9f8afd95b36f83f11d10ecc29d426 Mon Sep 17 00:00:00 2001 From: "Kar@k5" Date: Wed, 25 Feb 2026 12:40:10 +0530 Subject: [PATCH] deploy --- Dockerfile | 33 +++++++ README-DEPLOYMENT.md | 210 ++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 45 +++++++++ scripts/backup.sh | 95 +++++++++++++++++++ scripts/cleanup.sh | 52 +++++++++++ scripts/deploy.sh | 130 ++++++++++++++++++++++++++ scripts/init-mongo.js | 18 ++++ 7 files changed, 583 insertions(+) create mode 100644 Dockerfile create mode 100644 README-DEPLOYMENT.md create mode 100644 docker-compose.yml create mode 100755 scripts/backup.sh create mode 100755 scripts/cleanup.sh create mode 100755 scripts/deploy.sh create mode 100644 scripts/init-mongo.js diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1285a95 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +# Use Node.js 18 LTS +FROM node:18-alpine + +# Install MongoDB CLI tools for import operations +RUN apk add --no-cache mongodb-tools + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm ci --only=production + +# Copy application code +COPY . . + +# Create uploads directory for images +RUN mkdir -p uploads + +# Build the application +RUN npm run build + +# Expose port +EXPOSE 3000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3000/api/health || exit 1 + +# Start the application +CMD ["npm", "start"] diff --git a/README-DEPLOYMENT.md b/README-DEPLOYMENT.md new file mode 100644 index 0000000..fa22f38 --- /dev/null +++ b/README-DEPLOYMENT.md @@ -0,0 +1,210 @@ +# Observation App - Docker Deployment Guide + +This guide provides a complete Docker-based deployment solution for the Observation App with automated database import and image handling. + +## ๐Ÿ—๏ธ Architecture + +- **observation_app**: Next.js application container +- **observation_db**: MongoDB database container +- **observation_net**: Private network for container communication + +## ๐Ÿ“‹ Prerequisites + +- Docker and Docker Compose installed +- `.env` file configured +- `public/` directory with required files +- `public/db/` directory with JSON database files (optional) + +## ๐Ÿš€ Quick Deployment + +### 1. Prepare Environment + +Ensure you have: +```bash +# .env file with configuration +MONGODB_URI=mongodb://localhost/beanstalk +# ... other environment variables + +# public directory structure +public/ +โ”œโ”€โ”€ observations/ # Image files +โ”œโ”€โ”€ db/ # JSON database files +โ”‚ โ”œโ”€โ”€ indicators.json +โ”‚ โ”œโ”€โ”€ learning_areas.json +โ”‚ โ””โ”€โ”€ observations.json +โ””โ”€โ”€ ... # Other static files +``` + +### 2. Deploy + +```bash +# Make deployment script executable +chmod +x scripts/deploy.sh + +# Run deployment +./scripts/deploy.sh +``` + +The deployment script will: +- โœ… Build and start containers +- โœ… Wait for database readiness +- โœ… Import JSON files from `public/db/` automatically +- โœ… Copy images to container +- โœ… Perform health checks + +### 3. Access Services + +- **Application**: http://localhost:3000 +- **Database**: `mongodb://admin:password123@localhost:27017` + +## ๐Ÿ› ๏ธ Management Commands + +### Container Management +```bash +# View logs +docker-compose logs -f + +# Stop services +docker-compose down + +# Restart services +docker-compose restart + +# Access application container +docker-compose exec observation_app sh + +# Access database +docker-compose exec observation_db mongosh +``` + +### Database Operations +```bash +# Import new JSON file +curl -X POST -F "file=@data.json" http://localhost:3000/api/import-json + +# Export database +docker-compose exec observation_db mongodump --uri="mongodb://admin:password123@localhost:27017/beanstalk?authSource=admin" --archive > backup.archive +``` + +## ๐Ÿ“ Data Management + +### Images +- Place images in `public/observations/` +- Automatically copied to container during deployment +- Accessible via `/api/proxy-image` endpoint + +### Database Files +- Place JSON files in `public/db/` +- Filename becomes collection name (e.g., `users.json` โ†’ `users` collection) +- Automatically imported during deployment +- Existing collections are dropped before import + +## ๐Ÿ”ง Configuration + +### Environment Variables +```bash +# Database Connection +MONGODB_URI=mongodb://admin:password123@observation_db:27017/beanstalk?authSource=admin + +# Application +NODE_ENV=production +``` + +### Docker Compose Settings +- **MongoDB Version**: 6.0 +- **Node.js Version**: 18 Alpine +- **Ports**: App (3000), Database (27017) +- **Volumes**: Persistent MongoDB data + +## ๐Ÿ”„ Backup & Restore + +### Create Backup +```bash +chmod +x scripts/backup.sh +./scripts/backup.sh +``` + +Creates backup in `backups/YYYYMMDD_HHMMSS/` with: +- MongoDB database archive +- Image files +- Configuration files +- Automated restore script + +### Restore from Backup +```bash +cd backups/YYYYMMDD_HHMMSS/ +./restore.sh +``` + +## ๐Ÿงน Cleanup + +### Complete Cleanup +```bash +chmod +x scripts/cleanup.sh +./scripts/cleanup.sh +``` + +Removes: +- All containers +- Application images +- Unused networks +- Optionally: Database volumes (with confirmation) + +## ๐Ÿ” Troubleshooting + +### Database Connection Issues +```bash +# Check database status +docker-compose exec observation_db mongosh --eval "db.adminCommand('ping')" + +# View database logs +docker-compose logs observation_db +``` + +### Application Issues +```bash +# Check application health +curl http://localhost:3000/api/health + +# View application logs +docker-compose logs observation_app +``` + +### Rebuild Containers +```bash +# Force rebuild without cache +docker-compose build --no-cache +docker-compose up -d +``` + +## ๐Ÿ“Š Monitoring + +### Health Checks +- Application: `/api/health` +- Database: MongoDB ping command +- Container status: `docker-compose ps` + +### Logs +```bash +# All services +docker-compose logs -f + +# Specific service +docker-compose logs -f observation_app +docker-compose logs -f observation_db +``` + +## ๐Ÿ”’ Security Notes + +- Default credentials are for development only +- Change MongoDB passwords in production +- Use environment variables for sensitive data +- Consider using Docker secrets for production + +## ๐Ÿš€ Production Considerations + +1. **Security**: Update default passwords +2. **SSL**: Add HTTPS termination +3. **Backup**: Schedule regular backups +4. **Monitoring**: Add health monitoring +5. **Scaling**: Consider load balancer for multiple app instances diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7925abf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +version: '3.8' + +services: + observation_db: + image: mongo:6.0 + container_name: observation_db + restart: unless-stopped + environment: + MONGO_INITDB_ROOT_USERNAME: admin + MONGO_INITDB_ROOT_PASSWORD: password123 + MONGO_INITDB_DATABASE: beanstalk + ports: + - "27017:27017" + volumes: + - mongo_data:/data/db + - ./scripts/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro + networks: + - observation_net + + observation_app: + build: + context: . + dockerfile: Dockerfile + container_name: observation_app + restart: unless-stopped + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - MONGODB_URI=mongodb://admin:password123@observation_db:27017/beanstalk?authSource=admin + volumes: + - ./public:/app/public:ro + - ./uploads:/app/uploads + depends_on: + - observation_db + networks: + - observation_net + +volumes: + mongo_data: + driver: local + +networks: + observation_net: + driver: bridge diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100755 index 0000000..2d63fc7 --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Backup script for Observation App +# This script creates backups of database and images + +set -e + +echo "๐Ÿ’พ Creating backup of Observation App data..." + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +# Create backup directory with timestamp +BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)" +mkdir -p "$BACKUP_DIR" + +print_status "Backup directory: $BACKUP_DIR" + +# Backup database +print_status "Backing up MongoDB database..." +docker-compose exec -T observation_db mongodump --uri="mongodb://admin:password123@localhost:27017/beanstalk?authSource=admin" --archive > "$BACKUP_DIR/mongodb_backup.archive" + +# Backup images from public/observations +if [ -d "public/observations" ]; then + print_status "Backing up images..." + cp -r public/observations "$BACKUP_DIR/" + print_success "Images backed up" +else + print_warning "No images directory found" +fi + +# Backup configuration files +print_status "Backing up configuration..." +cp .env "$BACKUP_DIR/" 2>/dev/null || print_warning "No .env file found" +cp docker-compose.yml "$BACKUP_DIR/" 2>/dev/null || true + +# Create restore script +cat > "$BACKUP_DIR/restore.sh" << 'EOF' +#!/bin/bash + +# Restore script for Observation App backup +set -e + +echo "๐Ÿ”„ Restoring Observation App from backup..." + +# Colors for output +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +# Check if containers are running +if ! docker-compose ps | grep -q "Up"; then + echo "Please start the application first: docker-compose up -d" + exit 1 +fi + +# Restore database +print_status "Restoring database..." +docker-compose exec -T observation_db mongorestore --uri="mongodb://admin:password123@localhost:27017/beanstalk?authSource=admin" --archive < mongodb_backup.archive + +# Restore images +if [ -d "observations" ]; then + print_status "Restoring images..." + cp -r observations/* public/observations/ + print_success "Images restored" +fi + +print_success "Restore completed!" +EOF + +chmod +x "$BACKUP_DIR/restore.sh" + +print_success "Backup completed successfully!" +echo "Backup location: $BACKUP_DIR" +echo "To restore: cd $BACKUP_DIR && ./restore.sh" diff --git a/scripts/cleanup.sh b/scripts/cleanup.sh new file mode 100755 index 0000000..0c05145 --- /dev/null +++ b/scripts/cleanup.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Cleanup script for Observation App +# This script removes all containers, images, and volumes + +set -e + +echo "๐Ÿงน Cleaning up Observation App deployment..." + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +# Stop and remove containers +print_status "Stopping and removing containers..." +docker-compose down -v 2>/dev/null || true + +# Remove images +print_status "Removing application images..." +docker rmi observation_import-observation_app 2>/dev/null || true + +# Remove unused networks +print_status "Removing unused networks..." +docker network prune -f 2>/dev/null || true + +# Remove unused volumes (prompt user) +read -p "Remove all unused Docker volumes? This will delete database data! (y/N): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + print_status "Removing unused volumes..." + docker volume prune -f + print_warning "Database data has been removed!" +else + print_status "Keeping Docker volumes (database data preserved)" +fi + +print_success "Cleanup completed!" diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 0000000..e07839f --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +# Deployment script for Observation App +# This script handles the complete deployment process + +set -e # Exit on any error + +echo "๐Ÿš€ Starting Observation App Deployment..." + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +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 .env file exists +if [ ! -f .env ]; then + print_error ".env file not found!" + echo "Please create .env file before deploying." + exit 1 +fi + +# Check if public directory exists +if [ ! -d public ]; then + print_error "public directory not found!" + echo "Please ensure public directory exists with required files." + exit 1 +fi + +# Check if public/db directory exists +if [ ! -d public/db ]; then + print_warning "public/db directory not found. Creating empty directory..." + mkdir -p public/db +fi + +# Stop existing containers if running +print_status "Stopping existing containers..." +docker-compose down 2>/dev/null || true + +# Build and start containers +print_status "Building and starting containers..." +docker-compose up --build -d + +# Wait for database to be ready +print_status "Waiting for database to be ready..." +sleep 10 + +# Check if database is accessible +print_status "Checking database connection..." +docker-compose exec observation_db mongosh --eval "db.adminCommand('ping')" > /dev/null 2>&1 +if [ $? -eq 0 ]; then + print_success "Database is ready!" +else + print_error "Database connection failed!" + exit 1 +fi + +# Import database if files exist in public/db +if [ "$(ls -A public/db/*.json 2>/dev/null)" ]; then + print_status "Found database files in public/db. Starting import..." + + # Import each JSON file + for file in public/db/*.json; do + filename=$(basename "$file" .json) + print_status "Importing $filename..." + + # Copy file to container and import + docker cp "$file" observation_app:/tmp/"$(basename "$file")" + docker-compose exec observation_app curl -X POST -F "file=@/tmp/$(basename "$file")" http://localhost:3000/api/import-json + + # Clean up + docker-compose exec observation_app rm "/tmp/$(basename "$file")" + + print_success "Imported $filename" + done +else + print_warning "No database files found in public/db" +fi + +# Check application health +print_status "Checking application health..." +sleep 5 +if curl -f http://localhost:3000/api/health > /dev/null 2>&1; then + print_success "Application is healthy!" +else + print_warning "Application health check failed, but deployment may still be successful" +fi + +# Display deployment information +echo "" +print_success "๐ŸŽ‰ Deployment completed successfully!" +echo "" +echo "๐Ÿ“‹ Service Information:" +echo " โ€ข Application URL: http://localhost:3000" +echo " โ€ข Database URL: mongodb://admin:password123@localhost:27017" +echo " โ€ข Database Name: beanstalk" +echo "" +echo "๐Ÿ”ง Useful Commands:" +echo " โ€ข View logs: docker-compose logs -f" +echo " โ€ข Stop services: docker-compose down" +echo " โ€ข Restart services: docker-compose restart" +echo " โ€ข Access database: docker-compose exec observation_db mongosh" +echo "" +echo "๐Ÿ“ Data Locations:" +echo " โ€ข Images: ./public/observations/ (copied to container)" +echo " โ€ข Database files: ./public/db/ (imported to MongoDB)" +echo " โ€ข MongoDB data: Docker volume 'mongo_data'" +echo "" + +# Show container status +print_status "Container Status:" +docker-compose ps diff --git a/scripts/init-mongo.js b/scripts/init-mongo.js new file mode 100644 index 0000000..5817f5f --- /dev/null +++ b/scripts/init-mongo.js @@ -0,0 +1,18 @@ +// MongoDB initialization script +// This script runs when the container starts for the first time + +db = db.getSiblingDB('beanstalk'); + +// Create application user +db.createUser({ + user: 'app_user', + pwd: 'app_password', + roles: [ + { + role: 'readWrite', + db: 'beanstalk' + } + ] +}); + +print('Database initialization completed');