From 4f0bf2cca8a23f0bcdeeb53b60a62da8fabaaff8 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 15 Sep 2026 23:17:58 +0100 Subject: [PATCH] feat: one-command installers for macOS, Linux and Windows deployment/install.sh (curl | bash) and install.ps1 (irm | iex) check for Docker, install uv when it is missing or older than 0.8 (pinned 0.12.15 via Astral's installer), install or upgrade the docsgpt package with `uv tool install`, and hand the terminal to `docsgpt up` with any arguments. On Linux without Docker the shell installer offers get.docker.com. Both run entirely inside a function, so a download cut short runs nothing. Releases attach both scripts next to the Compose file, which is where docs.ac/install and docs.ac/install.ps1 will point. installer-lint.yml runs shellcheck and the PowerShell parser; docker-image-verify.yml now installs through install.sh. README, Quickstart, Docker-Deploying and the changelog lead with the one-liner. --- .github/workflows/ci.yml | 11 +- .github/workflows/docker-image-verify.yml | 47 +++--- .github/workflows/installer-lint.yml | 47 ++++++ README.md | 28 +++- deployment/install.ps1 | 94 +++++++++++ deployment/install.sh | 169 ++++++++++++++++++++ docs/content/Deploying/Docker-Deploying.mdx | 14 +- docs/content/changelog.mdx | 7 + docs/content/quickstart.mdx | 139 ++++++++-------- 9 files changed, 455 insertions(+), 101 deletions(-) create mode 100644 .github/workflows/installer-lint.yml create mode 100644 deployment/install.ps1 create mode 100755 deployment/install.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cd9c85e..fd042048 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -206,9 +206,16 @@ jobs: ref: ${{ inputs.version && format('refs/tags/{0}', inputs.version) || github.ref }} persist-credentials: false - - name: Attach the standalone compose file to the release + # The installers are served from these assets: docs.ac/install redirects to + # releases/latest/download/install.sh (and install.ps1), so the script a + # user runs always comes from the newest release. + - name: Attach the standalone compose file and the installers to the release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ env.RELEASE_TAG }} run: | - gh release upload "$TAG" deployment/docker-compose-standalone.yaml --clobber + gh release upload "$TAG" \ + deployment/docker-compose-standalone.yaml \ + deployment/install.sh \ + deployment/install.ps1 \ + --clobber diff --git a/.github/workflows/docker-image-verify.yml b/.github/workflows/docker-image-verify.yml index f592febf..a2825d52 100644 --- a/.github/workflows/docker-image-verify.yml +++ b/.github/workflows/docker-image-verify.yml @@ -23,6 +23,7 @@ on: - 'frontend/**' - 'scripts/build_frontend.sh' - 'deployment/docker-compose-standalone.yaml' + - 'deployment/install.sh' - 'docsgpt/deploy/**' - 'docsgpt/cli.py' - 'docsgpt/core/paths.py' @@ -98,41 +99,29 @@ 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 - with: - # No cache: a cache restored into a job that runs the built image is a poisoning risk. - enable-cache: false - - - name: docsgpt up runs the same image from the installed package + - name: The installer runs docsgpt up on the same image if: matrix.variant == '' + env: + DOCSGPT_NO_MODIFY_PATH: "1" 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" + pipx run build --wheel --outdir "$RUNNER_TEMP/dist" + export DOCSGPT_PACKAGE="$(ls "$RUNNER_TEMP"/dist/docsgpt-*.whl)" + # No uv is set up beforehand, so the installer's pinned uv download runs too. + # Without a terminal the installer passes --yes to docsgpt up. + bash deployment/install.sh --image-tag verify [!Note] -> Make sure you have [Docker](https://docs.docker.com/engine/install/) installed +> DocsGPT runs on [Docker](https://docs.docker.com/engine/install/). The installer checks for it first. -A more detailed [Quickstart](https://docs.docsgpt.cloud/quickstart) is available in our documentation +**macOS and Linux:** + +```bash +curl -fsSL https://docs.ac/install | bash +``` + +**Windows (PowerShell):** + +```powershell +irm https://docs.ac/install.ps1 | iex +``` + +The installer gets [uv](https://docs.astral.sh/uv/), installs the `docsgpt` Python package with it, and runs `docsgpt up`. That asks who should reach DocsGPT (only this computer, your network, or a domain with HTTPS) and which model provider to use, then starts it, at http://localhost:7091 for a local install. Afterwards, `docsgpt status`, `docsgpt logs`, `docsgpt upgrade`, `docsgpt down` and `docsgpt uninstall` manage it. + +To read the script before running it: + +```bash +curl -fsSL https://docs.ac/install -o install.sh +less install.sh +bash install.sh +``` + +A more detailed [Quickstart](https://docs.docsgpt.cloud/quickstart) is available in our documentation. + +### From a clone, with the setup script 1. **Clone the repository:** diff --git a/deployment/install.ps1 b/deployment/install.ps1 new file mode 100644 index 00000000..0c722b3b --- /dev/null +++ b/deployment/install.ps1 @@ -0,0 +1,94 @@ +# DocsGPT installer for Windows. +# +# irm https://docs.ac/install.ps1 | iex +# +# Installs uv when it is missing or too old, installs the docsgpt Python +# package with it, then runs `docsgpt up`, which sets up DocsGPT on Docker +# Desktop and starts it. Running it again upgrades the package and keeps your +# settings. To pass options to `docsgpt up`: +# +# & ([scriptblock]::Create((irm https://docs.ac/install.ps1))) --domain docs.example.com --yes +# +# Environment: +# DOCSGPT_VERSION package version to install (default: the latest release) +# DOCSGPT_PACKAGE install this instead of docsgpt from PyPI (a wheel path or URL) +# DOCSGPT_NO_MODIFY_PATH set to 1 to leave PATH alone +# +# Everything runs inside a function, so a download cut short runs nothing, and +# nothing calls `exit`, which would close the window `iex` runs in. + +function Install-DocsGPT { + param([string[]]$UpArguments) + + $ErrorActionPreference = 'Stop' + $UvVersion = '0.12.15' + $UvMinVersion = [version]'0.8.0' + + function Say([string]$Message) { Write-Host "==> $Message" } + + if (-not (Get-Command docker -ErrorAction SilentlyContinue)) { + throw 'DocsGPT runs on Docker. Install Docker Desktop (https://docs.docker.com/desktop/setup/install/windows-install/), start it, and run this again.' + } + + # uv installs and upgrades the package, and brings Python 3.12 when the system has none. + $uv = $null + $candidates = @( + (Get-Command uv -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source -First 1), + (Join-Path $HOME '.local\bin\uv.exe'), + (Join-Path $HOME '.cargo\bin\uv.exe') + ) | Where-Object { $_ -and (Test-Path $_) } + foreach ($candidate in $candidates) { + $found = "$(& $candidate --version 2>$null)" -replace '^uv\s+([0-9.]+).*$', '$1' + if ($found -match '^\d+\.\d+(\.\d+)?$' -and [version]$found -ge $UvMinVersion) { + $uv = $candidate + break + } + } + if (-not $uv) { + $uvDir = Join-Path $HOME '.local\bin' + Say "Installing uv $UvVersion into $uvDir" + $env:UV_INSTALL_DIR = $uvDir + $env:UV_NO_MODIFY_PATH = '1' + $env:UV_PRINT_QUIET = '1' + # A child PowerShell, so nothing the uv installer does can end this session. + $shell = (Get-Process -Id $PID).Path + & $shell -NoProfile -ExecutionPolicy Bypass -Command "irm https://astral.sh/uv/$UvVersion/install.ps1 | iex" + $uv = Join-Path $uvDir 'uv.exe' + if (-not (Test-Path $uv)) { throw "uv did not install into $uvDir" } + } + + if ($env:DOCSGPT_VERSION -and $env:DOCSGPT_PACKAGE) { + throw 'Set DOCSGPT_VERSION or DOCSGPT_PACKAGE, not both.' + } + if ($env:DOCSGPT_PACKAGE) { + Say "Installing docsgpt from $env:DOCSGPT_PACKAGE" + & $uv tool install --reinstall --python 3.12 $env:DOCSGPT_PACKAGE + } elseif ($env:DOCSGPT_VERSION) { + Say "Installing docsgpt $env:DOCSGPT_VERSION" + & $uv tool install --force --python 3.12 "docsgpt==$env:DOCSGPT_VERSION" + } else { + Say 'Installing the latest docsgpt' + & $uv tool install --upgrade --python 3.12 docsgpt + } + if ($LASTEXITCODE -ne 0) { throw 'Installing the docsgpt package failed.' } + + $binDir = "$(& $uv tool dir --bin)".Trim() + $docsgpt = Join-Path $binDir 'docsgpt.exe' + if (-not (Test-Path $docsgpt)) { throw "The docsgpt command is missing from $binDir." } + if (($env:Path -split ';') -notcontains $binDir) { + if ($env:DOCSGPT_NO_MODIFY_PATH -eq '1') { + Say "Add $binDir to PATH to run docsgpt from a new terminal" + } else { + & $uv tool update-shell *> $null + Say "Added $binDir to PATH for new terminals" + } + $env:Path = "$binDir;$env:Path" + } + + & $docsgpt up @UpArguments + if ($LASTEXITCODE -ne 0) { + Write-Error "docsgpt up exited with code $LASTEXITCODE. Run it again after fixing the problem above: docsgpt up" -ErrorAction Continue + } +} + +Install-DocsGPT -UpArguments $args diff --git a/deployment/install.sh b/deployment/install.sh new file mode 100755 index 00000000..95ed1401 --- /dev/null +++ b/deployment/install.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +# DocsGPT installer for macOS and Linux. +# +# curl -fsSL https://docs.ac/install | bash +# +# Installs uv when it is missing or too old, installs the `docsgpt` Python +# package with it, then runs `docsgpt up`, which sets up DocsGPT on Docker and +# starts it. Running it again upgrades the package and keeps your settings. +# Arguments go to `docsgpt up` (see `docsgpt up --help`): +# +# curl -fsSL https://docs.ac/install | bash -s -- --domain docs.example.com --yes +# +# Environment: +# DOCSGPT_VERSION package version to install (default: the latest release) +# DOCSGPT_PACKAGE install this instead of docsgpt from PyPI (a wheel path or URL) +# DOCSGPT_NO_MODIFY_PATH set to 1 to leave shell profiles alone +# DOCSGPT_INSTALL_DOCKER set to 1 to install Docker on Linux without asking +# +# Everything runs inside main(), so a download cut short runs nothing. + +UV_VERSION="0.12.15" +UV_MIN_VERSION="0.8.0" + +main() { + set -euo pipefail + + local bold="" red="" reset="" + if [ -t 2 ]; then + bold=$'\033[1m' red=$'\033[31m' reset=$'\033[0m' + fi + say() { printf '%s==>%s %s\n' "$bold" "$reset" "$*" >&2; } + die() { printf '%serror:%s %s\n' "$red" "$reset" "$*" >&2; exit 1; } + has() { command -v "$1" >/dev/null 2>&1; } + have_tty() { (exec /dev/null; } + ask_yes() { + local answer + printf '%s [y/N] ' "$1" >/dev/tty + read -r answer = B for dotted version numbers. + version_ge() { + local -a left right + IFS=. read -r -a left <<<"$1" + IFS=. read -r -a right <<<"$2" + local i x y + for i in 0 1 2; do + x="${left[i]:-0}" y="${right[i]:-0}" + x="${x%%[!0-9]*}" y="${y%%[!0-9]*}" + if (( 10#${x:-0} > 10#${y:-0} )); then return 0; fi + if (( 10#${x:-0} < 10#${y:-0} )); then return 1; fi + done + return 0 + } + + local os + os="$(uname -s)" + case "$os" in + Linux | Darwin) ;; + *) die "this installer is for macOS and Linux. On Windows, in PowerShell: irm https://docs.ac/install.ps1 | iex" ;; + esac + + # Docker first: without it nothing below is useful. + local docker_group_pending=0 + if ! has docker; then + if [ "$os" = Darwin ]; then + die "DocsGPT runs on Docker. Install Docker Desktop (https://docs.docker.com/desktop/setup/install/mac-install/) or OrbStack (https://orbstack.dev), start it, and run this again." + fi + if [ "${DOCSGPT_INSTALL_DOCKER:-}" = 1 ] || { have_tty && ask_yes "Docker is not installed. Install it now with Docker's script from get.docker.com?"; }; then + local sudo="" + if [ "$(id -u)" -ne 0 ]; then + has sudo || die "installing Docker needs root. Install it (https://docs.docker.com/engine/install/) and run this again." + sudo="sudo" + fi + say "Installing Docker" + download https://get.docker.com | $sudo sh + $sudo systemctl enable --now docker >/dev/null 2>&1 || true + if [ -n "$sudo" ]; then + $sudo usermod -aG docker "$(id -un)" + docker_group_pending=1 + fi + else + die "DocsGPT runs on Docker. Install it (https://docs.docker.com/engine/install/) and run this again." + fi + fi + + # uv installs and upgrades the package, and brings Python 3.12 when the system has none. + local uv="" candidate found + for candidate in "$(command -v uv 2>/dev/null || true)" "$HOME/.local/bin/uv" "$HOME/.cargo/bin/uv"; do + [ -n "$candidate" ] && [ -x "$candidate" ] || continue + found="$("$candidate" --version 2>/dev/null | awk '{print $2}')" || continue + if [ -n "$found" ] && version_ge "$found" "$UV_MIN_VERSION"; then + uv="$candidate" + break + fi + done + if [ -z "$uv" ]; then + local uv_dir="${XDG_BIN_HOME:-$HOME/.local/bin}" + say "Installing uv $UV_VERSION into $uv_dir" + download "https://astral.sh/uv/$UV_VERSION/install.sh" | env UV_INSTALL_DIR="$uv_dir" UV_NO_MODIFY_PATH=1 UV_PRINT_QUIET=1 sh + uv="$uv_dir/uv" + [ -x "$uv" ] || die "uv did not install into $uv_dir" + fi + + if [ -n "${DOCSGPT_VERSION:-}" ] && [ -n "${DOCSGPT_PACKAGE:-}" ]; then + die "set DOCSGPT_VERSION or DOCSGPT_PACKAGE, not both" + fi + if [ -n "${DOCSGPT_PACKAGE:-}" ]; then + say "Installing docsgpt from $DOCSGPT_PACKAGE" + "$uv" tool install --reinstall --python 3.12 "$DOCSGPT_PACKAGE" + elif [ -n "${DOCSGPT_VERSION:-}" ]; then + say "Installing docsgpt $DOCSGPT_VERSION" + "$uv" tool install --force --python 3.12 "docsgpt==$DOCSGPT_VERSION" + else + say "Installing the latest docsgpt" + "$uv" tool install --upgrade --python 3.12 docsgpt + fi + + local bin_dir docsgpt + bin_dir="$("$uv" tool dir --bin)" + docsgpt="$bin_dir/docsgpt" + [ -x "$docsgpt" ] || die "the docsgpt command is missing from $bin_dir" + case ":$PATH:" in + *":$bin_dir:"*) ;; + *) + if [ "${DOCSGPT_NO_MODIFY_PATH:-}" = 1 ]; then + say "Add $bin_dir to PATH to run docsgpt from a new terminal" + else + "$uv" tool update-shell >/dev/null 2>&1 || true + say "Added $bin_dir to PATH for new terminals" + fi + ;; + esac + + if [ "$docker_group_pending" = 1 ]; then + if has sg; then + # The docker group applies to new logins; sg gives it to this command now. + local command + command="$(printf '%q ' "$docsgpt" up "$@")" + if have_tty; then + exec sg docker -c "$command + To read the script before running it, download it first: `curl -fsSL https://docs.ac/install -o install.sh`, then `bash install.sh`. On Windows: `irm https://docs.ac/install.ps1 -OutFile install.ps1`, then `.\install.ps1`. + + +**Options.** Arguments after `bash -s --` go to `docsgpt up`, so a server can be set up without questions: + +```bash +curl -fsSL https://docs.ac/install | bash -s -- --yes --domain docs.example.com --provider openai --api-key "$OPENAI_API_KEY" +``` + +`DOCSGPT_VERSION` installs a specific release, and `DOCSGPT_NO_MODIFY_PATH=1` leaves your shell profile alone. `docsgpt up --help` lists every option. + +**Afterwards:** + +| Command | What it does | +| --- | --- | +| `docsgpt status` | Version, address, and whether DocsGPT answers | +| `docsgpt logs -f` | Follow the logs | +| `docsgpt token` | The access token, for installs reachable beyond this computer | +| `docsgpt up --reconfigure` | Ask the setup questions again | +| `docsgpt upgrade` | Upgrade to the latest release, keeping your settings and data | +| `docsgpt down` | Stop DocsGPT | +| `docsgpt uninstall` | Remove it; `--purge` also deletes settings and data | + +Running the install command again also upgrades. See [Run it with `docsgpt up`](/Deploying/Docker-Deploying#run-it-with-docsgpt-up) for the details. + +## From a clone, with the setup script + +To work from the source tree, for example to build the images yourself, use `setup.sh` (macOS and Linux) or `setup.ps1` (Windows). + +1. **Clone the repository:** ```bash git clone https://github.com/arc53/DocsGPT.git cd DocsGPT ``` -2. **Run the `setup.sh` script:** - - Navigate to the DocsGPT directory in your terminal and execute the `setup.sh` script: +2. **Run the setup script:** ```bash ./setup.sh ``` -3. **Follow the interactive setup:** + On Windows: - The `setup.sh` script will guide you through an interactive menu with the following options: + ```powershell + PowerShell -ExecutionPolicy Bypass -File .\setup.ps1 + ``` + +3. **Follow the interactive setup:** ``` Welcome to DocsGPT Setup! @@ -47,73 +98,29 @@ The easiest way to launch DocsGPT is using the provided `setup.sh` script. This Choose option (1-5): ``` - Let's break down each option: + * **1) Use DocsGPT Public API Endpoint (simple and free):** This is the simplest option to get started. It utilizes the DocsGPT public API, requiring no API keys or local model downloads. - * **1) Use DocsGPT Public API Endpoint (simple and free):** This is the simplest option to get started. It utilizes the DocsGPT public API, requiring no API keys or local model downloads. Choose this for a quick and easy setup. + * **2) Serve Local (with Ollama):** Runs a Large Language Model locally using [Ollama](https://ollama.com/). You'll be prompted to choose between CPU or GPU for Ollama and select a model to download. - * **2) Serve Local (with Ollama):** This option allows you to run a Large Language Model locally using [Ollama](https://ollama.com/). You'll be prompted to choose between CPU or GPU for Ollama and select a model to download. This is a good option for local processing and experimentation. + * **3) Connect Local Inference Engine:** If you already run a local inference engine like Llama.cpp, Text Generation Inference (TGI), vLLM, or others, choose this option and provide the connection details. - * **3) Connect Local Inference Engine:** If you are already running a local inference engine like Llama.cpp, Text Generation Inference (TGI), vLLM, or others, choose this option. You'll be asked to select your engine and provide the necessary connection details. This is for users with existing local LLM infrastructure. + * **4) Connect Cloud API Provider:** Connect DocsGPT to a Cloud API provider such as OpenAI, Google (Vertex AI/Gemini), Anthropic (Claude), Groq, HuggingFace Inference API, or Azure OpenAI. You will need an API key from your chosen provider. - * **4) Connect Cloud API Provider:** This option lets you connect DocsGPT to a commercial Cloud API provider such as OpenAI, Google (Vertex AI/Gemini), Anthropic (Claude), Groq, HuggingFace Inference API, or Azure OpenAI. You will need an API key from your chosen provider. Select this if you prefer to use a powerful cloud-based LLM. + * **5) Modify DocsGPT's source code and rebuild the Docker images locally.** Instead of pulling prebuilt images from Docker Hub, you build the backend and frontend from source, to customize how DocsGPT works internally or to run it in an environment without internet access. - * **5) Modify DocsGPT's source code and rebuild the Docker images locally.** Instead of pulling prebuilt images from Docker Hub or using the hosted/public API, you build the entire backend and frontend from source, customizing how DocsGPT works internally, or run it in an environment without internet access. + After selecting an option and providing any required information (like API keys or model names), the script configures your `.env` file and starts DocsGPT using Docker Compose. - After selecting an option and providing any required information (like API keys or model names), the script will configure your `.env` file and start DocsGPT using Docker Compose. +4. **Access DocsGPT in your browser:** open [http://localhost:5173/](http://localhost:5173/). -4. **Access DocsGPT in your browser:** - - Once the setup is complete and Docker containers are running, navigate to [http://localhost:5173/](http://localhost:5173/) in your web browser to access the DocsGPT web application. - -5. **Stopping DocsGPT:** - - To stop DocsGPT, simply open a new terminal in the `DocsGPT` directory and run: +5. **Stopping DocsGPT:** in the `DocsGPT` directory, run the `docker compose down` command the script printed at the end, for example: ```bash docker compose -f deployment/docker-compose-hub.yaml down ``` - (or the specific `docker compose` command shown at the end of the `setup.sh` execution, which may include optional compose files depending on your choices). -## Launching DocsGPT (Windows) +**Important for Windows:** Ensure Docker Desktop is installed and running before you start. The script tries to start Docker if it is not running, but you may need to start it manually. -For Windows users, we provide a PowerShell script that offers the same functionality as the macOS/Linux setup script. - -**Steps:** - -1. **Download the DocsGPT Repository:** - - First, you need to download the DocsGPT repository to your local machine. You can do this using Git: - - ```powershell - git clone https://github.com/arc53/DocsGPT.git - cd DocsGPT - ``` - -2. **Run the `setup.ps1` script:** - - Execute the PowerShell setup script: - - ```powershell - PowerShell -ExecutionPolicy Bypass -File .\setup.ps1 - ``` - -3. **Follow the interactive setup:** - - Just like the Linux/macOS script, the PowerShell script will guide you through setting DocsGPT. - The script will handle environment configuration and start DocsGPT based on your selections. - -4. **Access DocsGPT in your browser:** - - Once the setup is complete and Docker containers are running, navigate to [http://localhost:5173/](http://localhost:5173/) in your web browser to access the DocsGPT web application. - -5. **Stopping DocsGPT:** - - To stop DocsGPT run the Docker Compose down command displayed at the end of the setup script's execution. - -**Important for Windows:** Ensure Docker Desktop is installed and running correctly on your Windows system before proceeding. The script will attempt to start Docker if it's not running, but you may need to start it manually if there are issues. - -**Alternative Method:** -If you prefer a more manual approach, you can follow our [Docker Deployment documentation](/Deploying/Docker-Deploying) for detailed instructions on setting up DocsGPT on Windows using Docker commands directly. +**Alternative Method:** To run the pre-built images with Docker Compose yourself, follow the [Docker Deployment documentation](/Deploying/Docker-Deploying). ## Advanced Configuration