- What This Project Needs
- Setup Option A — Docker (Easiest, Recommended)
- Setup Option B — Without Docker (Manual, Dev Mode)
- Setup Option C — Hybrid (Infra in Docker, Code on Host)
- Production Setup
- Helm / Kubernetes Reference
- Troubleshooting
- Quick Reference Cards
| Service | What it does | Default port |
|---|---|---|
| PostgreSQL | Main database — stores users, meetings, transcripts | 5432 |
| Redis | Cache + session store — keeps WebRTC state, caches DB queries | 6379 |
| RabbitMQ | Message queue — sends translation/summary/embedding jobs to AI service | 5672 |
| MinIO | File storage — holds meeting recordings (S3-compatible) | 9000 |
| TurboVec | Vector database — stores AI embeddings for semantic search | 8080 |
| OpenTelemetry Collector | Collects traces/metrics for monitoring | 4317 |
| Service | What it does | Default port |
|---|---|---|
| Backend (NestJS) | Auth, meetings, WebRTC signaling, chat, transcripts, recordings | 4000 |
| AI Service (FastAPI) | Translation, speech-to-text, text-to-speech, embeddings, summaries | 8000 |
| Frontend (Next.js) | Web UI | 3000 |
| Tool | Required for | Install link |
|---|---|---|
| Docker Desktop | Options A, C | https://docs.docker.com/get-docker/ |
| Node.js 20+ | Options B, C | https://nodejs.org/ (LTS) |
| Python 3.12+ | Options B, C | https://www.python.org/downloads/ |
| Git | All options | https://git-scm.com/ |
| Gemini API Key | All options | https://aistudio.google.com/ (free tier available) |
Everything runs in containers. No Node.js or Python needed on your machine.
git clone <your-repo-url>
cd polyglot-meet# Windows (PowerShell)
$env:GEMINI_API_KEY = "your-key-here"
# macOS / Linux
export GEMINI_API_KEY="your-key-here"To make it permanent, create a file called .env in the project root:
echo GEMINI_API_KEY=your-key-here > .envdocker compose up -dThis starts all 12 containers. The first build takes 5-15 minutes.
# Infrastructure first
docker compose -f docker\compose\postgres.yml up -d
docker compose -f docker\compose\redis.yml up -d
docker compose -f docker\compose\rabbitmq.yml up -d
docker compose -f docker\compose\minio.yml up -d
# App services
docker compose -f docker\compose\backend.yml up -d
docker compose -f docker\compose\ai-service.yml up -d
docker compose -f docker\compose\frontend.yml up -d
# Monitoring (optional)
docker compose -f docker\compose\prometheus.yml up -d
docker compose -f docker\compose\grafana.yml up -d
docker compose -f docker\compose\loki.yml up -d
docker compose -f docker\compose\otel-collector.yml up -dEach file is self-contained with its own network and volumes. Start in any order, but app services will retry until their dependencies are ready.
docker compose exec backend npx prisma migrate dev --name initIf using individual files, use the file flag each time:
docker compose -f docker\compose\backend.yml exec backend npx prisma migrate dev --name initdocker compose exec backend npx prisma db seedOpen http://localhost:3000 in your browser.
Login with any of these:
| Password | Role | |
|---|---|---|
| admin@polyglotmeet.com | Password123 | Admin |
| alice@example.com | Password123 | Host |
| bob@example.com | Password123 | Participant |
docker compose psFor individual files:
docker compose -f docker\compose\postgres.yml psAll services should show Up or healthy.
# View logs of a specific service (all-at-once)
docker compose logs -f backend
# View logs (individual files)
docker compose -f docker\compose\backend.yml logs -f
# Stop everything
docker compose down
# Stop individual service
docker compose -f docker\compose\backend.yml down
# Stop and delete all data (volumes)
docker compose down -v
# Rebuild a single service after code changes
docker compose build backend
docker compose up -d backend
# Rebuild with individual file
docker compose -f docker\compose\backend.yml build
docker compose -f docker\compose\backend.yml up -d
# Run a command inside a container
docker compose exec backend sh| Port | Service | URL |
|---|---|---|
| 3000 | Frontend | http://localhost:3000 |
| 4000 | Backend API | http://localhost:4000/api/v1 |
| 8000 | AI Service | http://localhost:8000 |
| 5432 | PostgreSQL | localhost:5432 |
| 6379 | Redis | localhost:6379 |
| 5672 | RabbitMQ | localhost:5672 |
| 15672 | RabbitMQ Admin | http://localhost:15672 (user: polyglot, pass: polyglot_secret) |
| 9000 | MinIO API | localhost:9000 |
| 9001 | MinIO Console | http://localhost:9001 (user: polyglot, pass: polyglot_secret) |
| 9090 | Prometheus | http://localhost:9090 |
| 3001 | Grafana | http://localhost:3001 (user: admin, pass: admin) |
| 3100 | Loki | http://localhost:3100 |
Everything runs directly on your machine. You need PostgreSQL, Redis, RabbitMQ, and MinIO installed separately OR use Docker just for those (Option C).
- PostgreSQL 16 — https://www.postgresql.org/download/
- Redis 7 — https://redis.io/download/
- RabbitMQ 3.13 — https://www.rabbitmq.com/download.html
- MinIO — https://min.io/download
- TurboVec — https://github.com/valkmit/turbovec (or skip embeddings)
Open a PostgreSQL prompt or use any GUI (pgAdmin, TablePlus):
CREATE DATABASE polyglot_meet;
CREATE USER polyglot WITH PASSWORD 'polyglot_secret';
GRANT ALL PRIVILEGES ON DATABASE polyglot_meet TO polyglot;Backend — edit backend/.env:
NODE_ENV=development
PORT=4000
DATABASE_URL=postgresql://polyglot:polyglot_secret@localhost:5432/polyglot_meet
REDIS_URL=redis://localhost:6379
RABBITMQ_URL=amqp://polyglot:polyglot_secret@localhost:5672
MINIO_ENDPOINT=localhost
MINIO_PORT=9000
MINIO_ACCESS_KEY=polyglot
MINIO_SECRET_KEY=polyglot_secret
MINIO_USE_SSL=false
JWT_SECRET=change-this-to-a-random-string
JWT_REFRESH_SECRET=change-this-to-another-random-string
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
AI_SERVICE_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000Frontend — edit frontend/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:4000
NEXT_PUBLIC_WS_URL=http://localhost:4000
NEXT_PUBLIC_AI_URL=http://localhost:8000AI Service — create ai-service/.env:
GEMINI_API_KEY=your-gemini-api-key-here
TURBOVEC_URL=http://localhost:8080
DATABASE_URL=postgresql://polyglot:polyglot_secret@localhost:5432/polyglot_meet
REDIS_URL=redis://localhost:6379
RABBITMQ_URL=amqp://polyglot:polyglot_secret@localhost:5672
LOG_LEVEL=INFOcd backend
# Install dependencies
npm install
# Generate Prisma client (TypeScript types from schema)
npx prisma generate
# Create database tables
npx prisma migrate dev --name init
# Seed demo data
npx prisma db seed
# Start in development mode (auto-restarts on changes)
npm run start:dev# Option A: Use standard venv
cd ai-service
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS / Linux:
source .venv/bin/activate
# Option B: Use uv (faster, recommended)
cd ai-service
pip install uv
uv venv
uv pip install -r requirements.txt
# Initialize database tables
python scripts/init_db.py
# Start the service
uvicorn app.main:app --reload --port 8000cd frontend
npm install
# Start development server
npm run devOpen http://localhost:3000 and log in with the seeded credentials above.
| Terminal | Command |
|---|---|
| 1 | cd backend && npm run start:dev |
| 2 | cd ai-service && source .venv/bin/activate && uvicorn app.main:app --reload --port 8000 |
| 3 | cd frontend && npm run dev |
Note: Without Docker, you won't have monitoring (Prometheus/Grafana/Loki). That's fine for development.
Best for active development: infrastructure runs in Docker, app code runs on your machine with hot-reload.
# Start all infra with one command, or use individual files:
docker compose -f docker\compose\postgres.yml up -d
docker compose -f docker\compose\redis.yml up -d
docker compose -f docker\compose\rabbitmq.yml up -d
docker compose -f docker\compose\minio.yml up -dSame as manual setup, but your database, cache, queue, and storage are already running in Docker.
| Item | What to do |
|---|---|
| JWT secrets | Generate 64-char random strings: openssl rand -hex 32 |
| Database password | Generate a strong password, update all .env files |
| RabbitMQ password | Same — change default, update all files |
| MinIO password | Same — change default |
| PostgreSQL | Set PGPASSWORD, disable remote root login |
| Redis | Set REDIS_PASSWORD in production |
| HTTPS | Put behind Nginx/Caddy with Let's Encrypt |
| CORS | Update FRONTEND_URL to your actual domain |
| TURN server | Deploy coturn for users behind restrictive firewalls |
# Generate all secrets in one go
echo "JWT_SECRET=$(openssl rand -hex 32)"
echo "JWT_REFRESH_SECRET=$(openssl rand -hex 32)"
echo "DB_PASSWORD=$(openssl rand -hex 16)"
echo "RABBITMQ_PASSWORD=$(openssl rand -hex 16)"
echo "MINIO_PASSWORD=$(openssl rand -hex 16)"# docker-compose.prod.yml (create this for production)
services:
# Same as docker-compose.yml but with these changes:
postgres:
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
redis:
# Add password
command: redis-server --requirepass ${REDIS_PASSWORD}
rabbitmq:
environment:
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
backend:
environment:
JWT_SECRET: ${JWT_SECRET}
JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET}
ai-service:
environment:
GEMINI_API_KEY: ${GEMINI_API_KEY}
# Add a reverse proxy
caddy:
image: caddy:2
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data# Run production stack
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d# 1. Install Node.js 20, Python 3.12, PostgreSQL 16, Redis 7, RabbitMQ 3.13, MinIO
# 2. Build everything
# Backend
cd backend
npm ci
npm run build # creates dist/
# Frontend
cd ../frontend
npm ci
npm run build # creates .next/
# AI Service
cd ../ai-service
pip install -r requirements.txt
# 3. Use a process manager (PM2 or systemd)
# Example with PM2:
npm install -g pm2
# Create ecosystem.config.js in project root:
# module.exports = {
# apps: [
# { name: "backend", cwd: "./backend", script: "dist/main.js", env: { NODE_ENV: "production" } },
# { name: "frontend", cwd: "./frontend", script: "node_modules/.bin/next", args: "start", env: { NODE_ENV: "production" } },
# { name: "ai-service", cwd: "./ai-service", script: ".venv/bin/uvicorn", args: "app.main:app --host 0.0.0.0 --port 8000", env: { NODE_ENV: "production" } }
# ]
# }
pm2 start ecosystem.config.js
pm2 save
pm2 startup # auto-start on reboot# Backup
docker compose exec postgres pg_dump -U polyglot polyglot_meet > backup_$(date +%Y%m%d).sql
# Restore
cat backup.sql | docker compose exec -T postgres psql -U polyglot polyglot_meet
# Automated (cron job)
# 0 3 * * * cd /path/to/polyglot-meet && docker compose exec -T postgres pg_dump -U polyglot polyglot_meet | gzip > backups/db_$(date +\%Y\%m\%d).sql.gzHelm is the Kubernetes package manager (like apt or npm for K8s). The helm/polyglot-meet/ folder contains a chart — a bundle of YAML templates that describe how to run Polyglot Meet on a Kubernetes cluster.
Instead of running 10+ separate kubectl apply commands for Deployments, Services, ConfigMaps, Secrets, Ingress, HPA, etc., you run one command:
helm install polyglot-meet ./helm/polyglot-meethelm/polyglot-meet/
├── Chart.yaml # metadata (name, version, description)
├── values.yaml # all configurable settings with defaults
├── charts/ # vendored dependency charts (Bitnami Postgres, Redis)
└── templates/ # Go-templated YAML files
├── deployment-backend.yaml
├── deployment-ai-service.yaml
├── deployment-frontend.yaml
├── service-backend.yaml
├── ... (service, ingress, hpa, configmap, secret, etc.)
You need a Kubernetes cluster. Here are your options:
| Option | Setup cost | Best for |
|---|---|---|
| Minikube | Free, local | Learning / testing |
| K3s | Free, local | Lightweight local dev |
| Docker Desktop K8s | Free (built-in) | Easiest local option |
| DigitalOcean | $12/mo | Production (simple) |
| Hetzner + K3s | ~$5/mo | Production (cheap) |
| EKS / AKS / GKE | Varies | Production (managed) |
# 1. Install Minikube: https://minikube.sigs.k8s.io/docs/start/
# 2. Start cluster
minikube start --cpus 4 --memory 8192
# 3. Install the chart
helm install polyglot-meet ./helm/polyglot-meet \
--set global.geminiApiKey=your-key-here \
--set global.environment=production
# 4. Check pods
kubectl get pods -w
# 5. Access the app
minikube service polyglot-meet-frontend
# 6. Run migrations
kubectl exec deployment/polyglot-meet-backend -- npx prisma migrate dev --name init
kubectl exec deployment/polyglot-meet-backend -- npx prisma db seed# Override specific values
helm install polyglot-meet ./helm/polyglot-meet \
--set global.geminiApiKey=xxx \
--set backend.replicaCount=3 \
--set backend.resources.requests.cpu=500m \
--set postgresql.postgresqlPassword=secure-passThe k8s/ folder is Kustomize — an alternative to Helm that uses plain YAML without templates. It has:
k8s/
├── base/
│ ├── deployment-backend.yaml
│ ├── deployment-ai-service.yaml
│ ├── deployment-frontend.yaml
│ ├── service-backend.yaml
│ ├── service-ai-service.yaml
│ ├── service-frontend.yaml
│ ├── ingress.yaml
│ ├── hpa-backend.yaml
│ └── ...
└── overlays/
├── dev/ (dev overrides: 1 replica, debug enabled)
└── prod/ (prod overrides: 3 replicas, resource limits, HPA)
Usage:
kubectl apply -k k8s/overlays/dev
kubectl apply -k k8s/overlays/prodHeads up: Run the K8s ingress commands only if you have an Ingress Controller installed (like nginx-ingress or traefik). Without one, services won't be accessible from outside the cluster.
# Check logs (all-at-once)
docker compose logs backend
# Check logs (individual file)
docker compose -f docker\compose\backend.yml logs
# Common issues:
# 1. PostgreSQL not ready yet — wait 10s and retry
# 2. Missing .env file — copy from .env.example
# 3. Prisma client not generated — run: npx prisma generate
# 4. Port 4000 already in use — change PORT in .env# Check logs
docker compose logs ai-service
# or: docker compose -f docker\compose\ai-service.yml logs
# Common issues:
# 1. Missing GEMINI_API_KEY — set environment variable
# 2. Database not migrated — backend needs to run first
# 3. Port 8000 already in use — change port in config.py# Rebuild without cache (all at once)
docker compose build --no-cache backend
# Rebuild without cache (individual file)
docker compose -f docker\compose\backend.yml build --no-cache
# Check Dockerfile syntax
# Common: line endings, missing files in context# WebRTC needs HTTPS or localhost
# On a remote server, you MUST use HTTPS
# If participants can't connect, you need a TURN server:
# 1. Deploy coturn
# 2. Update WebRTC config in backend/src/webrtc/# Windows: find what's using a port
netstat -ano | findstr :4000
# macOS / Linux
lsof -i :4000# Reset database and start fresh
npx prisma migrate reset --force
npx prisma db seedThe startup order matters:
- PostgreSQL → Redis → RabbitMQ → MinIO
- Backend (needs DB + Redis + RabbitMQ + MinIO)
- AI Service (needs DB + Redis + RabbitMQ)
- Frontend (needs Backend)
Docker Compose handles this automatically (all-at-once or per-file — services retry connections). For manual setups, start in that order.
git clone <url> && cd polyglot-meet
export GEMINI_API_KEY="your-key"
docker compose up -d
docker compose exec backend npx prisma migrate dev --name init
docker compose exec backend npx prisma db seed
# Open http://localhost:3000git clone <url> && cd polyglot-meet
export GEMINI_API_KEY="your-key"
docker compose -f docker\compose\postgres.yml up -d
docker compose -f docker\compose\redis.yml up -d
docker compose -f docker\compose\rabbitmq.yml up -d
docker compose -f docker\compose\minio.yml up -d
docker compose -f docker\compose\backend.yml up -d
docker compose -f docker\compose\ai-service.yml up -d
docker compose -f docker\compose\frontend.yml up -d
docker compose -f docker\compose\backend.yml exec backend npx prisma migrate dev --name init
docker compose -f docker\compose\backend.yml exec backend npx prisma db seed
# Open http://localhost:3000# Terminal 1: Start infra services (all-at-once or individual files)
docker compose up -d postgres redis rabbitmq minio
# OR:
# docker compose -f docker\compose\postgres.yml up -d
# docker compose -f docker\compose\redis.yml up -d
# docker compose -f docker\compose\rabbitmq.yml up -d
# docker compose -f docker\compose\minio.yml up -d
# Terminal 2: Backend
cd backend && npm install && npx prisma generate && npx prisma migrate dev --name init && npx prisma db seed && npm run start:dev
# Terminal 3: AI Service
cd ai-service && python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt && python scripts/init_db.py && uvicorn app.main:app --reload --port 8000
# Terminal 4: Frontend
cd frontend && npm install && npm run dev# Docker (all at once)
docker compose build backend ai-service frontend
docker compose up -d
# Docker (individual files)
docker compose -f docker\compose\backend.yml build
docker compose -f docker\compose\backend.yml up -d
# Manual — just restart the process (Ctrl+C then re-run), or if using
# `npm run start:dev` / `uvicorn --reload`, it auto-restarts on changes# Backup
docker compose exec postgres pg_dump -U polyglot polyglot_meet > backup.sql
# Restore
cat backup.sql | docker compose exec -T postgres psql -U polyglot polyglot_meet# WARNING: Deletes all data
docker compose down -v
rm -rf backend/node_modules frontend/node_modules ai-service/.venv
# Then start fresh from step 1