diff --git a/.gitignore b/.gitignore index 268a0ff..1515bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ frontend/release/ # Local Claude Code instructions CLAUDE.md -*temp/ \ No newline at end of file +*temp/ +*.env* \ No newline at end of file diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..c4321ac --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,27 @@ +# Copy this file to .env.dev or .env.prod and fill in values. +# Never commit .env.dev or .env.prod — they are gitignored. + +# --- App ------------------------------------------------------------------ +APP_PORT=8000 + +# --- Ollama --------------------------------------------------------------- +# Ollama runs in Docker with port mapped to host. App runs on host. +# Override to point at an external Ollama instance (e.g. a GPU server). +OLLAMA_HOST=http://localhost:11434 +OLLAMA_MODEL=qwen2.5:1.5b +OLLAMA_TIMEOUT=300 + +# --- Whisper -------------------------------------------------------------- +# Whisper runs in Docker with port mapped to host. App runs on host. +# Override to point at an external Whisper endpoint. +WHISPER_HOST=http://localhost:9000 +WHISPER_MODEL=small.en + +# --- Gunicorn (prod only) ------------------------------------------------- +GUNICORN_WORKERS=2 + +# --- CORS ----------------------------------------------------------------- +# Comma-separated list of allowed frontend origins. +# Dev: http://localhost:5173,http://127.0.0.1:5173 +# Prod: https://your-domain.com +FRONTEND_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..e238c64 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,31 @@ +# Docker + +``` +docker/ + dev/ + Dockerfile # uvicorn --reload, source-mounted for hot reload + compose.yml + prod/ + Dockerfile # multi-stage build, gunicorn, no source mount + compose.yml + .env.example # template — copy to .env.dev or .env.prod + .env.dev # gitignored, dev values + .env.prod # gitignored, prod values + entrypoint.sh # runs DB migrations then exec's the server command + README.md +``` + +## Env vars + +See `.env.example` for the full list with descriptions. + +## Volumes + +`docker compose down` never removes volumes. Use `docker compose down -v` only to intentionally wipe all data. + +| Volume | Path in container | Purpose | +| ------------------ | ---------------------- | ----------------------------------- | +| `fireform_db` | `/data/db/fireform.db` | SQLite database | +| `fireform_uploads` | `/data/uploads` | Uploaded templates + generated PDFs | +| `ollama_data` | `/root/.ollama` | Ollama model weights | +| `whisper_models` | `/data/whisper` | Whisper model cache | diff --git a/docker/dev/compose.yml b/docker/dev/compose.yml index 5b7c2f0..cdb94cc 100644 --- a/docker/dev/compose.yml +++ b/docker/dev/compose.yml @@ -45,6 +45,7 @@ services: condition: service_healthy whisper: condition: service_started + entrypoint: ["sh", "docker/entrypoint.sh"] command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] volumes: - ../..:/app diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 0000000..84a8142 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +# Ensure data directories exist (volumes may be empty on first run) +mkdir -p /data/db /data/uploads + +# Run DB migrations / init before starting the server +python3 -m app.db.init_db + +exec "$@" diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 8ad8dea..f97d6dd 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -22,6 +22,7 @@ COPY --from=builder /install /usr/local # Copy only app code, not data/ temp/ tests/ docs/ etc. COPY app/ ./app/ COPY requirements.txt . +COPY docker/entrypoint.sh /entrypoint.sh ENV PYTHONPATH=/app @@ -30,6 +31,7 @@ RUN mkdir -p /data/db /data/uploads && chmod +x /entrypoint.sh EXPOSE 8000 +ENTRYPOINT ["/entrypoint.sh"] CMD ["gunicorn", "app.main:app", \ "--worker-class", "uvicorn.workers.UvicornWorker", \ "--bind", "0.0.0.0:8000", \