✅ Production-Ready Containerization: - Multi-stage frontend build (Vue.js + Nginx) - Optimized backend container (Node.js + Alpine) - PostgreSQL 15 with persistent storage and health checks - Custom Docker network for secure service communication ✅ Interactive Setup Wizard (setup.sh): - Beautiful CLI interface with colors and progress indicators - Automatic secure password and JWT secret generation - Complete environment configuration with validation - Domain, SSL, Azure AD, and OpenAI API setup - One-command deployment with immediate startup option ✅ Production Security & Performance: - Nginx reverse proxy with rate limiting and security headers - HTTPS/SSL support with custom certificate mounting - CORS protection and request validation - Non-root container execution for all services - Health checks and monitoring for reliability ✅ Management & Operations: - Comprehensive deploy.sh script with all common operations - Database backup and restore capabilities - Service logs management and troubleshooting tools - Docker Compose orchestration with dependency management - Development vs production environment support ✅ Enterprise Features: - Azure AD SSO integration with hybrid authentication - OpenAI API configuration and secure key management - Multi-environment support (localhost vs production) - Comprehensive documentation and troubleshooting guides - Resource optimization and performance tuning 🏗️ Architecture: - Frontend: Vue.js + Vite → Nginx (port 80/443) - Backend: Node.js + Express (internal port 3000) - Database: PostgreSQL 15 (internal port 5432) - Networking: Isolated Docker bridge network - Storage: Named volumes for data persistence 🚀 Deployment Commands: - ./setup.sh - Interactive deployment wizard - ./scripts/deploy.sh [start|stop|build|logs|status] - docker-compose up -d --build - Automatic migrations and admin user creation 🔒 Security Hardening: - Rate limiting on API endpoints (10 req/s) and auth (5 req/min) - Security headers (X-Frame-Options, CSP, HSTS) - CORS validation and origin checking - SSL/TLS encryption support - Container isolation and minimal attack surface 📚 Complete Documentation: - Comprehensive README with architecture overview - Troubleshooting guide with common issues - Development vs production configuration - Performance tuning and scaling recommendations 🎯 One-Command Production Deployment: Everything needed to deploy Ideas Generator 2025 in production with enterprise security, monitoring, and Azure AD SSO integration. 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
340 lines
No EOL
12 KiB
Bash
Executable file
340 lines
No EOL
12 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Ideas Generator 2025 - Interactive Docker Setup Script
|
|
# This script guides you through the complete deployment setup
|
|
|
|
set -e
|
|
|
|
# Colors for pretty output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
PURPLE='\033[0;35m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Unicode symbols
|
|
CHECKMARK="✅"
|
|
ROCKET="🚀"
|
|
GEAR="⚙️"
|
|
KEY="🔑"
|
|
DATABASE="🗄️"
|
|
CLOUD="☁️"
|
|
LOCK="🔒"
|
|
GLOBE="🌐"
|
|
|
|
print_header() {
|
|
clear
|
|
echo -e "${PURPLE}╔══════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${PURPLE}║${NC} ${ROCKET} ${CYAN}Ideas Generator 2025 - Docker Deployment Setup${NC} ${PURPLE}║${NC}"
|
|
echo -e "${PURPLE}╚══════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}This script will guide you through setting up your complete deployment.${NC}"
|
|
echo -e "${BLUE}We'll configure everything needed for production deployment.${NC}"
|
|
echo ""
|
|
}
|
|
|
|
print_section() {
|
|
echo ""
|
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${CYAN}$1${NC}"
|
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo ""
|
|
}
|
|
|
|
ask_question() {
|
|
local question="$1"
|
|
local default="$2"
|
|
local is_password="$3"
|
|
local response
|
|
|
|
if [ -n "$default" ]; then
|
|
if [ "$is_password" = "password" ]; then
|
|
echo -e "${BLUE}$question${NC} ${YELLOW}[default: ****]${NC}"
|
|
echo -n "Enter value (or press Enter for default): "
|
|
read -s response
|
|
echo ""
|
|
else
|
|
echo -e "${BLUE}$question${NC} ${YELLOW}[default: $default]${NC}"
|
|
echo -n "Enter value (or press Enter for default): "
|
|
read response
|
|
fi
|
|
|
|
if [ -z "$response" ]; then
|
|
response="$default"
|
|
fi
|
|
else
|
|
if [ "$is_password" = "password" ]; then
|
|
echo -e "${BLUE}$question${NC} ${RED}(required)${NC}"
|
|
while [ -z "$response" ]; do
|
|
echo -n "Enter value: "
|
|
read -s response
|
|
echo ""
|
|
if [ -z "$response" ]; then
|
|
echo -e "${RED}This field is required. Please enter a value.${NC}"
|
|
fi
|
|
done
|
|
else
|
|
echo -e "${BLUE}$question${NC} ${RED}(required)${NC}"
|
|
while [ -z "$response" ]; do
|
|
echo -n "Enter value: "
|
|
read response
|
|
if [ -z "$response" ]; then
|
|
echo -e "${RED}This field is required. Please enter a value.${NC}"
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
echo "$response"
|
|
}
|
|
|
|
generate_random_password() {
|
|
openssl rand -base64 32 2>/dev/null || date +%s | sha256sum | base64 | head -c 32
|
|
}
|
|
|
|
generate_jwt_secret() {
|
|
openssl rand -base64 64 2>/dev/null || date +%s | sha256sum | base64 | head -c 64
|
|
}
|
|
|
|
validate_email() {
|
|
local email="$1"
|
|
if [[ $email =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main setup function
|
|
main() {
|
|
print_header
|
|
|
|
echo -e "${GEAR} ${GREEN}Welcome to the Ideas Generator 2025 deployment setup!${NC}"
|
|
echo ""
|
|
echo "This wizard will collect all necessary configuration and generate your deployment files."
|
|
echo ""
|
|
read -p "Press Enter to continue..."
|
|
|
|
# Section 1: Basic Configuration
|
|
print_section "${GEAR} Basic Configuration"
|
|
|
|
DOMAIN_NAME=$(ask_question "What domain name will you use for deployment?" "localhost")
|
|
HTTP_PORT=$(ask_question "HTTP port to bind to?" "80")
|
|
HTTPS_PORT=$(ask_question "HTTPS port to bind to?" "443")
|
|
|
|
# Section 2: Database Configuration
|
|
print_section "${DATABASE} Database Configuration"
|
|
|
|
echo -e "${BLUE}Setting up PostgreSQL database configuration...${NC}"
|
|
echo ""
|
|
|
|
DATABASE_NAME=$(ask_question "Database name?" "ideas_gen_prod")
|
|
DATABASE_USER=$(ask_question "Database username?" "ideas_admin")
|
|
DEFAULT_DB_PASSWORD=$(generate_random_password)
|
|
DATABASE_PASSWORD=$(ask_question "Database password?" "$DEFAULT_DB_PASSWORD" "password")
|
|
|
|
# Section 3: Authentication & Security
|
|
print_section "${KEY} Authentication & Security Configuration"
|
|
|
|
echo -e "${BLUE}Setting up security credentials...${NC}"
|
|
echo ""
|
|
|
|
DEFAULT_JWT_SECRET=$(generate_jwt_secret)
|
|
JWT_SECRET=$(ask_question "JWT Secret (for password auth)?" "$DEFAULT_JWT_SECRET" "password")
|
|
|
|
echo ""
|
|
echo -e "${LOCK} ${CYAN}Azure AD Configuration${NC}"
|
|
echo -e "${BLUE}These values are pre-configured for Oliver Agency but can be customized:${NC}"
|
|
echo ""
|
|
|
|
AZURE_TENANT_ID=$(ask_question "Azure AD Tenant ID?" "e519c2e6-bc6d-4fdf-8d9c-923c2f002385")
|
|
AZURE_CLIENT_ID=$(ask_question "Azure AD Client ID?" "9079054c-9620-4757-a256-23413042f1ef")
|
|
|
|
# Section 4: OpenAI API Configuration
|
|
print_section "${CLOUD} OpenAI API Configuration"
|
|
|
|
echo -e "${BLUE}Configure your OpenAI API access:${NC}"
|
|
echo ""
|
|
|
|
OPENAI_API_KEY=$(ask_question "OpenAI API Key?" "" "password")
|
|
|
|
# Section 5: URLs and CORS
|
|
print_section "${GLOBE} URL and CORS Configuration"
|
|
|
|
echo -e "${BLUE}Configure application URLs and security settings...${NC}"
|
|
echo ""
|
|
|
|
if [ "$DOMAIN_NAME" != "localhost" ]; then
|
|
FRONTEND_URL="https://$DOMAIN_NAME"
|
|
BACKEND_URL="https://$DOMAIN_NAME/api"
|
|
CORS_ORIGIN="https://$DOMAIN_NAME,http://$DOMAIN_NAME"
|
|
else
|
|
FRONTEND_URL="http://localhost"
|
|
BACKEND_URL="http://localhost/api"
|
|
CORS_ORIGIN="http://localhost,https://localhost"
|
|
fi
|
|
|
|
FRONTEND_URL=$(ask_question "Frontend URL?" "$FRONTEND_URL")
|
|
BACKEND_URL=$(ask_question "Backend URL?" "$BACKEND_URL")
|
|
CORS_ORIGIN=$(ask_question "CORS allowed origins (comma-separated)?" "$CORS_ORIGIN")
|
|
|
|
# SSL Configuration
|
|
if [ "$DOMAIN_NAME" != "localhost" ]; then
|
|
echo ""
|
|
echo -e "${LOCK} ${CYAN}SSL Configuration${NC}"
|
|
SSL_CERT_PATH=$(ask_question "SSL certificate directory path?" "/etc/ssl/certs")
|
|
else
|
|
SSL_CERT_PATH="./certs"
|
|
fi
|
|
|
|
# Section 6: Generate Configuration Files
|
|
print_section "${GEAR} Generating Configuration Files"
|
|
|
|
echo -e "${BLUE}Creating .env file with your configuration...${NC}"
|
|
|
|
# Create .env file
|
|
cat > .env << EOF
|
|
# Ideas Generator 2025 - Docker Deployment Configuration
|
|
# Generated on $(date)
|
|
|
|
# Basic Configuration
|
|
DOMAIN_NAME=$DOMAIN_NAME
|
|
HTTP_PORT=$HTTP_PORT
|
|
HTTPS_PORT=$HTTPS_PORT
|
|
|
|
# Database Configuration
|
|
DATABASE_NAME=$DATABASE_NAME
|
|
DATABASE_USER=$DATABASE_USER
|
|
DATABASE_PASSWORD=$DATABASE_PASSWORD
|
|
|
|
# Security Configuration
|
|
JWT_SECRET=$JWT_SECRET
|
|
|
|
# Azure AD Configuration
|
|
AZURE_TENANT_ID=$AZURE_TENANT_ID
|
|
AZURE_CLIENT_ID=$AZURE_CLIENT_ID
|
|
|
|
# OpenAI Configuration
|
|
OPENAI_API_KEY=$OPENAI_API_KEY
|
|
|
|
# URL Configuration
|
|
FRONTEND_URL=$FRONTEND_URL
|
|
BACKEND_URL=$BACKEND_URL
|
|
CORS_ORIGIN=$CORS_ORIGIN
|
|
|
|
# SSL Configuration
|
|
SSL_CERT_PATH=$SSL_CERT_PATH
|
|
EOF
|
|
|
|
echo -e "${CHECKMARK} ${GREEN}.env file created successfully!${NC}"
|
|
|
|
# Create docker-compose override for development if localhost
|
|
if [ "$DOMAIN_NAME" == "localhost" ]; then
|
|
cat > docker-compose.override.yml << EOF
|
|
version: '3.8'
|
|
|
|
# Development overrides for localhost deployment
|
|
services:
|
|
frontend:
|
|
ports:
|
|
- "$HTTP_PORT:80"
|
|
environment:
|
|
NGINX_HOST: localhost
|
|
|
|
backend:
|
|
environment:
|
|
NODE_ENV: development
|
|
EOF
|
|
echo -e "${CHECKMARK} ${GREEN}docker-compose.override.yml created for development!${NC}"
|
|
fi
|
|
|
|
# Section 7: Final Instructions
|
|
print_section "${ROCKET} Deployment Ready!"
|
|
|
|
echo -e "${GREEN}Configuration completed successfully!${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}Your configuration has been saved to:${NC}"
|
|
echo -e " ${CYAN}.env${NC} - Main environment configuration"
|
|
[ -f docker-compose.override.yml ] && echo -e " ${CYAN}docker-compose.override.yml${NC} - Development overrides"
|
|
echo ""
|
|
echo -e "${YELLOW}Next steps:${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}1.${NC} Build and start the application:"
|
|
echo -e " ${CYAN}docker-compose up -d --build${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}2.${NC} Check the status of all services:"
|
|
echo -e " ${CYAN}docker-compose ps${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}3.${NC} View logs if needed:"
|
|
echo -e " ${CYAN}docker-compose logs -f${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}4.${NC} Access your application:"
|
|
echo -e " ${CYAN}$FRONTEND_URL${NC}"
|
|
echo ""
|
|
|
|
if [ "$DOMAIN_NAME" != "localhost" ]; then
|
|
echo -e "${YELLOW}Important for production deployment:${NC}"
|
|
echo -e "${BLUE}•${NC} Ensure your SSL certificates are in: ${CYAN}$SSL_CERT_PATH${NC}"
|
|
echo -e "${BLUE}•${NC} Configure your DNS to point to this server"
|
|
echo -e "${BLUE}•${NC} Ensure ports $HTTP_PORT and $HTTPS_PORT are open in your firewall"
|
|
echo ""
|
|
fi
|
|
|
|
echo -e "${LOCK} ${YELLOW}Security Notes:${NC}"
|
|
echo -e "${BLUE}•${NC} Your .env file contains sensitive information - keep it secure"
|
|
echo -e "${BLUE}•${NC} The admin user (daveporter@oliver.agency) will be created automatically"
|
|
echo -e "${BLUE}•${NC} Password authentication is enabled by default but can be disabled via admin panel"
|
|
echo ""
|
|
|
|
echo -e "${CHECKMARK} ${GREEN}Setup complete! Your Ideas Generator 2025 is ready to deploy.${NC}"
|
|
echo ""
|
|
|
|
# Ask if user wants to start deployment now
|
|
echo -n -e "${BLUE}Would you like to start the deployment now? (y/N): ${NC}"
|
|
read start_now
|
|
|
|
if [[ $start_now =~ ^[Yy]$ ]]; then
|
|
echo ""
|
|
echo -e "${ROCKET} ${GREEN}Starting deployment...${NC}"
|
|
echo ""
|
|
docker-compose up -d --build
|
|
|
|
echo ""
|
|
echo -e "${CHECKMARK} ${GREEN}Deployment started!${NC}"
|
|
echo -e "${BLUE}You can access your application at: ${CYAN}$FRONTEND_URL${NC}"
|
|
else
|
|
echo ""
|
|
echo -e "${BLUE}Run ${CYAN}docker-compose up -d --build${BLUE} when you're ready to deploy.${NC}"
|
|
fi
|
|
}
|
|
|
|
# Check for required tools
|
|
check_requirements() {
|
|
local missing_tools=()
|
|
|
|
if ! command -v docker &> /dev/null; then
|
|
missing_tools+=("docker")
|
|
fi
|
|
|
|
if ! command -v docker-compose &> /dev/null; then
|
|
missing_tools+=("docker-compose")
|
|
fi
|
|
|
|
if [ ${#missing_tools[@]} -ne 0 ]; then
|
|
echo -e "${RED}Error: Missing required tools: ${missing_tools[*]}${NC}"
|
|
echo ""
|
|
echo "Please install Docker and Docker Compose before running this script."
|
|
echo "Visit: https://docs.docker.com/get-docker/"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Script entry point
|
|
echo -e "${BLUE}Checking requirements...${NC}"
|
|
check_requirements
|
|
|
|
main
|
|
|
|
exit 0 |