From 296538b0eaec5fe43f2a5629bb18905f6e478393 Mon Sep 17 00:00:00 2001 From: nekenny Date: Fri, 3 Apr 2026 21:58:58 +0500 Subject: [PATCH] =?UTF-8?q?chore:=20project=20scaffolding=20=E2=80=94=20Do?= =?UTF-8?q?cker,=20nginx,=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .env.example | 37 ++++++++++++++++++ .gitignore | 29 ++++++++++++++ backend/Dockerfile | 23 +++++++++++ backend/requirements.txt | 43 +++++++++++++++++++++ docker-compose.dev.yml | 66 ++++++++++++++++++++++++++++++++ docker-compose.yml | 82 ++++++++++++++++++++++++++++++++++++++++ nginx/nginx.conf | 23 +++++++++++ 7 files changed, 303 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 backend/Dockerfile create mode 100644 backend/requirements.txt create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.yml create mode 100644 nginx/nginx.conf diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f7fad80 --- /dev/null +++ b/.env.example @@ -0,0 +1,37 @@ +# Database +POSTGRES_USER=meetproto +POSTGRES_PASSWORD=changeme +POSTGRES_DB=meetproto +DATABASE_URL=postgresql+asyncpg://meetproto:changeme@db:5432/meetproto + +# Redis +REDIS_URL=redis://redis:6379/0 + +# JWT +JWT_SECRET=change-this-to-a-random-secret +JWT_ALGORITHM=HS256 +JWT_EXPIRE_MINUTES=1440 + +# Whisper +WHISPER_MODEL=large-v3 +WHISPER_DEVICE=cuda +WHISPER_COMPUTE_TYPE=float16 + +# LLM +LITELLM_MODEL=openrouter/meta-llama/llama-3.1-70b-instruct +LITELLM_API_KEY=your-api-key-here +LITELLM_API_BASE= + +# Storage +UPLOAD_DIR=/app/uploads +EXPORT_DIR=/app/exports +RETENTION_DAYS=90 + +# Telegram +TELEGRAM_BOT_TOKEN=your-telegram-bot-token +TELEGRAM_WEBHOOK_URL=https://your-domain.com/api/telegram/webhook + +# App +APP_HOST=0.0.0.0 +APP_PORT=8000 +APP_URL=http://localhost:8000 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..881f5a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Python +__pycache__/ +*.py[cod] +*.egg-info/ +dist/ +.venv/ +venv/ + +# Environment +.env + +# IDE +.idea/ +.vscode/ +*.swp + +# Storage +uploads/ +exports/ + +# Node +node_modules/ +frontend/dist/ + +# Docker +*.log + +# Superpowers +.superpowers/ diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..e35489e --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,23 @@ +FROM nvidia/cuda:12.4.1-runtime-ubuntu22.04 + +ENV DEBIAN_FRONTEND=noninteractive +ENV PYTHONUNBUFFERED=1 + +# System dependencies +RUN apt-get update && apt-get install -y \ + python3.11 python3.11-venv python3-pip \ + ffmpeg \ + libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 \ + libffi-dev libcairo2 \ + && rm -rf /var/lib/apt/lists/* + +RUN ln -sf /usr/bin/python3.11 /usr/bin/python + +WORKDIR /app + +COPY requirements.txt . +RUN python -m pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..e580269 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,43 @@ +# Web framework +fastapi==0.115.6 +uvicorn[standard]==0.34.0 +python-multipart==0.0.20 + +# Database +sqlalchemy[asyncio]==2.0.36 +asyncpg==0.30.0 +alembic==1.14.1 + +# Validation +pydantic==2.10.4 +pydantic-settings==2.7.1 + +# Auth +passlib[bcrypt]==1.7.4 +python-jose[cryptography]==3.3.0 + +# Task queue +celery[redis]==5.4.0 +redis==5.2.1 + +# AI/ML +faster-whisper==1.1.0 +litellm==1.55.8 + +# Messengers +aiogram==3.15.0 + +# Export +python-docx==1.1.2 +weasyprint==63.1 +jinja2==3.1.5 +markdown==3.7 + +# Utils +ffmpeg-python==0.2.0 +httpx==0.28.1 + +# Testing +pytest==8.3.4 +pytest-asyncio==0.25.0 +httpx==0.28.1 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..ba51021 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,66 @@ +services: + app: + build: ./backend + env_file: .env + ports: + - "8000:8000" + volumes: + - ./backend:/app + - uploads:/app/uploads + - exports:/app/exports + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + command: > + sh -c "alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload" + + worker: + build: ./backend + env_file: .env + volumes: + - ./backend:/app + - uploads:/app/uploads + - exports:/app/exports + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] + command: celery -A app.tasks.celery_app worker --loglevel=info --concurrency=2 + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + db: + image: postgres:16-alpine + env_file: .env + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"] + interval: 5s + timeout: 3s + retries: 5 + +volumes: + pgdata: + uploads: + exports: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7307cca --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,82 @@ +services: + app: + build: ./backend + env_file: .env + ports: + - "8000:8000" + volumes: + - uploads:/app/uploads + - exports:/app/exports + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + command: > + sh -c "alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000" + + worker: + build: ./backend + env_file: .env + volumes: + - uploads:/app/uploads + - exports:/app/exports + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] + command: celery -A app.tasks.celery_app worker --loglevel=info --concurrency=2 + + beat: + build: ./backend + env_file: .env + depends_on: + redis: + condition: service_healthy + command: celery -A app.tasks.celery_app beat --loglevel=info + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + db: + image: postgres:16-alpine + env_file: .env + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"] + interval: 5s + timeout: 3s + retries: 5 + + nginx: + image: nginx:alpine + ports: + - "80:80" + volumes: + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf + - ./frontend/dist:/usr/share/nginx/html + depends_on: + - app + +volumes: + pgdata: + uploads: + exports: diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..7655c6c --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,23 @@ +upstream backend { + server app:8000; +} + +server { + listen 80; + server_name _; + client_max_body_size 2G; + + location /api/ { + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_read_timeout 300s; + } + + location / { + root /usr/share/nginx/html; + index index.html; + try_files $uri $uri/ /index.html; + } +}