diff --git a/.github/workflows/docker-image-verify.yml b/.github/workflows/docker-image-verify.yml index fec67707..3d162675 100644 --- a/.github/workflows/docker-image-verify.yml +++ b/.github/workflows/docker-image-verify.yml @@ -23,6 +23,10 @@ on: - 'frontend/**' - 'scripts/build_frontend.sh' - 'deployment/docker-compose-standalone.yaml' + - 'docsgpt/deploy/**' + - 'docsgpt/cli.py' + - 'docsgpt/core/paths.py' + - 'pyproject.toml' - '.github/workflows/docker-image-verify.yml' permissions: @@ -94,6 +98,32 @@ jobs: curl -fsS "$base/settings" | grep -q 'src="/config.js"' echo "API and UI served on $base" + - name: Set up uv + if: matrix.variant == '' + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0 + + - name: docsgpt up runs the same image from the installed package + if: matrix.variant == '' + run: | + set -euo pipefail + # Same Compose project name as the step above; stop that stack first. + docker compose -f deployment/docker-compose-standalone.yaml down -v + uv build --wheel --out-dir "$RUNNER_TEMP/dist" + uv venv "$RUNNER_TEMP/venv" + uv pip install --python "$RUNNER_TEMP/venv/bin/python" "$RUNNER_TEMP"/dist/*.whl + docsgpt="$RUNNER_TEMP/venv/bin/docsgpt" + stack="$RUNNER_TEMP/stack" + "$docsgpt" up --yes --dir "$stack" --image-tag verify + "$docsgpt" status --dir "$stack" + curl -fsS http://127.0.0.1:7091/ | grep -q 'src="/config.js"' + grep -q '^POSTGRES_PASSWORD=' "$stack/.env" + # Running up again keeps the generated secrets. + before=$(grep '^JWT_SECRET_KEY=' "$stack/.env") + "$docsgpt" up --yes --dir "$stack" --image-tag verify + [ "$(grep '^JWT_SECRET_KEY=' "$stack/.env")" = "$before" ] + "$docsgpt" uninstall --yes --purge --dir "$stack" + test ! -e "$stack" + - name: Stack logs if: failure() env: diff --git a/deployment/docker-compose-standalone.yaml b/deployment/docker-compose-standalone.yaml index ca69253b..52d38d06 100644 --- a/deployment/docker-compose-standalone.yaml +++ b/deployment/docker-compose-standalone.yaml @@ -9,10 +9,11 @@ # the API; without it every ingest fails with a 401 (setup.sh generates one). # # The backend image serves the web UI and the API on one port. Every release -# also attaches this file as an asset. Settings come from .env next to this -# file (any DocsGPT setting, VITE_* included; the compose-internal service URLs -# below take precedence). Data lives in named volumes, so `docker compose down` -# keeps it and `docker compose down -v` removes it. +# also attaches this file as an asset, and `docsgpt up` runs it from the Python +# package. Settings come from .env next to this file (any DocsGPT setting, +# VITE_* included; the compose-internal service URLs below take precedence). +# Data lives in named volumes, so `docker compose down` keeps it and +# `docker compose down -v` removes it. # # DOCSGPT_IMAGE_TAG release to run, e.g. 0.20.0 (default: latest release); # develop follows the main branch @@ -55,6 +56,10 @@ services: - CACHE_REDIS_URL=redis://redis:6379/2 - POSTGRES_URI=postgresql://docsgpt:${POSTGRES_PASSWORD:-docsgpt}@postgres:5432/docsgpt - EMBEDDINGS_NAME=${EMBEDDINGS_NAME:-ibm-granite/granite-embedding-311m-multilingual-r2} + # A model server on the host (Ollama, vLLM, ...) is reachable as + # host.docker.internal on Linux too, as it is on Docker Desktop. + extra_hosts: + - "host.docker.internal:host-gateway" ports: - "${DOCSGPT_BIND:-127.0.0.1}:${DOCSGPT_PORT:-7091}:7091" volumes: @@ -84,6 +89,8 @@ services: - POSTGRES_URI=postgresql://docsgpt:${POSTGRES_PASSWORD:-docsgpt}@postgres:5432/docsgpt - API_URL=http://backend:7091 - EMBEDDINGS_NAME=${EMBEDDINGS_NAME:-ibm-granite/granite-embedding-311m-multilingual-r2} + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - indexes:/app/indexes - inputs:/app/inputs diff --git a/docs/content/Deploying/Docker-Deploying.mdx b/docs/content/Deploying/Docker-Deploying.mdx index b9e24c90..fdc91229 100644 --- a/docs/content/Deploying/Docker-Deploying.mdx +++ b/docs/content/Deploying/Docker-Deploying.mdx @@ -17,6 +17,58 @@ Docker is the recommended method for deploying DocsGPT, providing a consistent a **Important Note for Windows Users:** Docker Desktop on Windows generally requires the WSL 2 backend to function correctly, especially when using features like host networking which are utilized in DocsGPT's Docker Compose setup. Ensure WSL 2 is enabled and configured in Docker Desktop settings. +## Run it with `docsgpt up` + +The `docsgpt` Python package can set up and run the stack described below for +you. It needs Docker with Compose 2.24 or newer, and Python 3.12 or newer (uv +installs one when it is missing): + +```bash +uv tool install docsgpt # or: pipx install docsgpt +docsgpt up +``` + +`docsgpt up` keeps the stack in `~/.docsgpt/server` (`/opt/docsgpt` when run as +root on Linux; `--dir` or `DOCSGPT_HOME` choose another folder): the Compose +file of the installed version, a `.env` with your settings and the generated +secrets, and `install.json`. Data lives in named Docker volumes. The first run +asks two questions: + +- **Who should reach DocsGPT:** only this computer; other machines on the + network (plain HTTP, with `AUTH_TYPE=simple_jwt` and an access token); or a + domain name with HTTPS (Caddy gets the certificate, access token as well). +- **Which model provider:** the DocsGPT public API (no key needed), OpenAI, + Anthropic, Google Gemini, OpenRouter, Groq, or an OpenAI-compatible server + such as Ollama or vLLM. + +Flags answer the same questions, for scripts and servers: + +```bash +docsgpt up --yes --domain docs.example.com --provider openai --api-key "$OPENAI_API_KEY" +``` + +Running `docsgpt up` again is safe: it keeps `.env` and the secrets and runs +the images of the installed package version. `docsgpt up --reconfigure` asks +the questions again. + +| Command | What it does | +| --- | --- | +| `docsgpt status` | Version, address, containers, and whether the API answers | +| `docsgpt logs [-f] [service]` | Container logs | +| `docsgpt token` | The access token, for installs reachable beyond this computer | +| `docsgpt open` | Open DocsGPT in the browser | +| `docsgpt env set KEY=VALUE` | Change a setting; `docsgpt up` applies it | +| `docsgpt upgrade` | Upgrade the package (for `uv tool` installs) and restart on the new version | +| `docsgpt down` | Stop the stack; data and settings stay | +| `docsgpt uninstall [--purge]` | Remove the containers; `--purge` also deletes the settings and all data | + +More `docsgpt up` options: `--port`, `--docling` (the image with the docling +parser engine and OCR), `--image-tag develop` (follow the `main` branch) and +`--adopt` (manage a stack you started from the standalone Compose file in +another folder; both use the same data volumes). For Ollama on the same +machine, use the base URL `http://host.docker.internal:11434/v1`; on Linux, +also make Ollama listen beyond localhost (`OLLAMA_HOST=0.0.0.0`). + ## Quickest Setup: Pre-built Images, No Checkout Every release publishes ready-to-run images to Docker Hub (`arc53/docsgpt`, diff --git a/docs/content/Deploying/Pip-Install.mdx b/docs/content/Deploying/Pip-Install.mdx index ffe92c1d..1b946687 100644 --- a/docs/content/Deploying/Pip-Install.mdx +++ b/docs/content/Deploying/Pip-Install.mdx @@ -13,6 +13,10 @@ DocsGPT is on PyPI as [`docsgpt`](https://pypi.org/project/docsgpt/): the API se `docsgpt api` serves the web UI on the same port as the API. Set `SERVE_UI=false` to run the API alone, for example behind the frontend Docker image or a UI you host yourself. + + With Docker available, the same package can run the whole stack for you, including Postgres and Redis: `docsgpt up`. See [Run it with `docsgpt up`](/Deploying/Docker-Deploying#run-it-with-docsgpt-up). + + ## Requirements - Python 3.12 or newer @@ -49,7 +53,11 @@ pipx runpip docsgpt install --force-reinstall --no-deps --index-url https://down ## Configure -DocsGPT keeps its runtime files in a **data home**: the `.env` file it reads settings from, uploaded files under `inputs/`, vector indexes under `indexes/` and downloaded embedding models under `models/`. The data home is the directory you run the commands from, or the directory `DOCSGPT_HOME` points to. `DOCSGPT_ENV_FILE` points at a `.env` kept somewhere else. Both variables must be set in the process environment, not in `.env`: they decide where `.env` is read from. +DocsGPT keeps its runtime files in a **data home**: the `.env` file it reads settings from, uploaded files under `inputs/`, vector indexes under `indexes/` and downloaded embedding models under `models/`. The data home is `~/.docsgpt/server` (`/opt/docsgpt` when you run as root on Linux), whatever directory you run the commands from. `DOCSGPT_HOME` moves it, and `DOCSGPT_ENV_FILE` points at a `.env` kept somewhere else. Both variables must be set in the process environment, not in `.env`: they decide where `.env` is read from. In a source checkout the data home is the checkout. + + + Up to 0.20 the data home of an installed package was the directory you ran the command from. If you kept `.env` and your data there, move them to `~/.docsgpt/server` or set `DOCSGPT_HOME` to that directory. `docsgpt api` and `docsgpt worker` point out a `.env` in the working directory that they no longer read. + Create a `.env` in the data home. The minimum for a hosted LLM: @@ -80,7 +88,7 @@ docsgpt worker # in a second terminal: the Celery worker, with the scheduler The API applies pending migrations when it starts (`AUTO_MIGRATE`), so `docsgpt migrate` is the explicit step for deployments that want the schema in place before the first request or that run the API with a restricted database role. -Both commands print the data home they resolved on start-up. Run them from the same directory, or set `DOCSGPT_HOME` for both, so the worker finds the files the API stores and the API finds the indexes the worker builds. +Both commands print the data home they resolved on start-up. They share it as long as `DOCSGPT_HOME` is the same for both (or unset), so the worker finds the files the API stores and the API finds the indexes the worker builds. The worker is not optional: query embedding runs on it, so search fails without one. `docsgpt worker --help` lists the queue, concurrency and pool options; `--no-beat` starts a worker without the scheduler when another worker already runs it. On Windows the scheduler cannot be embedded, so run `docsgpt beat` in a third terminal. diff --git a/docs/content/changelog.mdx b/docs/content/changelog.mdx index 0aa9324a..a655b79a 100644 --- a/docs/content/changelog.mdx +++ b/docs/content/changelog.mdx @@ -13,6 +13,22 @@ request, and [Upgrading](/upgrading) covers the steps an existing deployment has ## Unreleased +### `docsgpt up` runs DocsGPT on Docker + +The Python package now sets up and runs the Docker stack: `uv tool install docsgpt`, then +`docsgpt up`. The first run asks who should reach DocsGPT (this computer, the network with an +access token, or a domain with HTTPS) and which model provider to use, writes the settings and +secrets to `~/.docsgpt/server/.env`, and starts the images of the installed version. `docsgpt status`, +`logs`, `token`, `upgrade`, `down` and `uninstall` manage it afterwards. See +[Run it with `docsgpt up`](/Deploying/Docker-Deploying#run-it-with-docsgpt-up). + +### An installed package keeps its data in `~/.docsgpt/server` + +Outside a source checkout, the data home (`.env`, uploads, indexes, models) was the directory +the command ran from, so starting `docsgpt api` from another folder silently used other +settings. It is now `~/.docsgpt/server`, or `/opt/docsgpt` for root on Linux; `DOCSGPT_HOME` +still overrides it. See [Upgrading](/upgrading#pip-installs-data-home-moved). + ### The standalone Docker stack runs on one port The `arc53/docsgpt` image now serves the web UI next to the API, the way `docsgpt api` does from diff --git a/docs/content/upgrading.mdx b/docs/content/upgrading.mdx index 7df9a0e3..2e5d3032 100644 --- a/docs/content/upgrading.mdx +++ b/docs/content/upgrading.mdx @@ -11,6 +11,10 @@ import { Callout } from 'nextra/components' **Upgrading from 0.16.x?** User data moved from MongoDB to Postgres in 0.17.0. Follow the [Postgres Migration guide](/Deploying/Postgres-Migration) before running `docker compose pull` or `git pull` — existing deployments will not start cleanly without it. +## pip installs: data home moved + +An installed package (`pip install docsgpt`, pipx, `uv tool`) used to keep its data home, meaning `.env`, `inputs/`, `indexes/` and `models/`, in the directory you ran `docsgpt api` and `docsgpt worker` from. It is now `~/.docsgpt/server` (`/opt/docsgpt` for root on Linux). Either move those files there, or set `DOCSGPT_HOME` to the old directory in the environment of both commands. Both commands print the data home they use, and point out a `.env` in the working directory that they no longer read. Source checkouts and the Docker images are not affected. + ## Standalone Compose file: one port The standalone Compose file (`docker-compose-standalone.yaml`) no longer runs a frontend container. The backend image serves the web UI on port 7091, and the port is published on `127.0.0.1` unless you set `DOCSGPT_BIND`. After downloading the new file, start it with `--remove-orphans` to remove the old frontend container, then open port 7091 instead of 5173. If you opened DocsGPT from other machines, see [Upgrading from an earlier standalone file](/Deploying/Docker-Deploying#upgrading-from-an-earlier-standalone-file). The checkout Compose files and the Kubernetes manifests are unchanged.