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.