# 🚀 Deployment Guide — GrantForge AI Enterprise (v1.3.0) > **Sprint 9 — Instrukcja produkcyjna** > Aktualizacja: kwiecień 2026 | Stack: Render.com + PostgreSQL + GitHub Actions CI/CD --- ## Architektura Deploymentu ``` GitHub (main) → GitHub Actions CI/CD → Render.com ├── grantforge-api (FastAPI + Gunicorn) ├── grantforge-frontend (React SPA) └── grantforge-db (PostgreSQL 16) ``` --- ## KROK 1: GitHub Repository Secrets Przejdź do: `GitHub → Settings → Secrets and variables → Actions` ### Wymagane Secrets (CI/CD + Deploy): | Secret Name | Skąd wziąć | Ważny? | |---|---|---| | `GOOGLE_API_KEY` | [Google AI Studio](https://aistudio.google.com/app/apikey) | ✅ Wymagany | | `VITE_CLERK_PUBLISHABLE_KEY` | Clerk Dashboard → API Keys → Publishable Key | ✅ Wymagany | | `RENDER_DEPLOY_HOOK_BACKEND` | Render → API service → Settings → Deploy Hook | ✅ Wymagany | | `RENDER_DEPLOY_HOOK_FRONTEND` | Render → Static service → Settings → Deploy Hook | ✅ Wymagany | | `PINECONE_API_KEY` | [Pinecone Console](https://app.pinecone.io) | RAG optional | | `PINECONE_INDEX_NAME` | Pinecone Console → Index name | RAG optional | | `LANGCHAIN_API_KEY` | [LangSmith](https://smith.langchain.com) → Settings | Monitoring | ### Jak dodać secret: ``` GitHub repo → Settings → Secrets → Actions → New repository secret ``` #### Render Deploy Hook (backend): 1. Render Dashboard → `grantforge-api` → Settings 2. Scroll do sekcji **Deploy Hooks** 3. Kliknij **Add Deploy Hook** → Nazwa: `ci-deploy` 4. Skopiuj URL (format: `https://api.render.com/deploy/srv-xxx?key=yyy`) 5. Zapisz jako secret `RENDER_DEPLOY_HOOK_BACKEND` #### Render Deploy Hook (frontend): 1. Render Dashboard → `grantforge-frontend` → Settings 2. Kliknij **Add Deploy Hook** → Nazwa: `ci-frontend` 3. Skopiuj URL → Zapisz jako `RENDER_DEPLOY_HOOK_FRONTEND` --- ## KROK 2: Render → Environment Variables Przejdź do: `Render → grantforge-api → Environment` Ustaw następujące zmienne (kliknij **Add Environment Variable** dla każdej): ```bash # ── LLM ───────────────────────────── GOOGLE_API_KEY= # Klucz Google Gemini BIELIK_MODE=disabled # disabled / huggingface / ollama # ── Autentykacja Clerk ─────────────── CLERK_SECRET_KEY= # sk_live_... (Clerk Dashboard → API Keys) CLERK_PUBLISHABLE_KEY= # pk_live_... (Clerk Dashboard → API Keys) # ── RAG / Pinecone ─────────────────── PINECONE_API_KEY= # Opcjonalne — bez tego RAG działa lokalnie PINECONE_INDEX_NAME= # Nazwa indeksu PINECONE_ENVIRONMENT= # Np. "gcp-starter" # ── LangSmith (monitoring) ─────────── LANGCHAIN_API_KEY= # ls_... ze smith.langchain.com LANGCHAIN_TRACING_V2=true LANGCHAIN_PROJECT=grantforge-production # ── Stripe (płatności) ─────────────── STRIPE_SECRET_KEY= # sk_live_... STRIPE_WEBHOOK_SECRET= # whsec_... STRIPE_PRICE_ID_PRO= # price_... # ── Dysk danych ────────────────────── UPLOAD_DIR=/data/uploads VECTOR_STORE_DIR=/data/vector_store LLAMAPARSE_CACHE_DIR=/data/llamaparse_cache ``` > **Uwaga:** `DATABASE_URL` jest automatycznie wstrzyknięty przez Render Blueprint z bloku `databases`. --- ## KROK 3: Pierwsza Migracja Bazy Danych Po pierwszym deploymencie na Render, uruchom one-off job alembic: 1. Render → `grantforge-api` → **Shell** (lub: one-off command) 2. Wpisz: ```bash alembic upgrade head ``` 3. Sprawdź czy tabele zostały stworzone (w tym `project_documents` z Sprint 8). ### Lokalnie (przed deploy): ```bash cd backend alembic upgrade head ``` Jeśli błąd — sprawdź `DATABASE_URL` w `.env`. --- ## KROK 4: Weryfikacja po Deploy Po uruchomieniu, zweryfikuj każdy endpoint: ```bash # 1. Health check (podstawowy) curl https://grantforge-api.onrender.com/api/health # Oczekiwana odpowiedź: # {"status": "ok", "db": "connected", "version": "1.3.0", ...} # 2. Sprawdź czy upload PDF działa curl -X POST https://grantforge-api.onrender.com/api/projects/TEST_PROJECT_ID/documents \ -F "file=@test.pdf" # Oczekiwane: 202 Accepted # 3. Sprawdź listę dokumentów z kwotą curl https://grantforge-api.onrender.com/api/projects/TEST_PROJECT_ID/documents # Oczekiwane: {"documents": [], "quota": {"current": 0, "limit": 3, "plan": "free", "can_upload": true}} # 4. Sprawdź nabory curl https://grantforge-api.onrender.com/api/grants/nabory # Oczekiwane: {"total": N, "sources": [...]} ``` --- ## KROK 5: CI/CD — Pierwszy Push Po skonfigurowaniu secrets, każdy push na `main` uruchomi pipeline: ```bash git add -A git commit -m "chore: Sprint 9 — upload limits + E2E tests" git push origin main ``` Pipeline (`.github/workflows/ci.yml`): 1. 🔍 **Lint & Type Check** (ruff + mypy) 2. 🧪 **Backend Tests** (pytest) 3. 🎯 **DeepEval RAG** (tylko main) 4. 🏗️ **Frontend Build** (Vite) 5. 🐳 **Docker Build & Push** (ghcr.io) 6. 🚀 **Deploy to Render** (webhook) Monitor pipeline: `GitHub → Actions → CI/CD — GrantForge AI` --- ## Limity Upload PDF (Sprint 9) | Plan | Max pliki/projekt | Hard limit | |---|---|---| | Free | 3 PDF | 10 PDF | | Pro | 50 PDF | 10 PDF | | Enterprise | 50 PDF | 10 PDF | > Hard limit (10) jest bezwzględny — dotyczy wszystkich planów. > Soft limit jest egzekwowany przez `_check_upload_limits()` w `endpoints/documents.py`. --- ## Troubleshooting ### Backend nie startuje ```bash # Sprawdź logi Render → Logs # Najczęstszy błąd: brak DATABASE_URL lub import error ``` ### Alembic error: "Can't locate revision" ```bash cd backend alembic stamp head # jeśli tabele już istnieją alembic upgrade head ``` ### Upload 429 Too Many Requests Użytkownik osiągnął limit planu. Opcje: 1. Usuń stary dokument w zakładce "Dokumenty RAG" 2. Przejdź na plan Pro (`/cennik`) ### RAG nie indeksuje (status: error) Sprawdź w Render Shell: ```bash # W logach szukaj [RAG Upload] ❌ # Najprawdopodobniejsza przyczyna: Pinecone key / pusty PDF ```