Skip to content

Commit d292db5

Browse files
authored
Merge pull request #6 from dhruvpathak1/cursor/live-10s-parallel-transcribe-pipeline
Live pipeline, Pages deploy, Docker compose image
2 parents a6d595e + 1a42312 commit d292db5

5 files changed

Lines changed: 144 additions & 0 deletions

File tree

.dockerignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.git
2+
.github
3+
node_modules
4+
venv
5+
.venv
6+
dist
7+
**/__pycache__
8+
**/*.pyc
9+
.env
10+
.env.*
11+
!.env.example
12+
server/transcripts
13+
server/entity_exports
14+
server/whisper_models
15+
server/torch_home
16+
adhoc
17+
*.md
18+
!DOCKER.md
19+
.DS_Store

DOCKER.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Run PodLens with Docker
2+
3+
One container serves the **built React UI** and the **FastAPI** backend (Whisper, NER, enrichment).
4+
5+
## Quick start
6+
7+
```bash
8+
docker compose up --build
9+
```
10+
11+
Open **http://localhost:8080**. The first transcription downloads the Whisper model — expect a long delay and **several GB** of disk/RAM (CPU image).
12+
13+
## Optional configuration
14+
15+
- Copy `.env.example` to `.env` next to `docker-compose.yml` and fill in keys. Docker Compose reads that file for `${VAR}` substitution and forwards common variables into the container.
16+
- Override CORS for another browser origin:
17+
`CORS_EXTRA_ORIGINS=https://example.com docker compose up`
18+
19+
## Share with others
20+
21+
1. **Same LAN**: expose port `8080` (or change the mapping in `docker-compose.yml`) and share your machine IP.
22+
2. **Internet**: run the same compose stack on a small VPS, open firewall port **8080** (or put **nginx + HTTPS** in front).
23+
3. **Publish an image** (GitHub Container Registry example):
24+
25+
```bash
26+
docker build -t ghcr.io/YOUR_USER/podlens:latest .
27+
docker push ghcr.io/YOUR_USER/podlens:latest
28+
```
29+
30+
Others run:
31+
32+
```bash
33+
docker run --rm -p 8080:8000 -v podlens-data:/data ghcr.io/YOUR_USER/podlens:latest
34+
```
35+
36+
## GPU (optional)
37+
38+
The default image uses **CPU** Whisper. For NVIDIA GPUs you’d extend the Dockerfile with CUDA base images and compatible PyTorch wheels; not included here to keep the shareable image simple.
39+
40+
## Troubleshooting
41+
42+
- **`docker compose` fails during `pip install`**: ensure the build has network access; `server/requirements.txt` installs spaCy and downloads models.
43+
- **Container exits / OOM**: Whisper + PyTorch need RAM; try `WHISPER_MODEL=tiny` in `.env` for a smaller model.

Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# syntax=docker/dockerfile:1
2+
# PodLens: React SPA (built) + FastAPI (Whisper, entities, enrichment).
3+
4+
FROM node:22-bookworm-slim AS frontend
5+
WORKDIR /build
6+
COPY package.json package-lock.json ./
7+
RUN npm ci
8+
COPY tsconfig.json tsconfig.app.json tsconfig.node.json vite.config.ts index.html ./
9+
COPY public ./public
10+
COPY src ./src
11+
# Same-origin /api/* in the browser — no VITE_TRANSCRIBE_URL needed.
12+
RUN npm run build
13+
14+
FROM python:3.11-slim-bookworm
15+
16+
RUN apt-get update \
17+
&& apt-get install -y --no-install-recommends ffmpeg \
18+
&& rm -rf /var/lib/apt/lists/*
19+
20+
WORKDIR /app
21+
22+
COPY server/requirements.txt ./server/requirements.txt
23+
24+
RUN pip install --no-cache-dir --upgrade pip \
25+
&& pip install --no-cache-dir openai-whisper \
26+
&& pip install --no-cache-dir -r server/requirements.txt
27+
28+
COPY server ./server
29+
COPY --from=frontend /build/dist ./server/static
30+
31+
ENV PYTHONUNBUFFERED=1 \
32+
STATIC_DIST_DIR=/app/server/static \
33+
WHISPER_DOWNLOAD_ROOT=/data/whisper_models \
34+
TORCH_HOME=/data/torch_home \
35+
TRANSCRIPTS_DIR=/data/transcripts \
36+
ENTITY_JSON_DIR=/data/entity_exports
37+
38+
RUN mkdir -p /data/whisper_models /data/torch_home /data/transcripts /data/entity_exports
39+
40+
WORKDIR /app/server
41+
42+
EXPOSE 8000
43+
44+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

docker-compose.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# PodLens — run UI + API together (single container).
2+
#
3+
# docker compose up --build
4+
# Open http://localhost:8080
5+
#
6+
# Optional: copy `.env.example` → `.env` in this folder. Compose reads `.env` for
7+
# variable substitution and passes the values below into the container.
8+
9+
services:
10+
podlens:
11+
build: .
12+
ports:
13+
- "8080:8000"
14+
environment:
15+
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
16+
UNSPLASH_ACCESS_KEY: ${UNSPLASH_ACCESS_KEY:-}
17+
UNSPLASH_SECRET_KEY: ${UNSPLASH_SECRET_KEY:-}
18+
ENTITY_BACKEND: ${ENTITY_BACKEND:-}
19+
SPACY_MODEL: ${SPACY_MODEL:-}
20+
WHISPER_MODEL: ${WHISPER_MODEL:-base}
21+
CLAUDE_MODEL: ${CLAUDE_MODEL:-}
22+
CLAUDE_ENTITY_BATCH: ${CLAUDE_ENTITY_BATCH:-}
23+
NOMINATIM_USER_AGENT: ${NOMINATIM_USER_AGENT:-}
24+
CORS_EXTRA_ORIGINS: ${CORS_EXTRA_ORIGINS:-http://localhost:8080,http://127.0.0.1:8080}
25+
volumes:
26+
- podlens-data:/data
27+
28+
volumes:
29+
podlens-data:

server/main.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,3 +483,12 @@ def health():
483483
"entity_backend": resolve_entity_backend(None),
484484
"unsplash_configured": uk,
485485
}
486+
487+
488+
_static_dir_raw = os.environ.get("STATIC_DIST_DIR", "").strip()
489+
if _static_dir_raw:
490+
_static_dir = Path(_static_dir_raw)
491+
if _static_dir.is_dir():
492+
from fastapi.staticfiles import StaticFiles
493+
494+
app.mount("/", StaticFiles(directory=str(_static_dir), html=True), name="spa")

0 commit comments

Comments
 (0)