Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,24 @@ The RAG retrieval service runs as a **separate Hugging Face Space** to keep the

### Enable remote RAG in your environment



### Render Deployment (3 services)

```bash
# Verify deployed services
export RENDER_API_URL=https://codesec-api.onrender.com
export RENDER_DASHBOARD_URL=https://codesec-dashboard.onrender.com
export RENDER_REVIEW_UI_URL=https://codesec-review-ui.onrender.com
python scripts/check_render_deployment.py
```

Render blueprint: `render.yaml`

Full instructions: [docs/render_deployment.md](docs/render_deployment.md)

See also [docs/deployment_strategy.md](docs/deployment_strategy.md) for the full multi-environment plan.
=======
```env
CODESEC_ENABLE_RAG=true
CODESEC_RAG_MODE=remote
Expand Down
17 changes: 17 additions & 0 deletions deploy/render/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Render Deployment

These files configure CodeSecAudit AI for deployment on Render.

## Services

| Service | Dockerfile | Start Script | Purpose |
|---|---|---|---|
| API | `api.Dockerfile` | `api_start.sh` | FastAPI review + history endpoints |
| Dashboard | `dashboard.Dockerfile` | `dashboard_start.sh` | Streamlit analytics dashboard |
| Review UI | `review-ui.Dockerfile` | `review_ui_start.sh` | Streamlit review interface |

## Blueprint

The root `render.yaml` defines all three services as a blueprint group.

See [docs/render_deployment.md](../../docs/render_deployment.md) for full instructions.
19 changes: 19 additions & 0 deletions deploy/render/api.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml .
COPY config/ config/
COPY review_engine/ review_engine/
COPY review_store/ review_store/
COPY api/ api/

RUN pip install --no-cache-dir -e ".[api]" && \
rm -rf /root/.cache

COPY deploy/render/api_start.sh /api_start.sh
RUN chmod +x /api_start.sh

EXPOSE 8003

CMD ["/api_start.sh"]
3 changes: 3 additions & 0 deletions deploy/render/api_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -e
uvicorn api.main:app --host 0.0.0.0 --port "${PORT:-8003}"
16 changes: 16 additions & 0 deletions deploy/render/dashboard.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml .
COPY ui/dashboard.py ui/dashboard.py

RUN pip install --no-cache-dir -e ".[ui]" && \
rm -rf /root/.cache

COPY deploy/render/dashboard_start.sh /dashboard_start.sh
RUN chmod +x /dashboard_start.sh

EXPOSE 8502

CMD ["/dashboard_start.sh"]
3 changes: 3 additions & 0 deletions deploy/render/dashboard_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -e
streamlit run ui/dashboard.py --server.address 0.0.0.0 --server.port "${PORT:-8502}" --server.headless true
16 changes: 16 additions & 0 deletions deploy/render/review-ui.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml .
COPY ui/app.py ui/app.py

RUN pip install --no-cache-dir -e ".[ui]" && \
rm -rf /root/.cache

COPY deploy/render/review_ui_start.sh /review_ui_start.sh
RUN chmod +x /review_ui_start.sh

EXPOSE 8501

CMD ["/review_ui_start.sh"]
3 changes: 3 additions & 0 deletions deploy/render/review_ui_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -e
streamlit run ui/app.py --server.address 0.0.0.0 --server.port "${PORT:-8501}" --server.headless true
153 changes: 153 additions & 0 deletions docs/render_deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Render Deployment

Deploy CodeSecAudit AI on Render with three services: API, Dashboard, and Review UI.

The RAG retrieval service remains on Hugging Face Space (already deployed at `https://OMCHOKSI108-codereview-agent.hf.space`).

## Option A: Blueprint Deploy (Recommended)

1. Push the repository to GitHub.
2. Log in to [Render Dashboard](https://dashboard.render.com).
3. Click **New → Blueprint**.
4. Select your repository (`OMCHOKSI108/codesec-audit-dataset`).
5. Render reads `render.yaml` and creates three services:

| Service | Name | Purpose |
|---|---|---|
| API | `codesec-api` | FastAPI review + history endpoints |
| Dashboard | `codesec-dashboard` | Streamlit analytics dashboard |
| Review UI | `codesec-review-ui` | Streamlit review interface |

6. **Add the secret** `CODESEC_RAG_API_KEY` in the Render dashboard for `codesec-api` (under Environment → Secret Files). This is the API key shared with the HF Space RAG service.
7. **Update** `CODESEC_API_URL` on `codesec-dashboard` and `codesec-review-ui` to the actual URL of your deployed API service (e.g., `https://codesec-api.onrender.com`). This is set automatically by the blueprint but may need a suffix if the URL differs.
8. Click **Apply** and wait for the build (~3-5 min per service).

## Option B: Manual Service Creation

### 1. Create the API Service

| Setting | Value |
|---|---|
| **Type** | Web Service |
| **Name** | `codesec-api` |
| **Environment** | Docker |
| **Dockerfile Path** | `deploy/render/api.Dockerfile` |
| **Plan** | Free |
| **Health Check Path** | `/health` |

**Required env vars**:

```env
APP_ENV=production
CODESEC_ENABLE_RAG=true
CODESEC_RAG_MODE=remote
CODESEC_RAG_SERVICE_URL=https://OMCHOKSI108-codereview-agent.hf.space
CODESEC_RAG_API_KEY=<secret>
CODESEC_DEFAULT_TOP_K=3
DATABASE_BACKEND=sqlite
CODESEC_DB_PATH=/tmp/reviews.db
OWNER_CONTACT_EMAIL=omchoksi108@gmail.com
```

`CODESEC_RAG_API_KEY` must be set as a **secret** (not plain text). It must match the `RAG_API_KEY` set on the Hugging Face Space.

### 2. Create the Dashboard Service

| Setting | Value |
|---|---|
| **Type** | Web Service |
| **Name** | `codesec-dashboard` |
| **Environment** | Docker |
| **Dockerfile Path** | `deploy/render/dashboard.Dockerfile` |
| **Plan** | Free |

**Required env vars**:

```env
CODESEC_API_URL=https://codesec-api.onrender.com
```

Replace with your actual API URL after the API service deploys.

### 3. Create the Review UI Service

| Setting | Value |
|---|---|
| **Type** | Web Service |
| **Name** | `codesec-review-ui` |
| **Environment** | Docker |
| **Dockerfile Path** | `deploy/render/review-ui.Dockerfile` |
| **Plan** | Free |

**Required env vars**:

```env
CODESEC_API_URL=https://codesec-api.onrender.com
```

## Verify Deployment

After all services deploy, run the smoke test:

```bash
export RENDER_API_URL=https://codesec-api.onrender.com
export RENDER_DASHBOARD_URL=https://codesec-dashboard.onrender.com
export RENDER_REVIEW_UI_URL=https://codesec-review-ui.onrender.com

python scripts/check_render_deployment.py
```

Expected output:

```
[1/6] API /health .................... PASS
[2/6] API / .......................... PASS
[3/6] API /review/code ............... PASS
[4/6] API /stats ..................... PASS
[5/6] Dashboard URL .................. PASS
[6/6] Review UI URL .................. PASS
All checks passed.
```

## Architecture

```text
┌─────────────────────────────┐
│ Hugging Face Space │
│ codesec-rag-service │
│ /rag/search (RAG index) │
│ 2,833 OWASP chunks │
└──────────┬──────────────────┘
│ HTTP (outbound from Render)
┌─────────────────────────────┐
│ Render — codesec-api │
│ FastAPI review + history │
│ SQLite at /tmp/reviews.db │
│ Health: /health │
└──────────┬──────────────────┘
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ Dashboard│ │Review UI│
│streamlit │ │streamlit│
└──────────┘ └─────────┘
```

## Known Limitations on Render Free

| Limitation | Impact | Mitigation |
|---|---|---|
| **Spin-down after inactivity** | First request after idle period takes 30-60s | Set up external uptime monitor (e.g., UptimeRobot, cron-job.org) |
| **Ephemeral filesystem** | SQLite DB (`/tmp/reviews.db`) resets on each deploy or restart | Migrate to MongoDB Atlas for production persistence |
| **512 MB RAM** | May limit concurrent request handling | Rule-based engine is lightweight (~100 MB idle) |
| **No cron jobs on free** | Cannot run periodic tasks | Use external cron services if needed |

## Production Readiness Next Steps

1. **MongoDB Atlas** — Replace SQLite with MongoDB for persistent review storage.
2. **Resend Email** — Set `RESEND_API_KEY` and enable email workflows.
3. **GitHub App** — Register a GitHub App and set `GITHUB_*` env vars.
4. **Custom Domain** — Add a custom domain in Render dashboard.
5. **Paid Plan** — Upgrade from free to starter/individual for no spin-down.
44 changes: 44 additions & 0 deletions render.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
services:
- type: web
name: codesec-api
env: docker
dockerfilePath: deploy/render/api.Dockerfile
plan: free
healthCheckPath: /health
envVars:
- key: APP_ENV
value: production
- key: CODESEC_ENABLE_RAG
value: "true"
- key: CODESEC_RAG_MODE
value: remote
- key: CODESEC_RAG_SERVICE_URL
value: https://OMCHOKSI108-codereview-agent.hf.space
- key: CODESEC_DEFAULT_TOP_K
value: "3"
- key: DATABASE_BACKEND
value: sqlite
- key: CODESEC_DB_PATH
value: /tmp/reviews.db
- key: OWNER_CONTACT_EMAIL
value: omchoksi108@gmail.com
- key: CODESEC_RAG_API_KEY
sync: false

- type: web
name: codesec-dashboard
env: docker
dockerfilePath: deploy/render/dashboard.Dockerfile
plan: free
envVars:
- key: CODESEC_API_URL
value: https://codesec-api.onrender.com

- type: web
name: codesec-review-ui
env: docker
dockerfilePath: deploy/render/review-ui.Dockerfile
plan: free
envVars:
- key: CODESEC_API_URL
value: https://codesec-api.onrender.com
Loading
Loading