diff --git a/docker/README.md b/docker/README.md index 2911e94..cbd18f1 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,367 +1,110 @@ -# 🚀 Ideas Generator 2025 - Docker Deployment - -Complete production-ready Docker deployment for the Ideas Generator 2025 application with Azure AD SSO and hybrid authentication. - -## 📋 Overview - -This Docker setup provides a complete, production-ready deployment including: - -- **Frontend**: Vue.js 3 + Vite (served via Nginx) -- **Backend**: Node.js + Express API server -- **Database**: PostgreSQL 15 with persistent storage -- **Proxy**: Nginx reverse proxy with SSL support -- **Authentication**: Hybrid Azure AD SSO + Password authentication -- **Security**: Production-grade security headers and rate limiting - -## 🚀 Quick Start - -### Prerequisites - -- Docker 20.x or higher -- Docker Compose 2.x or higher -- OpenAI API key -- Azure AD tenant access (for SSO) - -### One-Command Deployment - -```bash -cd docker -./setup.sh -``` - -The interactive setup script will guide you through: -- Domain and port configuration -- Database setup with secure credentials -- Azure AD integration -- OpenAI API configuration -- SSL/TLS setup -- Security configuration - -## 📁 Architecture - -``` -docker/ -├── docker-compose.yml # Main orchestration file -├── Dockerfile.backend # Node.js backend container -├── Dockerfile.frontend # Vue.js + Nginx frontend container -├── setup.sh # Interactive deployment wizard -├── nginx/ -│ └── nginx.conf.template # Nginx configuration with variables -├── postgres/ -│ └── init.sql # Database initialization -└── scripts/ - ├── deploy.sh # Deployment management commands - └── frontend-entrypoint.sh # Frontend container initialization -``` - -## 🔧 Services - -### Frontend Service (`frontend`) -- **Base**: nginx:alpine -- **Port**: 80 (HTTP), 443 (HTTPS) -- **Features**: - - Production Vue.js build - - Gzip compression - - Security headers - - Rate limiting - - Health checks - -### Backend Service (`backend`) -- **Base**: node:18-alpine -- **Port**: 3000 (internal) -- **Features**: - - Express.js API server - - PostgreSQL connection - - Azure AD token validation - - OpenAI API integration - - Health monitoring - -### Database Service (`database`) -- **Base**: postgres:15-alpine -- **Port**: 5432 (internal) -- **Features**: - - Persistent data storage - - Automatic initialization - - Health checks - - Backup support - -## ⚙️ Configuration - -### Environment Variables - -The setup script generates a `.env` file with all necessary configuration: - -```env -# Basic Configuration -DOMAIN_NAME=your-domain.com -HTTP_PORT=80 -HTTPS_PORT=443 - -# Database -DATABASE_NAME=ideas_gen_prod -DATABASE_USER=ideas_admin -DATABASE_PASSWORD=generated-secure-password - -# Security -JWT_SECRET=generated-jwt-secret - -# Azure AD -AZURE_TENANT_ID=your-tenant-id -AZURE_CLIENT_ID=your-client-id - -# OpenAI -OPENAI_API_KEY=your-openai-key - -# URLs -FRONTEND_URL=https://your-domain.com -BACKEND_URL=https://your-domain.com/api -CORS_ORIGIN=https://your-domain.com -``` - -### Manual Configuration - -If you prefer manual setup, copy the example: - -```bash -cp .env.example .env -# Edit .env with your values -``` - -## 🚀 Deployment Commands - -### Using the Management Script - -```bash -# Start all services -./scripts/deploy.sh start - -# Build and deploy with latest changes -./scripts/deploy.sh build - -# View service status -./scripts/deploy.sh status - -# View logs -./scripts/deploy.sh logs - -# Stop all services -./scripts/deploy.sh stop -``` - -### Using Docker Compose Directly - -```bash -# Start in background -docker-compose up -d - -# Build and start -docker-compose up -d --build - -# View logs -docker-compose logs -f - -# Stop services -docker-compose down -``` - -## 🔒 Security Features - -### Network Security -- Custom isolated Docker network -- Internal service communication -- No exposed database ports - -### Web Security -- HTTPS/SSL support -- Security headers (HSTS, CSP, etc.) -- Rate limiting on API endpoints -- CORS protection - -### Authentication Security -- Azure AD token validation -- JWT secret generation -- Password hashing with bcrypt -- Role-based access control - -### Container Security -- Non-root user execution -- Minimal base images (Alpine Linux) -- Health checks for all services -- Resource limits and constraints - -## 📊 Monitoring & Maintenance - -### Health Checks - -All services include health checks: - -```bash -# Check all service health -docker-compose ps - -# View detailed health status -docker inspect ideas-gen-backend --format='{{.State.Health.Status}}' -``` - -### Logs - -Access logs for troubleshooting: - -```bash -# All services -docker-compose logs -f - -# Specific service -docker-compose logs -f backend -docker-compose logs -f frontend -docker-compose logs -f database -``` - -### Database Backup - -```bash -# Create backup -./scripts/deploy.sh backup - -# Manual backup -docker-compose exec database pg_dump -U ideas_admin ideas_gen_prod > backup.sql -``` - -### Updates - -```bash -# Update to latest version -./scripts/deploy.sh update - -# Manual update -git pull -docker-compose up -d --build -``` - -## 🔧 Advanced Configuration - -### Custom SSL Certificates - -1. Place your certificates in the SSL directory: -```bash -mkdir -p /etc/ssl/certs/ideas-gen -cp your-cert.crt /etc/ssl/certs/ideas-gen/ -cp your-key.key /etc/ssl/certs/ideas-gen/ -``` - -2. Update SSL_CERT_PATH in .env: -```env -SSL_CERT_PATH=/etc/ssl/certs/ideas-gen -``` - -### Custom Domain Setup - -1. Configure DNS to point to your server -2. Update DOMAIN_NAME in .env -3. Restart services: -```bash -docker-compose up -d -``` - -### Production Tuning - -For high-traffic deployments, consider: - -1. **Resource Limits**: Add memory/CPU limits to docker-compose.yml -2. **Load Balancing**: Use multiple backend replicas -3. **Database Tuning**: Optimize PostgreSQL settings -4. **Monitoring**: Add Prometheus/Grafana monitoring - -## 🐛 Troubleshooting - -### Common Issues - -#### Services Won't Start -```bash -# Check logs for errors -docker-compose logs - -# Check Docker daemon -docker info - -# Verify disk space -df -h -``` - -#### Database Connection Issues -```bash -# Check database health -docker-compose exec database pg_isready -U ideas_admin - -# Reset database -docker-compose down -v -docker-compose up database -d -``` - -#### Frontend Build Issues -```bash -# Rebuild frontend only -docker-compose build frontend -docker-compose up -d frontend -``` - -#### Permission Issues -```bash -# Fix Docker permissions (Linux) -sudo chown -R $USER:docker /var/run/docker.sock -``` - -### Performance Issues - -#### Slow Response Times -1. Check system resources: `docker stats` -2. Review nginx logs: `docker-compose logs frontend` -3. Monitor database queries: `docker-compose logs database` - -#### High Memory Usage -1. Optimize Node.js memory: Add `NODE_OPTIONS=--max-old-space-size=512` to backend environment -2. Tune PostgreSQL: Adjust `shared_buffers` and `work_mem` - -## 🔄 Development vs Production - -### Development Mode (Localhost) -- Uses HTTP only -- Relaxed CORS settings -- Debug logging enabled -- Hot reload for frontend development - -### Production Mode -- HTTPS enforcement -- Strict security headers -- Compressed assets -- Rate limiting enabled -- Health monitoring - -## 📚 Additional Resources - -- [Docker Documentation](https://docs.docker.com/) -- [Docker Compose Reference](https://docs.docker.com/compose/) -- [Azure AD Integration Guide](../AUTHENTICATION_GUIDE.md) -- [OpenAI API Documentation](https://platform.openai.com/docs) - -## 🆘 Support - -For deployment issues: - -1. Check the troubleshooting section above -2. Review service logs: `docker-compose logs` -3. Verify configuration: `docker-compose config` -4. Check system resources: `docker stats` - -## 🏷️ Version Information - -- **Docker Compose Version**: 3.8 -- **Node.js Version**: 18 (Alpine) -- **PostgreSQL Version**: 15 (Alpine) -- **Nginx Version**: Latest (Alpine) - ---- - -**Generated with [Claude Code](https://claude.ai/code)** - -*This deployment setup provides enterprise-grade security, scalability, and maintainability for the Ideas Generator 2025 application.* \ No newline at end of file +# Ideas Generator 2025 - Docker Deployment + +Complete Docker deployment for Ideas Generator 2025 with automatic database initialization. + +## Quick Start + +1. **Clone the repository:** + ```bash + git clone git@bitbucket.org:zlalani/ideas-generator.git + cd ideas-generator + git checkout docker-deployment + cd docker + ``` + +2. **Run the simple setup:** + ```bash + chmod +x simple-setup.sh + ./simple-setup.sh + ``` + +3. **Access your application:** + - URL: http://localhost:8083 + - Admin Login: admin@oliver.agency / admin123 + +## What Gets Set Up + +- ✅ PostgreSQL database with automatic initialization +- ✅ Node.js backend API with authentication +- ✅ Vue.js frontend with modern UI +- ✅ Nginx reverse proxy +- ✅ Admin user created automatically +- ✅ All AI agents seeded and ready to use + +## Admin Features + +Login as `admin@oliver.agency` to: +- Manage users and access controls +- Configure AI agents and assistants +- View analytics and system health +- Toggle password authentication on/off +- Assign agents to users manually + +## Requirements + +- Docker and Docker Compose installed +- OpenAI API key (you'll be prompted during setup) +- Ports 8083 available (or customize in setup) + +## Customization + +The setup script will ask for: +- Domain name (default: localhost) +- HTTP port (default: 8083) +- OpenAI API key (required) + +Advanced configuration can be done by editing the generated `.env` file. + +## Architecture + +``` +Frontend (Vue.js + Nginx) + ↓ +Backend (Node.js + Express) + ↓ +Database (PostgreSQL) +``` + +## Troubleshooting + +**Port conflicts:** Change the HTTP_PORT in .env file +**Database issues:** Check `docker compose logs database` +**Backend errors:** Check `docker compose logs backend` +**Frontend issues:** Check `docker compose logs frontend` + +**Reset everything:** +```bash +docker compose down --volumes +docker system prune -f +./simple-setup.sh +``` + +## Management Commands + +```bash +# View status +docker compose ps + +# View logs +docker compose logs -f + +# Stop services +docker compose down + +# Restart services +docker compose restart + +# Update and rebuild +git pull origin docker-deployment +docker compose up -d --build +``` + +## Production Deployment + +For production deployment: +1. Use a proper domain name +2. Set up SSL certificates in `/certs` directory +3. Change default admin password +4. Configure proper CORS settings +5. Set up backup procedures for PostgreSQL data +EOF < /dev/null diff --git a/docker/scripts/init-database.js b/docker/scripts/init-database.js new file mode 100644 index 0000000..089e74e --- /dev/null +++ b/docker/scripts/init-database.js @@ -0,0 +1,74 @@ +#!/usr/bin/env node + +/** + * Database Initialization Script for Docker Deployment + * Runs migrations and creates admin user automatically + */ + +const bcrypt = require('bcrypt'); +const { sequelize, testConnection } = require('../config/database'); +const { User } = require('../models'); + +async function initDatabase() { + try { + console.log('🔄 Initializing database...'); + + // Test connection + await testConnection(); + + // Run migrations (sync models) + console.log('📋 Running database migrations...'); + await sequelize.sync({ force: false, alter: true }); + console.log('✅ Database migrations completed'); + + // Check if admin user exists + const existingAdmin = await User.findOne({ + where: { email: 'admin@oliver.agency' } + }); + + if (!existingAdmin) { + // Create admin user + console.log('👑 Creating admin user...'); + const hashedPassword = await bcrypt.hash('admin123', 10); + + await User.create({ + email: 'admin@oliver.agency', + name: 'Administrator', + password: hashedPassword, + isActive: true, + preferences: { + theme: 'light', + notifications: true, + defaultAssistant: 'creator-bot-push-the-boundaries-of-technology', + role: 'admin', + allowedAgents: null, + } + }); + + console.log('✅ Admin user created: admin@oliver.agency / admin123'); + } else { + console.log('👑 Admin user already exists'); + } + + // Run seed data (agents) + console.log('🌱 Seeding initial data...'); + const seedScript = require('../migrations/seed'); + await seedScript(); + + console.log('🎉 Database initialization completed successfully!'); + console.log('📋 Admin login: admin@oliver.agency / admin123'); + + } catch (error) { + console.error('❌ Database initialization failed:', error); + throw error; + } +} + +// Run if called directly +if (require.main === module) { + initDatabase() + .then(() => process.exit(0)) + .catch(() => process.exit(1)); +} + +module.exports = initDatabase; \ No newline at end of file diff --git a/docker/simple-setup.sh b/docker/simple-setup.sh index 4a97419..88a4e8d 100755 --- a/docker/simple-setup.sh +++ b/docker/simple-setup.sh @@ -118,6 +118,14 @@ EOF echo "✅ Configuration saved to .env" +echo "" +echo -e "${BLUE}📋 Important Information:${NC}" +echo -e "${YELLOW} After deployment, you can login with:${NC}" +echo -e "${CYAN} Email: admin@oliver.agency${NC}" +echo -e "${CYAN} Password: admin123${NC}" +echo -e "${YELLOW} The database will be automatically initialized on first start.${NC}" +echo "" + echo "" echo -e "${CYAN}━━━ 🚀 Starting Docker Deployment ━━━${NC}" echo "" diff --git a/server/.env b/server/.env deleted file mode 100644 index 63adbf2..0000000 --- a/server/.env +++ /dev/null @@ -1,27 +0,0 @@ -# Database Configuration -DATABASE_URL=postgres://localhost:5432/ideas_gen_dev -DATABASE_HOST=localhost -DATABASE_NAME=ideas_gen_dev -DATABASE_USER=daveporter -DATABASE_PASS= - -# Redis Configuration -REDIS_URL=redis://localhost:6379 - -# OpenAI Configuration (REQUIRED - Replace with your actual keys) -OPENAI_API_KEY=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 -OPENAI_ORG_ID=org-HSioKMud1tZBdpWhBjJE6SLe - -# Server Configuration -PORT=3000 -NODE_ENV=development - -# Development Flags -SKIP_AUTH=true -ENABLE_CORS=true -LOG_LEVEL=debug -SKIP_RATE_LIMITING=true - -# Optional Features -ENABLE_TITLE_GENERATION=true -ENABLE_MODERATION=true diff --git a/server/index.js b/server/index.js index 21d9d75..de3d68f 100644 --- a/server/index.js +++ b/server/index.js @@ -99,6 +99,17 @@ app.listen(PORT, async () => { // Test database connection await testConnection(); + // Auto-initialize database in Docker environment + if (process.env.NODE_ENV === 'production' && process.env.DATABASE_HOST) { + try { + console.log('🔧 Auto-initializing database for Docker deployment...'); + const initDatabase = require('./scripts/init-database'); + await initDatabase(); + } catch (error) { + console.warn('⚠️ Database auto-initialization failed:', error.message); + } + } + // Log important environment status if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY.includes('your-actual')) { console.warn('⚠️ WARNING: OpenAI API key not configured! Update .env file.'); diff --git a/server/scripts/init-database.js b/server/scripts/init-database.js new file mode 100644 index 0000000..76fe92c --- /dev/null +++ b/server/scripts/init-database.js @@ -0,0 +1,67 @@ +const bcrypt = require('bcrypt'); +const { sequelize, testConnection } = require('../config/database'); +const { User } = require('../models'); + +async function initDatabase() { + try { + console.log('🔄 Initializing database...'); + + // Test connection + await testConnection(); + + // Run migrations (sync models) + console.log('📋 Running database migrations...'); + await sequelize.sync({ force: false, alter: true }); + console.log('✅ Database migrations completed'); + + // Check if admin user exists + const existingAdmin = await User.findOne({ + where: { email: 'admin@oliver.agency' } + }); + + if (!existingAdmin) { + // Create admin user + console.log('👑 Creating admin user...'); + const hashedPassword = await bcrypt.hash('admin123', 10); + + await User.create({ + email: 'admin@oliver.agency', + name: 'Administrator', + password: hashedPassword, + isActive: true, + preferences: { + theme: 'light', + notifications: true, + defaultAssistant: 'creator-bot-push-the-boundaries-of-technology', + role: 'admin', + allowedAgents: null, + } + }); + + console.log('✅ Admin user created: admin@oliver.agency / admin123'); + } else { + console.log('👑 Admin user already exists'); + } + + // Run seed data (agents) - import and check if it has the async function + try { + const seedModule = require('../migrations/seed'); + if (typeof seedModule === 'function') { + console.log('🌱 Seeding initial data...'); + await seedModule(); + console.log('✅ Initial data seeded'); + } + } catch (seedError) { + console.warn('⚠️ Seed data already exists or failed:', seedError.message); + } + + console.log('🎉 Database initialization completed successfully!'); + console.log('📋 Admin login: admin@oliver.agency / admin123'); + + } catch (error) { + console.error('❌ Database initialization failed:', error); + throw error; + } +} + +module.exports = initDatabase; \ No newline at end of file