mirror of
https://github.com/imartinez/privateGPT.git
synced 2026-07-16 17:00:12 +00:00
* fix: ensure that the publisher is ready to publish new messages
* fix: dockerfile
* fix: clones
(cherry picked from commit bc0a77e050)
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
220 lines
8.6 KiB
Docker
220 lines
8.6 KiB
Docker
ARG EXTRAS="core"
|
|
|
|
FROM python:3.11.10-slim-bookworm AS base
|
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
ENV PATH="/usr/local/bin:${PATH}"
|
|
ENV UV_LINK_MODE=copy \
|
|
UV_CACHE_DIR=/root/.cache/uv
|
|
|
|
FROM base AS os-deps
|
|
ARG EXTRAS
|
|
RUN rm -f /etc/apt/apt.conf.d/docker-clean
|
|
|
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
set -eu; \
|
|
ENABLE_DOCUMENTS=0; \
|
|
ENABLE_MEDIA=0; \
|
|
ENABLE_WEB_SCRAPING=0; \
|
|
ENABLE_DATABASE=0; \
|
|
for extra in $EXTRAS; do \
|
|
case "$extra" in core|ingest|ingest-core|ingest-documents|ingest-markitdown|ingest-markup) ENABLE_DOCUMENTS=1 ;; esac; \
|
|
case "$extra" in core|media|media-core|media-image|media-audio|media-video) ENABLE_MEDIA=1 ;; esac; \
|
|
case "$extra" in core|tools|tool-web-scraping) ENABLE_WEB_SCRAPING=1 ;; esac; \
|
|
case "$extra" in core|tools|tool-database|database|database-core|database-postgres|database-mysql|database-mssql|database-db2) ENABLE_DATABASE=1 ;; esac; \
|
|
done; \
|
|
apt update; \
|
|
apt install -yqq --no-install-recommends \
|
|
curl \
|
|
ca-certificates; \
|
|
if [ "$ENABLE_DOCUMENTS" = "1" ]; then \
|
|
apt install -yqq --no-install-recommends \
|
|
libmagic1 \
|
|
libxml2 \
|
|
libxslt1.1 \
|
|
poppler-utils \
|
|
libreoffice \
|
|
pandoc \
|
|
ghostscript; \
|
|
fi; \
|
|
if [ "$ENABLE_MEDIA" = "1" ]; then \
|
|
apt install -yqq --no-install-recommends \
|
|
ffmpeg \
|
|
libavcodec-extra; \
|
|
fi; \
|
|
if [ "$ENABLE_WEB_SCRAPING" = "1" ]; then \
|
|
apt install -yqq --no-install-recommends \
|
|
libglib2.0-0 \
|
|
libnss3 \
|
|
libnspr4 \
|
|
libdbus-1-3 \
|
|
libatk1.0-0 \
|
|
libatk-bridge2.0-0 \
|
|
libatspi2.0-0 \
|
|
libcups2 \
|
|
libx11-6 \
|
|
libxcomposite1 \
|
|
libxdamage1 \
|
|
libxext6 \
|
|
libxfixes3 \
|
|
libxrandr2 \
|
|
libgbm1 \
|
|
libxcb1 \
|
|
libxkbcommon0 \
|
|
libpango-1.0-0 \
|
|
libcairo2 \
|
|
libasound2 \
|
|
libxfont2 \
|
|
x11-xkb-utils \
|
|
xserver-common; \
|
|
fi; \
|
|
if [ "$ENABLE_DATABASE" = "1" ]; then \
|
|
apt install -yqq --no-install-recommends libmariadb3; \
|
|
curl -sSL -O https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb; \
|
|
dpkg -i packages-microsoft-prod.deb; \
|
|
rm packages-microsoft-prod.deb; \
|
|
apt update; \
|
|
ACCEPT_EULA=Y apt install -yqq --no-install-recommends msodbcsql18; \
|
|
fi; \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
FROM base AS dependencies
|
|
WORKDIR /home/worker/app
|
|
|
|
ARG EXTRAS
|
|
|
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
set -eu; \
|
|
apt update; \
|
|
apt install -yqq --no-install-recommends \
|
|
build-essential \
|
|
pkg-config; \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY pyproject.toml uv.lock ./
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
set -eu; \
|
|
extra_flags=""; \
|
|
for extra in $EXTRAS; do \
|
|
extra_flags="$extra_flags --extra $extra"; \
|
|
done; \
|
|
uv sync --no-dev --frozen --no-install-project $extra_flags
|
|
|
|
# remove hf_xet, it does not support custom CA which
|
|
# makes them fail in some corporate environments.
|
|
# The fallback is hf-transfer, which uses HTTPS properly (with certificate validation)
|
|
RUN uv pip uninstall hf-xet
|
|
|
|
FROM base AS build
|
|
WORKDIR /home/worker/app
|
|
COPY private_gpt/ private_gpt
|
|
COPY ui/ ui
|
|
|
|
# New download stage for caching model files
|
|
FROM base AS downloads
|
|
WORKDIR /home/worker/app
|
|
ARG EXTRAS
|
|
ARG PGPT_DOWNLOAD_NLTK
|
|
ARG PGPT_DOWNLOAD_TIKTOKEN_CACHE
|
|
ARG PGPT_DOWNLOAD_TIKTOKEN_ENCODINGS
|
|
ARG PGPT_DOWNLOAD_PLAYWRIGHT
|
|
|
|
COPY pyproject.toml uv.lock ./
|
|
|
|
ENV PGPT_HOME=/home/worker/app
|
|
ENV HF_HOME=/home/worker/app/local_data
|
|
ENV PLAYWRIGHT_BROWSERS_PATH=/home/worker/app/.local-browsers
|
|
ENV TIKTOKEN_CACHE_DIR=/home/worker/app/tiktoken_cache
|
|
ENV TIKTOKEN_ENCODINGS_BASE=/home/worker/app/encodings
|
|
ENV TIKTOKEN_RS_CACHE_DIR=/home/worker/app/encodings
|
|
|
|
RUN mkdir -p models/nltk_cache .local-browsers tiktoken_cache encodings local_data
|
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
set -eu; \
|
|
has_web_scraping=0; \
|
|
for extra in $EXTRAS; do \
|
|
if [ "$extra" = "tools" ] || [ "$extra" = "tool-web-scraping" ] || [ "$extra" = "core" ]; then \
|
|
has_web_scraping=1; \
|
|
break; \
|
|
fi; \
|
|
done; \
|
|
resolved_download_nltk="${PGPT_DOWNLOAD_NLTK:-1}"; \
|
|
resolved_download_tiktoken_cache="${PGPT_DOWNLOAD_TIKTOKEN_CACHE:-1}"; \
|
|
resolved_download_tiktoken_encodings="${PGPT_DOWNLOAD_TIKTOKEN_ENCODINGS:-1}"; \
|
|
resolved_download_playwright="${PGPT_DOWNLOAD_PLAYWRIGHT:-$has_web_scraping}"; \
|
|
requested_packages=""; \
|
|
if [ "$resolved_download_nltk" = "1" ]; then \
|
|
requested_packages="$requested_packages nltk"; \
|
|
fi; \
|
|
if [ "$resolved_download_tiktoken_cache" = "1" ] || [ "$resolved_download_tiktoken_encodings" = "1" ]; then \
|
|
requested_packages="$requested_packages tiktoken"; \
|
|
fi; \
|
|
if [ "$resolved_download_playwright" = "1" ]; then \
|
|
requested_packages="$requested_packages playwright"; \
|
|
fi; \
|
|
if [ -n "$requested_packages" ]; then \
|
|
export REQUESTED_PACKAGES="$requested_packages"; \
|
|
locked_packages="$(python3 -c 'import os, sys, tomllib; requested = [pkg for pkg in os.environ.get("REQUESTED_PACKAGES", "").split() if pkg]; lock = tomllib.load(open("uv.lock", "rb")); versions = {pkg["name"]: pkg["version"] for pkg in lock.get("package", []) if pkg.get("name") in requested and "version" in pkg}; missing = [pkg for pkg in requested if pkg not in versions]; sys.exit("Missing locked version(s) in uv.lock for: " + ", ".join(missing)) if missing else print(" ".join(f"{pkg}=={versions[pkg]}" for pkg in requested))')"; \
|
|
uv pip install --system $locked_packages; \
|
|
fi; \
|
|
if [ "$resolved_download_nltk" = "1" ]; then \
|
|
python3 -c "import nltk, zipfile; from pathlib import Path; download_dir=Path('models/nltk_cache'); packages=('punkt_tab', 'punkt', 'averaged_perceptron_tagger_eng', 'averaged_perceptron_tagger', 'stopwords', 'wordnet'); [nltk.download(p, download_dir=str(download_dir), raise_on_error=True) for p in packages]; [(lambda path: (lambda zf: (zf.extractall(path.parent), zf.close()))(zipfile.ZipFile(path)))(path) for path in download_dir.rglob('*.zip')]"; \
|
|
fi; \
|
|
if [ "$resolved_download_tiktoken_cache" = "1" ]; then \
|
|
python3 -c "import tiktoken; tiktoken.get_encoding('cl100k_base')"; \
|
|
fi; \
|
|
if [ "$resolved_download_tiktoken_encodings" = "1" ]; then \
|
|
python3 -c "import urllib.request; from pathlib import Path; d = Path('encodings'); d.mkdir(exist_ok=True); [urllib.request.urlretrieve(f'https://openaipublic.blob.core.windows.net/encodings/{name}', d / name) for name in ('o200k_base.tiktoken', 'cl100k_base.tiktoken')]"; \
|
|
fi; \
|
|
if [ "$resolved_download_playwright" = "1" ]; then \
|
|
playwright install chromium; \
|
|
fi
|
|
|
|
FROM os-deps AS final
|
|
|
|
ENV PYTHONUNBUFFERED=1
|
|
ENV PORT=8080
|
|
EXPOSE 8080
|
|
|
|
RUN adduser worker
|
|
WORKDIR /home/worker/app
|
|
RUN mkdir -p /home/worker/app /home/worker/app/local_data /home/worker/app/models /home/worker/app/scripts /home/worker/app/ui \
|
|
&& chown -R worker /home/worker/app
|
|
|
|
# Copy virtual environment
|
|
COPY --chown=worker --from=dependencies /home/worker/app/pyproject.toml /home/worker/app/pyproject.toml
|
|
COPY --chown=worker --from=dependencies /home/worker/app/uv.lock /home/worker/app/uv.lock
|
|
COPY --chown=worker --from=dependencies /home/worker/app/.venv/ /home/worker/app/.venv/
|
|
|
|
# Copy application code
|
|
COPY --chown=worker --from=build /home/worker/app/ /home/worker/app/
|
|
|
|
# Copy downloaded model files
|
|
COPY --chown=worker --from=downloads /home/worker/app/models/nltk_cache/ models/nltk_cache/
|
|
COPY --chown=worker --from=downloads /home/worker/app/.local-browsers/ .local-browsers/
|
|
COPY --chown=worker --from=downloads /home/worker/app/tiktoken_cache/ tiktoken_cache/
|
|
COPY --chown=worker --from=downloads /home/worker/app/encodings/ encodings/
|
|
|
|
# Copy additional files
|
|
COPY --chown=worker scripts/worker_entrypoint scripts/worker_entrypoint
|
|
RUN chmod +x scripts/worker_entrypoint
|
|
|
|
COPY --chown=worker version.txt version.txt
|
|
COPY --chown=worker settings.yaml settings.yaml
|
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv uv pip install --python /home/worker/app/.venv/bin/python --no-deps .
|
|
|
|
ENV PATH="/home/worker/app/.venv/bin:/usr/local/bin:${PATH}"
|
|
ENV PGPT_HOME=/home/worker/app
|
|
ENV HF_HOME=/home/worker/app/local_data
|
|
ENV PYTHONPATH="$PYTHONPATH:/private_gpt/"
|
|
ENV SETUPTOOLS_USE_DISTUTILS=stdlib
|
|
|
|
ENV PLAYWRIGHT_BROWSERS_PATH=/home/worker/app/.local-browsers
|
|
ENV TIKTOKEN_CACHE_DIR=/home/worker/app/tiktoken_cache
|
|
ENV TIKTOKEN_ENCODINGS_BASE=/home/worker/app/encodings
|
|
ENV TIKTOKEN_RS_CACHE_DIR=/home/worker/app/encodings
|
|
|
|
ENTRYPOINT ["private-gpt"]
|
|
CMD ["serve"]
|