Skip to content

Commit 6a675ad

Browse files
Add Docker support and auto-start web UI from repowise serve
- repowise serve now auto-downloads and starts the web frontend if Node.js is available. Frontend cached in ~/.repowise/web/ (~50 MB, one-time). - Added --ui-port and --no-ui flags to serve command - Added Dockerfile (multi-stage: Node.js build + Python runtime) - Added docker-compose.yml and entrypoint.sh - Updated publish workflow to build web UI tarball and create GitHub releases - Updated README, Quickstart, and User Guide with simplified instructions
1 parent de13ae9 commit 6a675ad

10 files changed

Lines changed: 694 additions & 95 deletions

File tree

.dockerignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Git
2+
.git
3+
.gitignore
4+
5+
# Python
6+
__pycache__
7+
*.pyc
8+
*.pyo
9+
*.egg-info
10+
.venv
11+
venv
12+
.mypy_cache
13+
.ruff_cache
14+
.pytest_cache
15+
htmlcov
16+
dist
17+
build
18+
19+
# Node
20+
node_modules
21+
packages/web/.next
22+
packages/web/out
23+
24+
# Runtime data
25+
.repowise
26+
*.db
27+
*.db-shm
28+
*.db-wal
29+
lancedb
30+
31+
# IDE
32+
.idea
33+
.vscode
34+
*.swp
35+
36+
# Docker
37+
docker-compose.override.yml
38+
39+
# Docs (not needed in image)
40+
docs/
41+
tests/

.github/workflows/publish.yml

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,54 @@ on:
55
tags: ['v*']
66

77
permissions:
8-
contents: read
8+
contents: write # needed for creating GitHub releases
99

1010
jobs:
11-
build:
12-
name: Build distribution
11+
# ---------------------------------------------------------------------------
12+
# Build the Next.js frontend as a standalone tarball
13+
# ---------------------------------------------------------------------------
14+
build-web:
15+
name: Build Web UI
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Set up Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: "20"
25+
cache: "npm"
26+
cache-dependency-path: packages/web/package-lock.json
27+
28+
- name: Install dependencies
29+
run: cd packages/web && npm install
30+
31+
- name: Build Next.js (standalone)
32+
run: cd packages/web && npm run build
33+
env:
34+
NEXT_PUBLIC_REPOWISE_API_URL: ""
35+
36+
- name: Package standalone output
37+
run: |
38+
cd packages/web/.next/standalone
39+
# Copy static files into standalone (Next.js requirement)
40+
cp -r ../../.next/static .next/static
41+
[ -d ../../public ] && cp -r ../../public public || true
42+
# Create tarball
43+
tar -czf /tmp/repowise-web.tar.gz .
44+
45+
- name: Upload web artifact
46+
uses: actions/upload-artifact@v4
47+
with:
48+
name: repowise-web
49+
path: /tmp/repowise-web.tar.gz
50+
51+
# ---------------------------------------------------------------------------
52+
# Build the Python package
53+
# ---------------------------------------------------------------------------
54+
build-python:
55+
name: Build Python package
1356
runs-on: ubuntu-latest
1457

1558
steps:
@@ -32,9 +75,41 @@ jobs:
3275
name: dist
3376
path: dist/
3477

78+
# ---------------------------------------------------------------------------
79+
# Create GitHub release with web UI tarball
80+
# ---------------------------------------------------------------------------
81+
release:
82+
name: Create GitHub Release
83+
needs: [build-web, build-python]
84+
runs-on: ubuntu-latest
85+
86+
steps:
87+
- name: Download web artifact
88+
uses: actions/download-artifact@v4
89+
with:
90+
name: repowise-web
91+
path: ./artifacts/
92+
93+
- name: Download Python dist
94+
uses: actions/download-artifact@v4
95+
with:
96+
name: dist
97+
path: ./dist/
98+
99+
- name: Create release
100+
uses: softprops/action-gh-release@v2
101+
with:
102+
files: |
103+
artifacts/repowise-web.tar.gz
104+
dist/*
105+
generate_release_notes: true
106+
107+
# ---------------------------------------------------------------------------
108+
# Publish to PyPI
109+
# ---------------------------------------------------------------------------
35110
publish:
36111
name: Publish to PyPI
37-
needs: build
112+
needs: build-python
38113
runs-on: ubuntu-latest
39114
environment: pypi
40115
permissions:

Dockerfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# =============================================================================
2+
# repowise — multi-stage Docker build (backend + frontend)
3+
# =============================================================================
4+
# Usage:
5+
# docker build -t repowise .
6+
# docker run -p 7337:7337 -p 3000:3000 -v /path/to/repo/.repowise:/data -e GEMINI_API_KEY=... repowise
7+
# =============================================================================
8+
9+
# ---------------------------------------------------------------------------
10+
# Stage 1: Build the Next.js frontend
11+
# ---------------------------------------------------------------------------
12+
FROM node:20-alpine AS frontend-builder
13+
14+
WORKDIR /app
15+
16+
# Install dependencies first (cached layer)
17+
COPY packages/web/package.json packages/web/package-lock.json* ./
18+
RUN npm install --production=false
19+
20+
# Copy source and build
21+
COPY packages/web/ ./
22+
ENV NEXT_TELEMETRY_DISABLED=1
23+
ENV NEXT_PUBLIC_REPOWISE_API_URL=http://localhost:7337
24+
RUN npm run build
25+
26+
# ---------------------------------------------------------------------------
27+
# Stage 2: Python backend + frontend runtime
28+
# ---------------------------------------------------------------------------
29+
FROM python:3.12-slim AS runtime
30+
31+
# Install git (required by gitpython) and Node.js (required for Next.js server)
32+
RUN apt-get update && apt-get install -y --no-install-recommends \
33+
git \
34+
curl \
35+
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
36+
&& apt-get install -y --no-install-recommends nodejs \
37+
&& rm -rf /var/lib/apt/lists/*
38+
39+
WORKDIR /app
40+
41+
# Install repowise Python package
42+
COPY pyproject.toml README.md LICENSE MANIFEST.in ./
43+
COPY packages/core/ packages/core/
44+
COPY packages/cli/ packages/cli/
45+
COPY packages/server/ packages/server/
46+
RUN pip install --no-cache-dir ".[all]"
47+
48+
# Copy built Next.js standalone output
49+
COPY --from=frontend-builder /app/.next/standalone /app/web
50+
COPY --from=frontend-builder /app/.next/static /app/web/.next/static
51+
COPY --from=frontend-builder /app/public /app/web/public 2>/dev/null || true
52+
53+
# Data volume for .repowise directory
54+
VOLUME /data
55+
56+
# Environment defaults
57+
ENV REPOWISE_DB_URL=sqlite+aiosqlite:///data/wiki.db
58+
ENV REPOWISE_EMBEDDER=mock
59+
ENV PORT_BACKEND=7337
60+
ENV PORT_FRONTEND=3000
61+
ENV HOSTNAME=0.0.0.0
62+
63+
# Expose both ports
64+
EXPOSE 7337 3000
65+
66+
# Startup script
67+
COPY docker/entrypoint.sh /app/entrypoint.sh
68+
RUN chmod +x /app/entrypoint.sh
69+
70+
ENTRYPOINT ["/app/entrypoint.sh"]

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,23 @@ repowise includes a full web dashboard (Next.js + React + D3.js) with:
115115
- **Dead code finder** — unused code with confidence scores and bulk actions
116116
- **Decision tracker** — architectural decisions with health monitoring
117117

118-
See the [User Guide](https://github.com/RaghavChamadiya/repowise/blob/main/docs/USER_GUIDE.md#web-ui) for setup instructions.
118+
**Starts automatically with `repowise serve`** if Node.js 20+ is installed. No separate setup — the frontend is downloaded and cached on first run.
119+
120+
No Node.js? Use Docker instead:
121+
122+
```bash
123+
docker build -t repowise https://github.com/RaghavChamadiya/repowise.git
124+
docker run -p 7337:7337 -p 3000:3000 -v .repowise:/data repowise
125+
```
126+
127+
See the [User Guide](https://github.com/RaghavChamadiya/repowise/blob/main/docs/USER_GUIDE.md#web-ui) for more options.
119128

120129
## Requirements
121130

122131
- Python 3.11+
123132
- Git (for repository analysis)
124133
- An LLM API key (for documentation generation — not needed for analysis-only mode)
125-
- Node.js 20+ (only if running the web UI frontend)
134+
- Node.js 20+ or Docker (optional, for the web UI)
126135

127136
## Documentation
128137

docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
repowise:
3+
build: .
4+
ports:
5+
- "7337:7337" # API
6+
- "3000:3000" # Web UI
7+
volumes:
8+
# Mount the .repowise directory from your indexed repo
9+
- ${REPOWISE_DATA:-./data}:/data
10+
environment:
11+
- REPOWISE_DB_URL=sqlite+aiosqlite:///data/wiki.db
12+
- REPOWISE_EMBEDDER=${REPOWISE_EMBEDDER:-mock}
13+
# Set your LLM provider API key
14+
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
15+
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
16+
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
17+
restart: unless-stopped

docker/README.md

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,45 @@
11
# Docker
22

3-
> Built in Phase 9. Placeholder file.
3+
Run the full repowise stack (API + Web UI) in a single container.
44

5-
The multi-stage Dockerfile and docker-compose.yml will be implemented in Phase 9.
6-
See `BUILD_STATUS.md` for current status.
5+
## Prerequisites
6+
7+
- Docker installed
8+
- A repository already indexed with `repowise init` (the `.repowise/` directory exists)
9+
10+
## Quick Start
11+
12+
```bash
13+
docker build -t repowise .
14+
15+
# Run with a mounted .repowise directory
16+
docker run -p 7337:7337 -p 3000:3000 \
17+
-v /path/to/your-repo/.repowise:/data \
18+
-e GEMINI_API_KEY=your-key \
19+
-e REPOWISE_EMBEDDER=gemini \
20+
repowise
21+
```
22+
23+
Open http://localhost:3000 for the Web UI, http://localhost:7337 for the API.
24+
25+
## Docker Compose
26+
27+
```bash
28+
# Set the path to your .repowise directory
29+
export REPOWISE_DATA=/path/to/your-repo/.repowise
30+
export GEMINI_API_KEY=your-key
31+
32+
docker compose up
33+
```
34+
35+
## Environment Variables
36+
37+
| Variable | Default | Description |
38+
|----------|---------|-------------|
39+
| `REPOWISE_DB_URL` | `sqlite+aiosqlite:///data/wiki.db` | Database URL |
40+
| `REPOWISE_EMBEDDER` | `mock` | Embedder: `gemini`, `openai`, `mock` |
41+
| `ANTHROPIC_API_KEY` || Anthropic API key (for chat) |
42+
| `OPENAI_API_KEY` || OpenAI API key (for chat) |
43+
| `GEMINI_API_KEY` || Gemini API key (for chat + embeddings) |
44+
| `PORT_BACKEND` | `7337` | API server port |
45+
| `PORT_FRONTEND` | `3000` | Web UI port |

docker/entrypoint.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Start the FastAPI backend
5+
echo "Starting repowise API server on port ${PORT_BACKEND}..."
6+
uvicorn repowise.server.app:create_app \
7+
--factory \
8+
--host 0.0.0.0 \
9+
--port "${PORT_BACKEND}" &
10+
11+
# Start the Next.js frontend
12+
echo "Starting repowise Web UI on port ${PORT_FRONTEND}..."
13+
cd /app/web
14+
REPOWISE_API_URL="http://localhost:${PORT_BACKEND}" \
15+
HOSTNAME="0.0.0.0" \
16+
PORT="${PORT_FRONTEND}" \
17+
node server.js &
18+
19+
# Wait for either process to exit
20+
wait -n
21+
exit $?

0 commit comments

Comments
 (0)