Merge pull request #2 from coder3101/add-dockerfile

feat: Add Dockerfile and compose with usage instructions
This commit is contained in:
Extraltodeus
2026-07-15 19:07:11 +02:00
committed by GitHub
4 changed files with 124 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
# ── J-Wash Docker image ──────────────────────────────────────────────────────
# Requires an NVIDIA GPU with CUDA 12.4+ drivers on the host.
# docker build -t j-wash .
# docker run --gpus all -p 8381:8381 -v ./data:/app/data -v ./hf_cache:/app/hf_cache j-wash
FROM nvidia/cuda:12.4.1-runtime-ubuntu22.04 AS base
SHELL ["/bin/bash", "-c"]
RUN apt-get update && apt-get install -y --no-install-recommends \
python3.11 python3.11-dev python3-pip python3.11-venv \
git curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
RUN python3.11 -m venv /venv
ENV PATH="/venv/bin:$PATH"
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cu124
RUN git clone https://github.com/anthropics/jacobian-lens vendor/jacobian-lens \
&& pip install -e vendor/jacobian-lens
RUN pip install --no-cache-dir -r requirements.txt
COPY ui/package.json ui/package-lock.json ui/
RUN cd ui && npm ci
COPY . .
RUN cd ui && npm run build
ENV HF_HOME=/app/hf_cache
ENV JWASH_DATA_DIR=/app/data
EXPOSE 8381
VOLUME ["/app/data", "/app/hf_cache", "/app/lenses"]
ENTRYPOINT ["python3.11", "-X", "utf8", "run.py", "--host", "0.0.0.0"]
+47
View File
@@ -46,6 +46,8 @@ Requirements:
- Python 3.11+
- Node.js 18+
### Native
```bash
git clone https://github.com/extraltodeus/j-wash.git
cd j-wash
@@ -63,6 +65,51 @@ python -X utf8 run.py
Then open **http://localhost:8381**.
### Docker
Requirements:
- NVIDIA GPU with CUDA 12.4+ drivers
- [Docker](https://docs.docker.com/engine/install/) with the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
```bash
# Build the image
docker build -t j-wash .
# Run (data and HF cache persist on the host)
docker run --gpus all \
-p 8381:8381 \
-v ./data:/app/data \
-v ./hf_cache:/app/hf_cache \
-v ./lenses:/app/lenses \
j-wash
```
Or use Docker Compose:
```bash
docker compose up -d
```
The container binds to `0.0.0.0` by default so the UI is reachable from outside
the container. Pass additional arguments (e.g. `--port`, `--host`) after the image
name:
```bash
docker run --gpus all -p 8381:8381 j-wash --port 8381 --host 0.0.0.0
```
Set `HF_TOKEN` for gated/private models:
```bash
docker run --gpus all -p 8381:8381 -e HF_TOKEN=hf_your_token j-wash
# or with docker-compose:
# HF_TOKEN=hf_your_token docker compose up -d
```
> **Note**: The Docker image includes the `jacobian-lens` library and pre-builds the
> React front-end at build time. Model weights are downloaded at runtime into the
> mounted `hf_cache` volume (shared with the host).
## Running
+24
View File
@@ -0,0 +1,24 @@
services:
j-wash:
build: .
image: j-wash
container_name: j-wash
restart: unless-stopped
ports:
- "8381:8381"
volumes:
- ./data:/app/data
- ./hf_cache:/app/hf_cache
- ./lenses:/app/lenses
environment:
- JWASH_HOST=0.0.0.0
- HF_HOME=/app/hf_cache
- JWASH_DATA_DIR=/app/data
- HF_TOKEN=${HF_TOKEN:-}
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
+6 -1
View File
@@ -18,6 +18,10 @@ def main():
"Default: ./data. Give each instance its own when running several "
"servers side by side.",
)
parser.add_argument(
"--host", default=None,
help="Bind address (default: 127.0.0.1). Use 0.0.0.0 for Docker.",
)
parser.add_argument(
"--port", type=int, default=None,
help="HTTP port (default: 8381). Use a distinct port per instance.",
@@ -49,7 +53,8 @@ def main():
import uvicorn
uvicorn.run("api.app:app", host=config.HOST, port=args.port or config.PORT, log_level="info")
host = args.host or os.environ.get("JWASH_HOST") or config.HOST
uvicorn.run("api.app:app", host=host, port=args.port or config.PORT, log_level="info")
if __name__ == "__main__":