diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7d895b6 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +DB_TYPE=sqlite +SQLITE_PATH=databases/chatbot.db +FLASK_DEBUG=true +FLASK_SECRET_KEY=change-this-in-productio \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..eb43eb6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Use Python 3.11 slim image for smaller size +FROM python:3.11-slim + +# Set maintainer +LABEL maintainer="your-email@example.com" +LABEL description="PY_ChatBot - Modern Flask-based Chatbot Application" + +# Set environment variables +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + FLASK_APP=main.py \ + FLASK_ENV=production \ + PIP_NO_CACHE_DIR=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# Set work directory +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + gcc \ + sqlite3 \ + && rm -rf /var/lib/apt/lists/* + +# Create non-root user for security +RUN addgroup --system --gid 1001 chatbot && \ + adduser --system --uid 1001 --gid 1001 --no-create-home --disabled-password chatbot + +# Copy requirements first for better Docker layer caching +COPY requirements.txt . + +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application code +COPY . . + +# Create necessary directories and set permissions +RUN mkdir -p /app/databases /app/logs /app/static && \ + chown -R chatbot:chatbot /app + +# Copy entrypoint script +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +# Switch to non-root user +USER chatbot + +# Expose port +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ + CMD curl -f http://localhost:8080/ || exit 1 + +# Set entrypoint +ENTRYPOINT ["docker-entrypoint.sh"] + +# Default command +CMD ["python", "main.py"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8e97c01 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +services: + # Main ChatBot Application + chatbot: + build: + context: . + dockerfile: Dockerfile + container_name: py_chatbot + restart: unless-stopped + ports: + - "8080:8080" + environment: + # Database Configuration + - DB_TYPE=sqlite + - SQLITE_PATH=/app/data/chatbot.db + + # Flask Configuration + - FLASK_HOST=0.0.0.0 + - FLASK_PORT=8080 + - FLASK_DEBUG=false + - FLASK_SECRET_KEY=your-super-secret-key-change-this-in-production + + # Session Configuration + - SESSION_LIFETIME_HOURS=24 + - SESSION_COOKIE_SECURE=false + - SESSION_COOKIE_HTTPONLY=true + volumes: + # Persist database and logs + - chatbot_data:/app/data + - chatbot_logs:/app/logs + networks: + - chatbot_network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + # Optional: PostgreSQL Database (for production) + #postgres: + # image: postgres:15-alpine + # container_name: py_chatbot_postgres + # restart: unless-stopped + # environment: + # - POSTGRES_DB=chatbot + # - POSTGRES_USER=chatbot_user + # - POSTGRES_PASSWORD=secure_password_change_this + # volumes: + # - postgres_data:/var/lib/postgresql/data + # - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro + # networks: + # - chatbot_network + # profiles: + # - postgres + +# Named Volumes +volumes: + chatbot_data: + driver: local + chatbot_logs: + driver: local + #postgres_data: + # driver: local + +# Networks +networks: + chatbot_network: + driver: bridge \ No newline at end of file diff --git a/docker-entrypoint b/docker-entrypoint new file mode 100644 index 0000000..82e108c --- /dev/null +++ b/docker-entrypoint @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +echo "🤖 Starting PY_ChatBot..." + +# Create directories if they don't exist +mkdir -p /app/databases /app/logs + +# Set default environment variables if not provided +export DB_TYPE=${DB_TYPE:-sqlite} +export SQLITE_PATH=${SQLITE_PATH:-databases/chatbot.db} +export FLASK_HOST=${FLASK_HOST:-0.0.0.0} +export FLASK_PORT=${FLASK_PORT:-8080} +export FLASK_DEBUG=${FLASK_DEBUG:-false} + +# Generate a random secret key if not provided +if [ -z "$FLASK_SECRET_KEY" ]; then + export FLASK_SECRET_KEY=$(python -c "import secrets; print(secrets.token_hex(32))") + echo "⚠️ Generated random secret key. Set FLASK_SECRET_KEY environment variable for production!" +fi + +# Initialize database if it doesn't exist +if [ "$DB_TYPE" = "sqlite" ] && [ ! -f "$SQLITE_PATH" ]; then + echo "📦 Initializing SQLite database at $SQLITE_PATH..." + python -c " +import sys +sys.path.append('/app') +from config.database import DatabaseConfig +from database import get_database + +try: + db_config = DatabaseConfig() + db_type, config = db_config.get_database_config() + database = get_database(db_type, config) + print('✅ Database initialized successfully!') + database.disconnect() +except Exception as e: + print(f'❌ Database initialization failed: {e}') + sys.exit(1) +" +fi + +# Print configuration info +echo "📋 Configuration:" +echo " - Database Type: $DB_TYPE" +echo " - Database Path: $SQLITE_PATH" +echo " - Flask Host: $FLASK_HOST" +echo " - Flask Port: $FLASK_PORT" +echo " - Debug Mode: $FLASK_DEBUG" + +# Execute the command +exec "$@" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5a4a2b9..2bc2985 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,36 @@ -flask -python-dotenv \ No newline at end of file +# Requirements for PY_ChatBot +# Core Framework +Flask>=2.3.0,<3.0.0 +Werkzeug>=2.3.0,<3.0.0 + +# Database & ORM (Optional for future expansion) +SQLAlchemy>=2.0.0,<3.0.0 + +# Environment & Configuration +python-dotenv>=1.0.0 + +# Security & Authentication +bcrypt>=4.0.0 + +# HTTP Client (for health checks and external APIs) +requests>=2.31.0 + +# Date/Time utilities +python-dateutil>=2.8.0 + +# Development Dependencies (commented out for production) +# pytest>=7.4.0 +# pytest-flask>=1.2.0 +# pytest-cov>=4.1.0 +# black>=23.7.0 +# flake8>=6.0.0 +# mypy>=1.5.0 + +# Production WSGI Server +gunicorn>=21.2.0 + +# Logging +colorlog>=6.7.0 + +# Utility +click>=8.1.0 \ No newline at end of file