mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-11-10 21:32:43 +08:00
Add go build files , reduce image size, update entrypoint-go.sh (#19041)
Add go build files , reduce image size, update entrypoint-go.sh
This commit is contained in:
1 parent
f300b154b0
commit
7690ebd84b
4 files changed
+1160
No files matched your search
+222
@@ -0,0 +1,222 @@
|
||||
# base stage
|
||||
FROM ubuntu:24.04 AS base
|
||||
USER root
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG NEED_MIRROR=1
|
||||
|
||||
#Optional parameter
|
||||
#If set NEED_MIRROR=1, and set GITEE_TOKEN="xxxxx" , donwload source from gitee.
|
||||
#If don't set GITEE_TOKEN , download from github
|
||||
#ARG GITEE_TOKEN=""
|
||||
|
||||
WORKDIR /ragflow
|
||||
|
||||
# copy models downloaded via download_deps.py
|
||||
# layout.laws/manual/paper.onnx are byte-identical to layout.onnx, so we
|
||||
# exclude them from the tar extract and symlink them to layout.onnx instead,
|
||||
# saving ~219MB in the image.
|
||||
RUN mkdir -p /ragflow/rag/res/deepdoc /root/.ragflow
|
||||
RUN --mount=type=bind,from=infiniflow/ragflow_deps:latest,source=/huggingface.co,target=/huggingface.co \
|
||||
tar --exclude='.*' \
|
||||
--exclude='layout.laws.onnx' \
|
||||
--exclude='layout.manual.onnx' \
|
||||
--exclude='layout.paper.onnx' \
|
||||
-cf - \
|
||||
/huggingface.co/InfiniFlow/text_concat_xgb_v1.0 \
|
||||
/huggingface.co/InfiniFlow/deepdoc \
|
||||
| tar -xf - --strip-components=3 -C /ragflow/rag/res/deepdoc && \
|
||||
ln -s layout.onnx /ragflow/rag/res/deepdoc/layout.laws.onnx && \
|
||||
ln -s layout.onnx /ragflow/rag/res/deepdoc/layout.manual.onnx && \
|
||||
ln -s layout.onnx /ragflow/rag/res/deepdoc/layout.paper.onnx
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Setup apt
|
||||
RUN --mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \
|
||||
if [ "$NEED_MIRROR" == "1" ]; then \
|
||||
# CI runners may inject a proxy whose TLS certificate is not trusted inside
|
||||
# the fresh Ubuntu base image yet. Keep the Ubuntu mirror on HTTP here so
|
||||
# the mirror switch remains usable before the full CA store is available.
|
||||
sed -i 's|http://archive.ubuntu.com/ubuntu|http://mirrors.aliyun.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources; \
|
||||
sed -i 's|http://security.ubuntu.com/ubuntu|http://mirrors.aliyun.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources; \
|
||||
fi; \
|
||||
rm -f /etc/apt/apt.conf.d/docker-clean && \
|
||||
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache && \
|
||||
chmod 1777 /tmp && \
|
||||
apt update && \
|
||||
#apt --no-install-recommends install -y ca-certificates \
|
||||
#libglib2.0-0 libglx-mesa0 libgl1 pkg-config libgdiplus default-jdk libatk-bridge2.0-0 \
|
||||
#libgtk-4-1 libnss3 xdg-utils libjemalloc-dev gnupg unzip curl wget git vim less \
|
||||
#ghostscript pandoc texlive texlive-latex-extra texlive-xetex texlive-lang-chinese \
|
||||
#fonts-freefont-ttf fonts-noto-cjk postgresql-client
|
||||
|
||||
apt --no-install-recommends install -y ca-certificates libjemalloc2 curl vim unzip iproute2 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Download resource from GitHub to /usr/share/infinity
|
||||
# Ship only the directories required by the runtime tokenizer:
|
||||
# rag - base analyzer dictionaries (mandatory)
|
||||
# opencc - Traditional/Simplified Chinese conversion
|
||||
# wordnet - WordNet resources
|
||||
RUN --mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends git && \
|
||||
mkdir -p /usr/share/infinity/resource && \
|
||||
if [ "$NEED_MIRROR" == "1" ]; then \
|
||||
if [ -n "$GITEE_TOKEN" ]; then \
|
||||
git clone --depth 1 --single-branch "https://oauth2:${GITEE_TOKEN}@gitee.com/infiniflow/resource" /tmp/resource; \
|
||||
else \
|
||||
git clone --depth 1 --single-branch https://github.com/infiniflow/resource.git /tmp/resource; \
|
||||
fi; \
|
||||
else \
|
||||
git clone --depth 1 --single-branch https://github.com/infiniflow/resource.git /tmp/resource; \
|
||||
fi && \
|
||||
for d in rag opencc wordnet; do \
|
||||
cp -r "/tmp/resource/$d" /usr/share/infinity/resource/; \
|
||||
done && \
|
||||
rm -rf /tmp/resource && \
|
||||
apt-get purge -y git && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG NGINX_VERSION=1.31.3-1~noble
|
||||
RUN --mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \
|
||||
apt -o Acquire::Retries=5 update && \
|
||||
apt -o Acquire::Retries=5 install -y --no-install-recommends gnupg && \
|
||||
mkdir -p /etc/apt/keyrings && \
|
||||
curl --retry 5 --retry-delay 2 --retry-all-errors -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /etc/apt/keyrings/nginx-archive-keyring.gpg && \
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/mainline/ubuntu/ noble nginx" > /etc/apt/sources.list.d/nginx.list && \
|
||||
apt -o Acquire::Retries=5 update && \
|
||||
apt -o Acquire::Retries=5 install -y --no-install-recommends nginx=${NGINX_VERSION} && \
|
||||
apt-mark hold nginx && \
|
||||
apt-get purge -y gnupg && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#ENV PATH=/root/.local/bin:$PATH
|
||||
|
||||
# NOTE: Node.js is intentionally NOT installed in `base`. The pure-Go backend
|
||||
# serves the prebuilt static frontend via nginx and needs no Node runtime at
|
||||
# runtime. Node.js is only required to *build* the frontend, so it lives
|
||||
# exclusively in the `web-builder` stage and never reaches the final image.
|
||||
|
||||
|
||||
|
||||
# ── cpp-builder stage ──────────────────────────────────────────────
|
||||
# Compile C++ static library (librag_tokenizer_c_api.a) using the
|
||||
# infinity_builder image which ships clang-20, cmake and other C++
|
||||
# tooling. This stage is independent from the base image so that the
|
||||
# heavy C++ build toolchain does not bloat the final production image.
|
||||
FROM infiniflow/infinity_builder:ubuntu22_clang20 AS cpp-builder
|
||||
USER root
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG NEED_MIRROR=1
|
||||
WORKDIR /ragflow
|
||||
|
||||
COPY internal/binding/cpp internal/binding/cpp
|
||||
COPY build.sh ./
|
||||
|
||||
RUN git config --global safe.directory "*" && \
|
||||
cd /ragflow && ./build.sh --cpp
|
||||
|
||||
# ── go-builder stage ──
|
||||
FROM infiniflow/github_action_runner:latest AS go-builder
|
||||
USER root
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
WORKDIR /ragflow
|
||||
|
||||
COPY internal internal
|
||||
COPY cmd cmd
|
||||
COPY go.mod go.sum ./
|
||||
COPY build.sh ./
|
||||
|
||||
# Overwrite C++ build artifact from cpp-builder
|
||||
COPY --from=cpp-builder \
|
||||
/ragflow/internal/binding/cpp/cmake-build-release/librag_tokenizer_c_api.a \
|
||||
/ragflow/internal/binding/cpp/cmake-build-release/librag_tokenizer_c_api.a
|
||||
|
||||
RUN git config --global safe.directory "*" && \
|
||||
./build.sh -s --go
|
||||
|
||||
|
||||
# ── web-builder stage ──
|
||||
# Builds the static frontend. Node.js is installed HERE only, so the runtime
|
||||
# image (production, which extends `base`) never contains Node.js.
|
||||
FROM base AS web-builder
|
||||
USER root
|
||||
|
||||
WORKDIR /ragflow
|
||||
|
||||
# Install Node.js 22.x (Ubuntu 24.04's Node.js is too old)
|
||||
RUN --mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
|
||||
apt-get purge -y nodejs npm && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get update && \
|
||||
apt-get install -y nodejs
|
||||
|
||||
# Install frontend dependencies — depends only on package manifests so
|
||||
# web source / docs changes don't invalidate this layer.
|
||||
COPY web/package.json web/package-lock.json web/.npmrc ./web/
|
||||
RUN --mount=type=cache,id=ragflow_npm,target=/root/.npm,sharing=locked \
|
||||
cd web && NODE_OPTIONS="--max-old-space-size=8192" npm install
|
||||
|
||||
# Copy full web source and docs for the frontend build.
|
||||
COPY web web
|
||||
COPY docs docs
|
||||
RUN --mount=type=cache,id=ragflow_npm,target=/root/.npm,sharing=locked \
|
||||
cd web && NODE_OPTIONS="--max-old-space-size=8192" VITE_BUILD_SOURCEMAP=false VITE_MINIFY=esbuild npm run build
|
||||
|
||||
RUN --mount=type=bind,source=.git,target=/ragflow/.git \
|
||||
--mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends git && \
|
||||
version_info=$(git describe --tags --match=v* --first-parent --always) && \
|
||||
echo "$version_info" > /ragflow/VERSION && \
|
||||
apt-get purge -y git && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# production stage
|
||||
FROM base AS production
|
||||
USER root
|
||||
|
||||
WORKDIR /ragflow
|
||||
|
||||
# Copy the compiled Go backend binaries (set exec bits at copy time to avoid a redundant chmod layer)
|
||||
COPY --from=go-builder --chmod=755 /ragflow/bin/ /ragflow/bin/
|
||||
|
||||
ENV PYTHONPATH=/ragflow/
|
||||
|
||||
COPY docker/service_conf.yaml.template ./conf/service_conf.yaml.template
|
||||
COPY docker/entrypoint*.sh ./
|
||||
RUN chmod +x ./entrypoint*.sh
|
||||
|
||||
# Copy nginx configuration for frontend serving
|
||||
RUN mkdir -p /etc/nginx/conf.d /var/log/nginx
|
||||
|
||||
COPY docker/nginx/nginx.conf docker/nginx/proxy.conf /etc/nginx/
|
||||
COPY docker/nginx/ragflow.conf.golang \
|
||||
# docker/nginx/ragflow.conf.python \
|
||||
docker/nginx/ragflow.conf.hybrid \
|
||||
/etc/nginx/conf.d/
|
||||
|
||||
RUN rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
|
||||
COPY conf conf
|
||||
COPY agent/templates agent/templates
|
||||
|
||||
|
||||
# Copy compiled web pages
|
||||
COPY --from=web-builder /ragflow/web/dist /ragflow/web/dist
|
||||
|
||||
# Copy version info
|
||||
COPY --from=web-builder /ragflow/VERSION /ragflow/VERSION
|
||||
|
||||
# Set environment variables
|
||||
ENV HF_ENDPOINT=https://hf-mirror.com
|
||||
|
||||
ENTRYPOINT ["./entrypoint-go.sh"]
|
||||
+405
@@ -0,0 +1,405 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# SECURITY WARNING: DO NOT DEPLOY WITH DEFAULT PASSWORDS
|
||||
# For non-local deployments, please change all passwords (ELASTIC_PASSWORD,
|
||||
# MYSQL_PASSWORD, MINIO_PASSWORD, etc.) to strong, unique values.
|
||||
# You can generate a random string using: openssl rand -hex 32
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# docker env var for specifying vector db type at startup
|
||||
# (based on the vector db type, the corresponding docker
|
||||
# compose profile will be used)
|
||||
# ------------------------------
|
||||
# The type of doc engine to use.
|
||||
# Available options:
|
||||
# - `elasticsearch` (default)
|
||||
# - `infinity` (https://github.com/infiniflow/infinity)
|
||||
# - `oceanbase` (https://github.com/oceanbase/oceanbase)
|
||||
# - `opensearch` (https://github.com/opensearch-project/OpenSearch)
|
||||
# - `seekdb` (https://github.com/oceanbase/seekdb)
|
||||
# - `gaussdb` GaussDB Centralized / Distributed DocEngine
|
||||
DOC_ENGINE=${DOC_ENGINE:-elasticsearch}
|
||||
|
||||
# The business metadata database type used by DB_TYPE.
|
||||
# Available options: mysql (default), postgres, gaussdb, oceanbase.
|
||||
DB_TYPE=${DB_TYPE:-mysql}
|
||||
|
||||
# Device on which deepdoc inference run.
|
||||
# Available levels:
|
||||
# - `cpu` (default)
|
||||
# - `gpu`
|
||||
DEVICE=${DEVICE:-cpu}
|
||||
|
||||
# This controls only the bundled metadata service started by Compose; DB_TYPE
|
||||
# independently selects the metadata backend used by RAGFlow. Keep `mysql` to
|
||||
# start the in-cluster MySQL service. For external GaussDB, set both
|
||||
# DB_TYPE=gaussdb and METADATA_DB_PROFILE=gaussdb so MySQL stays disabled.
|
||||
METADATA_DB_PROFILE=${METADATA_DB_PROFILE:-mysql}
|
||||
COMPOSE_PROFILES=${DOC_ENGINE},${DEVICE},metadata-${METADATA_DB_PROFILE}
|
||||
|
||||
# The version of Elasticsearch.
|
||||
STACK_VERSION=${STACK_VERSION:-8.11.3}
|
||||
|
||||
# The hostname where the Elasticsearch service is exposed
|
||||
ES_HOST=es01
|
||||
|
||||
# The port used to expose the Elasticsearch service to the host machine,
|
||||
# allowing EXTERNAL access to the service running inside the Docker container.
|
||||
ES_PORT=1200
|
||||
|
||||
# The password for Elasticsearch.
|
||||
# WARNING: Change this for production!
|
||||
ELASTIC_PASSWORD=infini_rag_flow
|
||||
|
||||
# the hostname where OpenSearch service is exposed, set it not the same as elasticsearch
|
||||
OS_PORT=1201
|
||||
|
||||
# The hostname where the OpenSearch service is exposed
|
||||
OS_HOST=opensearch01
|
||||
|
||||
# The password for OpenSearch.
|
||||
# At least one uppercase letter, one lowercase letter, one digit, and one special character
|
||||
OPENSEARCH_PASSWORD=infini_rag_flow_OS_01
|
||||
|
||||
# The port used to expose the Kibana service to the host machine,
|
||||
# allowing EXTERNAL access to the service running inside the Docker container.
|
||||
# To enable kibana, you need to:
|
||||
# 1. Ensure that COMPOSE_PROFILES includes kibana, for example: COMPOSE_PROFILES=${COMPOSE_PROFILES},kibana
|
||||
# 2. Comment out or delete the following configurations of the es service in docker-compose-base.yml: xpack.security.enabled、xpack.security.http.ssl.enabled、xpack.security.transport.ssl.enabled (for details: https://www.elastic.co/docs/deploy-manage/security/self-auto-setup#stack-existing-settings-detected)
|
||||
# 3. Adjust the es.hosts in conf/service_config.yaml or docker/service_conf.yaml.template to 'https://localhost:1200'
|
||||
# 4. After the startup is successful, in the es container, execute the command to generate the kibana token: `bin/elasticsearch-create-enrollment-token -s kibana`, then you can use kibana normally
|
||||
KIBANA_PORT=6601
|
||||
|
||||
# The maximum amount of the memory, in bytes, that a specific Docker container can use while running.
|
||||
# Update it according to the available memory in the host machine.
|
||||
MEM_LIMIT=8073741824
|
||||
|
||||
# The hostname where the Infinity service is exposed
|
||||
INFINITY_HOST=infinity
|
||||
|
||||
# Port to expose Infinity API to the host
|
||||
INFINITY_THRIFT_PORT=23817
|
||||
INFINITY_HTTP_PORT=23820
|
||||
INFINITY_PSQL_PORT=5432
|
||||
|
||||
# The hostname where the SereneDB service is exposed. SereneDB speaks the
|
||||
# PostgreSQL wire protocol, so DOC_ENGINE=serenedb connects over lib/pq/psycopg2.
|
||||
SERENEDB_HOST=serenedb
|
||||
# Port to expose SereneDB to the host
|
||||
SERENEDB_PORT=7890
|
||||
# The password for SereneDB (POSTGRES_PASSWORD in the container)
|
||||
SERENEDB_PASSWORD=infini_rag_flow
|
||||
|
||||
# The hostname where the OceanBase service is exposed
|
||||
OCEANBASE_HOST=oceanbase
|
||||
# The port used to expose the OceanBase service
|
||||
OCEANBASE_PORT=2881
|
||||
# The username for OceanBase
|
||||
OCEANBASE_USER=root@ragflow
|
||||
# The password for OceanBase
|
||||
OCEANBASE_PASSWORD=infini_rag_flow
|
||||
# The doc database of the OceanBase service to use
|
||||
OCEANBASE_DOC_DBNAME=ragflow_doc
|
||||
|
||||
# GaussDB DocEngine connection. RAGFlow does not start or manage GaussDB;
|
||||
# configure an existing GaussDB instance here.
|
||||
# GaussDB host.
|
||||
GAUSSDB_HOST=
|
||||
# GaussDB port.
|
||||
GAUSSDB_PORT=
|
||||
# GaussDB database name.
|
||||
GAUSSDB_DATABASE=postgres
|
||||
# GaussDB login user.
|
||||
GAUSSDB_USER=
|
||||
# GaussDB login password.
|
||||
GAUSSDB_PASSWORD=
|
||||
# GaussDB schema for RAGFlow DocEngine objects.
|
||||
GAUSSDB_SCHEMA=
|
||||
|
||||
# OceanBase container configuration
|
||||
OB_CLUSTER_NAME=${OB_CLUSTER_NAME:-ragflow}
|
||||
OB_TENANT_NAME=${OB_TENANT_NAME:-ragflow}
|
||||
OB_SYS_PASSWORD=${OCEANBASE_PASSWORD:-infini_rag_flow}
|
||||
OB_TENANT_PASSWORD=${OCEANBASE_PASSWORD:-infini_rag_flow}
|
||||
OB_MEMORY_LIMIT=${OB_MEMORY_LIMIT:-10G}
|
||||
OB_SYSTEM_MEMORY=${OB_SYSTEM_MEMORY:-2G}
|
||||
OB_DATAFILE_SIZE=${OB_DATAFILE_SIZE:-20G}
|
||||
OB_LOG_DISK_SIZE=${OB_LOG_DISK_SIZE:-20G}
|
||||
|
||||
# The hostname where the SeekDB service is exposed
|
||||
SEEKDB_HOST=seekdb
|
||||
# The port used to expose the SeekDB service
|
||||
SEEKDB_PORT=2881
|
||||
# The username for SeekDB
|
||||
SEEKDB_USER=root
|
||||
# The password for SeekDB
|
||||
SEEKDB_PASSWORD=infini_rag_flow
|
||||
# The doc database of the SeekDB service to use
|
||||
SEEKDB_DOC_DBNAME=ragflow_doc
|
||||
# SeekDB memory limit
|
||||
SEEKDB_MEMORY_LIMIT=2G
|
||||
|
||||
# The password for MySQL.
|
||||
# WARNING: Change this for production!
|
||||
MYSQL_PASSWORD=infini_rag_flow
|
||||
# The hostname where the MySQL service is exposed
|
||||
MYSQL_HOST=mysql
|
||||
# The database of the MySQL service to use
|
||||
MYSQL_DBNAME=rag_flow
|
||||
# The port used to connect to MySQL from RAGFlow container.
|
||||
# Change this if you use external MySQL.
|
||||
MYSQL_PORT=3306
|
||||
# The port used to expose the MySQL service to the host machine,
|
||||
# allowing EXTERNAL access to the MySQL database running inside the Docker container.
|
||||
EXPOSE_MYSQL_PORT=3306
|
||||
# The maximum size of communication packets sent to the MySQL server
|
||||
MYSQL_MAX_PACKET=1073741824
|
||||
|
||||
# External GaussDB metadata database settings, used when DB_TYPE=gaussdb.
|
||||
# These are intentionally separate from the GAUSSDB_* DocEngine settings.
|
||||
GAUSSDB_METADATA_HOST=
|
||||
GAUSSDB_METADATA_PORT=
|
||||
GAUSSDB_METADATA_USER=
|
||||
GAUSSDB_METADATA_PASSWORD=
|
||||
GAUSSDB_METADATA_DBNAME=rag_flow
|
||||
GAUSSDB_METADATA_SCHEMA=public
|
||||
GAUSSDB_METADATA_MAX_CONNECTIONS=100
|
||||
GAUSSDB_METADATA_STALE_TIMEOUT=30
|
||||
|
||||
# The hostname where the MinIO service is exposed
|
||||
MINIO_HOST=minio
|
||||
# The port used to expose the MinIO console interface to the host machine,
|
||||
# allowing EXTERNAL access to the web-based console running inside the Docker container.
|
||||
MINIO_CONSOLE_PORT=9001
|
||||
# The port used to expose the MinIO API service to the host machine,
|
||||
# allowing EXTERNAL access to the MinIO object storage service running inside the Docker container.
|
||||
MINIO_PORT=9000
|
||||
# The username for MinIO.
|
||||
# When updated, you must revise the `minio.user` entry in service_conf.yaml accordingly.
|
||||
MINIO_USER=rag_flow
|
||||
# The password for MinIO.
|
||||
# When updated, you must revise the `minio.password` entry in service_conf.yaml accordingly.
|
||||
MINIO_PASSWORD=infini_rag_flow
|
||||
|
||||
# The hostname where the Redis service is exposed
|
||||
REDIS_HOST=redis
|
||||
# The port used to expose the Redis service to the host machine,
|
||||
# allowing EXTERNAL access to the Redis service running inside the Docker container.
|
||||
REDIS_PORT=6379
|
||||
# The password for Redis.
|
||||
REDIS_PASSWORD=infini_rag_flow
|
||||
|
||||
NATS_HOST=nats
|
||||
# Port used by RAGFlow's Go services to connect to NATS inside the container network.
|
||||
# Do NOT change this unless you also change `nats.port` in conf/service_conf.yaml.template.
|
||||
NATS_PORT=4222
|
||||
# Host-side port that maps to the NATS container port 4222. Change this to avoid
|
||||
# clashing with a port already used on the host machine. This ONLY affects the
|
||||
# published host port and is never read by RAGFlow's internal services.
|
||||
EXPOSE_NATS_PORT=4222
|
||||
|
||||
# The hostname where the ClickHouse service is exposed
|
||||
CLICKHOUSE_HOST=clickhouse
|
||||
# Native TCP port used by RAGFlow's Go services to connect to ClickHouse inside
|
||||
# the container network. Do NOT change this unless you also change `clickhouse.port`
|
||||
# in conf/service_conf.yaml.template.
|
||||
CLICKHOUSE_TCP_PORT=9000
|
||||
# Host-side port that maps to the ClickHouse container native TCP port 9000. Change
|
||||
# this to avoid clashing with a port already used on the host machine. This ONLY
|
||||
# affects the published host port and is never read by RAGFlow's internal services.
|
||||
EXPOSE_CLICKHOUSE_TCP_PORT=9900
|
||||
# The port used to expose the ClickHouse HTTP service
|
||||
CLICKHOUSE_HTTP_PORT=8123
|
||||
# The username for ClickHouse
|
||||
CLICKHOUSE_USER=ragflow
|
||||
# The password for ClickHouse
|
||||
CLICKHOUSE_PASSWORD=infini_rag_flow
|
||||
# The database for ClickHouse
|
||||
CLICKHOUSE_DATABASE=ragflow
|
||||
|
||||
# Jaeger (distributed tracing)
|
||||
# Enable by adding `jaeger` to COMPOSE_PROFILES, e.g.:
|
||||
# COMPOSE_PROFILES=${COMPOSE_PROFILES},jaeger
|
||||
# Then update otel.host in service_conf.yaml to "jaeger".
|
||||
JAEGER_VERSION=2.19.0
|
||||
JAEGER_OTLP_GRPC_PORT=4317
|
||||
JAEGER_OTLP_HTTP_PORT=4318
|
||||
JAEGER_UI_PORT=16686
|
||||
|
||||
# The port used to expose RAGFlow's HTTP API service to the host machine,
|
||||
# allowing EXTERNAL access to the service running inside the Docker container.
|
||||
SVR_WEB_HTTP_PORT=80
|
||||
SVR_WEB_HTTPS_PORT=443
|
||||
SVR_HTTP_PORT=9380
|
||||
ADMIN_SVR_HTTP_PORT=9381
|
||||
SVR_MCP_PORT=9382
|
||||
GO_HTTP_PORT=9384
|
||||
GO_ADMIN_PORT=9383
|
||||
|
||||
# API_PROXY_SCHEME=hybrid # go and python hybrid deploy mode
|
||||
API_PROXY_SCHEME=go # use go server deployment
|
||||
#API_PROXY_SCHEME=python # use pure python server deployment
|
||||
|
||||
# Development-only: set to 1 to bypass host safety checks for test_db_connection and allow private/local database hosts.
|
||||
# Do not enable in production.
|
||||
ALLOW_ANY_HOST=0
|
||||
|
||||
# The RAGFlow Docker image to download. v0.22+ doesn't include embedding models.
|
||||
RAGFLOW_IMAGE=infiniflow/ragflow:go-test-1
|
||||
|
||||
# If you cannot download the RAGFlow Docker image:
|
||||
# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.27.0
|
||||
# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:v0.27.0
|
||||
#
|
||||
# - For the `nightly` edition, uncomment either of the following:
|
||||
# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly
|
||||
# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly
|
||||
|
||||
# The embedding service image, model and port.
|
||||
# Important: To enable the embedding service, you need to uncomment one of the following two lines:
|
||||
# COMPOSE_PROFILES=${COMPOSE_PROFILES},tei-cpu
|
||||
# COMPOSE_PROFILES=${COMPOSE_PROFILES},tei-gpu
|
||||
|
||||
# The embedding service image:
|
||||
TEI_IMAGE_CPU=infiniflow/text-embeddings-inference:cpu-1.8
|
||||
TEI_IMAGE_GPU=infiniflow/text-embeddings-inference:1.8
|
||||
|
||||
# The embedding service model:
|
||||
# Available options:
|
||||
# - `Qwen/Qwen3-Embedding-0.6B` (default, requires 25GB RAM/vRAM to load)
|
||||
# - `BAAI/bge-m3` (requires 21GB RAM/vRAM to load)
|
||||
# - `BAAI/bge-small-en-v1.5` (requires 1.2GB RAM/vRAM to load)
|
||||
TEI_MODEL=${TEI_MODEL:-Qwen/Qwen3-Embedding-0.6B}
|
||||
|
||||
# The embedding service port:
|
||||
TEI_HOST=tei
|
||||
# The port used to expose the TEI service to the host machine,
|
||||
# allowing EXTERNAL access to the service running inside the Docker container.
|
||||
TEI_PORT=6380
|
||||
|
||||
# The local time zone.
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# Uncomment the following line if you have limited access to huggingface.co:
|
||||
# HF_ENDPOINT=https://hf-mirror.com
|
||||
|
||||
# Optimizations for MacOS
|
||||
# Uncomment the following line if your operating system is MacOS:
|
||||
# MACOS=1
|
||||
|
||||
# The maximum file size limit (in bytes) for each upload to your dataset or RAGFlow's File system.
|
||||
# To change the 1GB file size limit, uncomment the line below and update as needed.
|
||||
# MAX_CONTENT_LENGTH=1073741824
|
||||
# After updating, ensure `client_max_body_size` in nginx/nginx.conf is updated accordingly.
|
||||
# Note that neither `MAX_CONTENT_LENGTH` nor `client_max_body_size` sets the maximum size for files uploaded to an agent.
|
||||
# See https://ragflow.io/docs/dev/begin_component for details.
|
||||
|
||||
# Controls how many documents are processed in a single batch.
|
||||
# Defaults to 4 if DOC_BULK_SIZE is not explicitly set.
|
||||
DOC_BULK_SIZE=${DOC_BULK_SIZE:-4}
|
||||
|
||||
# Defines the number of items to process per batch when generating embeddings.
|
||||
# Defaults to 16 if EMBEDDING_BATCH_SIZE is not set in the environment.
|
||||
EMBEDDING_BATCH_SIZE=${EMBEDDING_BATCH_SIZE:-16}
|
||||
|
||||
# Log level for the RAGFlow's own and imported packages.
|
||||
# Available levels:
|
||||
# - `DEBUG`
|
||||
# - `INFO` (default)
|
||||
# - `WARNING`
|
||||
# - `ERROR`
|
||||
# For example, the following line changes the log level of `ragflow.es_conn` to `DEBUG`:
|
||||
# LOG_LEVELS=ragflow.es_conn=DEBUG
|
||||
|
||||
# aliyun OSS configuration
|
||||
# STORAGE_IMPL=OSS
|
||||
# ACCESS_KEY=xxx
|
||||
# SECRET_KEY=eee
|
||||
# ENDPOINT=http://oss-cn-hangzhou.aliyuncs.com
|
||||
# REGION=cn-hangzhou
|
||||
# BUCKET=ragflow65536
|
||||
#
|
||||
|
||||
# A user registration switch:
|
||||
# - Enable registration: 1
|
||||
# - Disable registration: 0
|
||||
REGISTER_ENABLED=1
|
||||
ENABLE_REGISTER=1
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Sandbox
|
||||
# -----------------------------------------------------------------------------
|
||||
# Sandbox provider type and runtime settings are configured in Admin > Sandbox
|
||||
# Settings.
|
||||
|
||||
# Enable sandbox support.
|
||||
# SANDBOX_ENABLED=1
|
||||
# COMPOSE_PROFILES=${COMPOSE_PROFILES},sandbox
|
||||
|
||||
# Shared sandbox settings
|
||||
# The MinIO bucket name for storing sandbox-generated artifacts.
|
||||
# SANDBOX_ARTIFACT_BUCKET=sandbox-artifacts
|
||||
|
||||
# Number of days before sandbox artifacts are automatically deleted.
|
||||
# SANDBOX_ARTIFACT_EXPIRE_DAYS=7
|
||||
|
||||
# Self-managed deployment defaults
|
||||
# These values are used by the `sandbox` compose profile and shown in Admin as
|
||||
# deployment defaults for the self-managed provider.
|
||||
# Pull the required base images before running:
|
||||
# docker pull infiniflow/sandbox-base-nodejs:latest
|
||||
# docker pull infiniflow/sandbox-base-python:latest
|
||||
# Default runtime images include:
|
||||
# - Node.js base image: axios
|
||||
# - Python base image: requests, numpy, pandas
|
||||
# SANDBOX_EXECUTOR_MANAGER_IMAGE=${SANDBOX_EXECUTOR_MANAGER_IMAGE:-infiniflow/sandbox-executor-manager:latest}
|
||||
# SANDBOX_EXECUTOR_MANAGER_POOL_SIZE=${SANDBOX_EXECUTOR_MANAGER_POOL_SIZE:-3}
|
||||
# SANDBOX_BASE_PYTHON_IMAGE=${SANDBOX_BASE_PYTHON_IMAGE:-infiniflow/sandbox-base-python:latest}
|
||||
# SANDBOX_BASE_NODEJS_IMAGE=${SANDBOX_BASE_NODEJS_IMAGE:-infiniflow/sandbox-base-nodejs:latest}
|
||||
# SANDBOX_EXECUTOR_MANAGER_PORT=${SANDBOX_EXECUTOR_MANAGER_PORT:-9385}
|
||||
# SANDBOX_ENABLE_SECCOMP=false
|
||||
# SANDBOX_MAX_MEMORY=256m # b, k, m, g
|
||||
# SANDBOX_TIMEOUT=10s # s, m, 1m30s
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Sandbox End
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# Enable DocLing
|
||||
USE_DOCLING=false
|
||||
|
||||
# Enable Mineru
|
||||
# Uncommenting these lines will automatically add MinerU to the model provider whenever possible.
|
||||
# More details see https://ragflow.io/docs/faq#how-to-use-mineru-to-parse-pdf-documents.
|
||||
# MINERU_DELETE_OUTPUT=0 # keep output directory
|
||||
# MINERU_BACKEND=pipeline # or another backend you prefer
|
||||
|
||||
# pptx support
|
||||
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
||||
|
||||
# crypto utils
|
||||
# RAGFLOW_CRYPTO_ENABLED=true
|
||||
# RAGFLOW_CRYPTO_ALGORITHM=aes-256-cbc # one of aes-256-cbc, aes-128-cbc, sm4-cbc
|
||||
# RAGFLOW_CRYPTO_KEY=ragflow-crypto-key
|
||||
|
||||
|
||||
# Used for ThreadPoolExecutor
|
||||
THREAD_POOL_MAX_WORKERS=128
|
||||
|
||||
#Option to disable login form for SSO
|
||||
DISABLE_PASSWORD_LOGIN=false
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# DeepDoc OSS Vision Service
|
||||
# -----------------------------------------------------------------------------
|
||||
# URL for the deepdoc vision API (DLA, OCR, TSR) served by OSS ONNX models.
|
||||
# The `deepdoc` service defined in docker-compose.yml provides this endpoint.
|
||||
# When unset, the parser falls back to inline ONNX Runtime inference.
|
||||
|
||||
# Comment existing COMPOSE_PROFILES and uncomment below if need deepdoc service.
|
||||
# COMPOSE_PROFILES=${DOC_ENGINE},${DEVICE},deepdoc
|
||||
|
||||
# DEEPDOC_URL=http://deepdoc:9390
|
||||
|
||||
# Docker image for the OSS deepdoc service. CPU-only; uses ONNX Runtime.
|
||||
# DEEPDOC_IMAGE=deepdoc_oss:latest
|
||||
@@ -0,0 +1,167 @@
|
||||
include:
|
||||
- ./docker-compose-base.yml
|
||||
# To ensure that the container processes the locally modified `service_conf.yaml.template` instead of the one included in its image, you need to mount the local `service_conf.yaml.template` to the container.
|
||||
services:
|
||||
deepdoc:
|
||||
image: ${DEEPDOC_IMAGE:-deepdoc_oss:latest}
|
||||
profiles:
|
||||
- deepdoc
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: Dockerfile_deepdoc_oss
|
||||
networks:
|
||||
- ragflow
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9390/health"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 60
|
||||
|
||||
ragflow-cpu:
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
profiles:
|
||||
- cpu
|
||||
image: ${RAGFLOW_IMAGE}
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
nproc:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
# Example configuration to set up an MCP server:
|
||||
# command:
|
||||
# - --enable-mcpserver
|
||||
# - --mcp-host=0.0.0.0
|
||||
# - --mcp-port=9382
|
||||
# - --mcp-base-url=http://127.0.0.1:9380
|
||||
# - --mcp-script-path=/ragflow/mcp/server/server.py
|
||||
# - --mcp-mode=self-host
|
||||
# - --mcp-host-api-key=ragflow-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
# Optional transport flags for MCP (customize if needed).
|
||||
# Host mode need to combined with --no-transport-streamable-http-enabled flag, namely, host+streamable-http is not supported yet.
|
||||
# The following are enabled by default unless explicitly disabled with --no-<flag>.
|
||||
# - --no-transport-sse-enabled # Disable legacy SSE endpoints (/sse and /messages/)
|
||||
# - --no-transport-streamable-http-enabled # Disable Streamable HTTP transport (/mcp endpoint)
|
||||
# - --no-json-response # Disable JSON response mode in Streamable HTTP transport (instead of SSE over HTTP)
|
||||
|
||||
# Example configuration to start Admin server:
|
||||
command:
|
||||
- --enable-adminserver
|
||||
#- --init-model-provider-tables
|
||||
ports:
|
||||
- ${SVR_WEB_HTTP_PORT}:80
|
||||
- ${SVR_WEB_HTTPS_PORT}:443
|
||||
- ${SVR_HTTP_PORT}:9380
|
||||
- ${ADMIN_SVR_HTTP_PORT}:9381
|
||||
- ${SVR_MCP_PORT}:9382 # entry for MCP (host_port:docker_port). The docker_port must match the value you set for `mcp-port` above.
|
||||
- ${GO_HTTP_PORT}:9384
|
||||
- ${GO_ADMIN_PORT}:9383
|
||||
volumes:
|
||||
- ./ragflow-logs:/ragflow/logs
|
||||
# - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf
|
||||
# - ./nginx/proxy.conf:/etc/nginx/proxy.conf
|
||||
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template
|
||||
- ./entrypoint-go.sh:/ragflow/entrypoint.sh
|
||||
env_file: .env-go
|
||||
networks:
|
||||
- ragflow
|
||||
restart: unless-stopped
|
||||
# https://docs.docker.com/engine/daemon/prometheus/#create-a-prometheus-configuration
|
||||
# If you use Docker Desktop, the --add-host flag is optional. This flag ensures that the host's internal IP is exposed to the Prometheus container.
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
ragflow-gpu:
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
profiles:
|
||||
- gpu
|
||||
image: ${RAGFLOW_IMAGE}
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
nproc:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
# Example configuration to set up an MCP server:
|
||||
# command:
|
||||
# - --enable-mcpserver
|
||||
# - --mcp-host=0.0.0.0
|
||||
# - --mcp-port=9382
|
||||
# - --mcp-base-url=http://127.0.0.1:9380
|
||||
# - --mcp-script-path=/ragflow/mcp/server/server.py
|
||||
# - --mcp-mode=self-host
|
||||
# - --mcp-host-api-key=ragflow-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
# Optional transport flags for MCP (customize if needed).
|
||||
# Host mode need to combined with --no-transport-streamable-http-enabled flag, namely, host+streamable-http is not supported yet.
|
||||
# The following are enabled by default unless explicitly disabled with --no-<flag>.
|
||||
# - --no-transport-sse-enabled # Disable legacy SSE endpoints (/sse and /messages/)
|
||||
# - --no-transport-streamable-http-enabled # Disable Streamable HTTP transport (/mcp endpoint)
|
||||
# - --no-json-response # Disable JSON response mode in Streamable HTTP transport (instead of SSE over HTTP)
|
||||
|
||||
# Example configuration to start Admin server:
|
||||
command:
|
||||
- --enable-adminserver
|
||||
ports:
|
||||
- ${SVR_WEB_HTTP_PORT}:80
|
||||
- ${SVR_WEB_HTTPS_PORT}:443
|
||||
- ${SVR_HTTP_PORT}:9380
|
||||
- ${ADMIN_SVR_HTTP_PORT}:9381
|
||||
- ${SVR_MCP_PORT}:9382 # entry for MCP (host_port:docker_port). The docker_port must match the value you set for `mcp-port` above.
|
||||
volumes:
|
||||
- ./ragflow-logs:/ragflow/logs
|
||||
# - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf
|
||||
# - ./nginx/proxy.conf:/etc/nginx/proxy.conf
|
||||
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template
|
||||
- ./entrypoint.sh:/ragflow/entrypoint.sh
|
||||
env_file: .env-go
|
||||
networks:
|
||||
- ragflow
|
||||
restart: unless-stopped
|
||||
# https://docs.docker.com/engine/daemon/prometheus/#create-a-prometheus-configuration
|
||||
# If you use Docker Desktop, the --add-host flag is optional. This flag ensures that the host's internal IP is exposed to the Prometheus container.
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
|
||||
|
||||
# executor:
|
||||
# depends_on:
|
||||
# mysql:
|
||||
# condition: service_healthy
|
||||
# image: ${RAGFLOW_IMAGE}
|
||||
# volumes:
|
||||
# - ./ragflow-logs:/ragflow/logs
|
||||
# - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf
|
||||
# env_file: .env
|
||||
# entrypoint: "/ragflow/entrypoint_task_executor.sh 1 3"
|
||||
# networks:
|
||||
# - ragflow
|
||||
# restart: unless-stopped
|
||||
# # https://docs.docker.com/engine/daemon/prometheus/#create-a-prometheus-configuration
|
||||
# # If you're using Docker Desktop, the --add-host flag is optional. This flag makes sure that the host's internal IP gets exposed to the Prometheus container.
|
||||
# extra_hosts:
|
||||
# - "host.docker.internal:host-gateway"
|
||||
# deploy:
|
||||
# resources:
|
||||
# reservations:
|
||||
# devices:
|
||||
# - driver: nvidia
|
||||
# count: all
|
||||
# capabilities: [gpu]
|
||||
Executable
+366
@@ -0,0 +1,366 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Start RAGFlow cluster, version: "
|
||||
cat /ragflow/VERSION
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Usage and command-line argument parsing
|
||||
# -----------------------------------------------------------------------------
|
||||
function usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo
|
||||
echo " --disable-webserver Disables the web server (nginx + ragflow_server)."
|
||||
echo " --disable-taskexecutor Disables task executor workers."
|
||||
echo " --disable-datasync Disables synchronization of datasource workers."
|
||||
echo " --enable-mcpserver Enables the MCP server."
|
||||
echo " --enable-adminserver Enables the Admin server."
|
||||
echo " --init-model-provider-tables Run model provider table migrations and exit."
|
||||
echo " --init-superuser Initializes the superuser."
|
||||
echo " --consumer-no-beg=<num> Start range for consumers (if using range-based)."
|
||||
echo " --consumer-no-end=<num> End range for consumers (if using range-based)."
|
||||
echo " --workers=<num> Number of task executors to run (if range is not used)."
|
||||
echo " --host-id=<string> Unique ID for the host (defaults to \`hostname\`)."
|
||||
echo " --mcp-host=<string> Address the MCP server binds to (default: 127.0.0.1)."
|
||||
echo " --mcp-port=<num> Port the MCP server listens on (default: 9382)."
|
||||
echo " --mcp-base-url=<string> RAGFlow base URL the MCP server calls (default: http://127.0.0.1:9380)."
|
||||
echo " --mcp-script-path=<path> MCP server entry script (default: /ragflow/mcp/server/server.py)."
|
||||
echo " --mcp-mode=<self-host|host> MCP server mode (default: self-host)."
|
||||
echo " --mcp-host-api-key=<string> API key required when --mcp-mode=self-host."
|
||||
echo " --no-transport-sse-enabled Disables the MCP SSE transport."
|
||||
echo " --no-transport-streamable-http-enabled Disables the MCP streamable HTTP transport. Disabling"
|
||||
echo " both transports re-enables this one, since the server"
|
||||
echo " requires at least one."
|
||||
echo " --no-json-response Disables JSON responses from the MCP server."
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " $0 --disable-taskexecutor"
|
||||
echo " $0 --disable-webserver --consumer-no-beg=0 --consumer-no-end=5"
|
||||
echo " $0 --disable-webserver --workers=2 --host-id=myhost123"
|
||||
echo " $0 --enable-mcpserver"
|
||||
echo " $0 --enable-adminserver"
|
||||
echo " $0 --init-superuser"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ENABLE_WEBSERVER=1 # Default to enable web server
|
||||
ENABLE_TASKEXECUTOR=1 # Default to enable task executor
|
||||
ENABLE_DATASYNC=1
|
||||
ENABLE_MCP_SERVER=0
|
||||
ENABLE_ADMIN_SERVER=0 # Default close admin server
|
||||
INIT_SUPERUSER_ARGS="" # Default to not initialize superuser
|
||||
INIT_MODEL_PROVIDER_TABLES=0
|
||||
CONSUMER_NO_BEG=0
|
||||
CONSUMER_NO_END=0
|
||||
WORKERS=1
|
||||
|
||||
MCP_HOST="127.0.0.1"
|
||||
MCP_PORT=9382
|
||||
MCP_BASE_URL="http://127.0.0.1:9380"
|
||||
MCP_SCRIPT_PATH="/ragflow/mcp/server/server.py"
|
||||
MCP_MODE="self-host"
|
||||
MCP_HOST_API_KEY=""
|
||||
MCP_TRANSPORT_SSE_FLAG="--transport-sse-enabled"
|
||||
MCP_TRANSPORT_STREAMABLE_HTTP_FLAG="--transport-streamable-http-enabled"
|
||||
MCP_JSON_RESPONSE_FLAG="--json-response"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Host ID logic:
|
||||
# 1. By default, use the system hostname if length <= 32
|
||||
# 2. Otherwise, use the full MD5 hash of the hostname (32 hex chars)
|
||||
# -----------------------------------------------------------------------------
|
||||
CURRENT_HOSTNAME="$(hostname)"
|
||||
if [ ${#CURRENT_HOSTNAME} -le 32 ]; then
|
||||
DEFAULT_HOST_ID="$CURRENT_HOSTNAME"
|
||||
else
|
||||
DEFAULT_HOST_ID="$(echo -n "$CURRENT_HOSTNAME" | md5sum | cut -d ' ' -f 1)"
|
||||
fi
|
||||
|
||||
HOST_ID="$DEFAULT_HOST_ID"
|
||||
|
||||
# Parse arguments
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--disable-webserver)
|
||||
ENABLE_WEBSERVER=0
|
||||
shift
|
||||
;;
|
||||
--disable-taskexecutor)
|
||||
ENABLE_TASKEXECUTOR=0
|
||||
shift
|
||||
;;
|
||||
--disable-datasync)
|
||||
ENABLE_DATASYNC=0
|
||||
shift
|
||||
;;
|
||||
--enable-mcpserver)
|
||||
ENABLE_MCP_SERVER=1
|
||||
shift
|
||||
;;
|
||||
--enable-adminserver)
|
||||
ENABLE_ADMIN_SERVER=1
|
||||
shift
|
||||
;;
|
||||
--init-model-provider-tables)
|
||||
INIT_MODEL_PROVIDER_TABLES=1
|
||||
shift
|
||||
;;
|
||||
--init-superuser)
|
||||
INIT_SUPERUSER_ARGS="--init-superuser"
|
||||
shift
|
||||
;;
|
||||
--mcp-host=*)
|
||||
MCP_HOST="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--mcp-port=*)
|
||||
MCP_PORT="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--mcp-base-url=*)
|
||||
MCP_BASE_URL="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--mcp-mode=*)
|
||||
MCP_MODE="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--mcp-host-api-key=*)
|
||||
MCP_HOST_API_KEY="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--mcp-script-path=*)
|
||||
MCP_SCRIPT_PATH="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--no-transport-sse-enabled)
|
||||
MCP_TRANSPORT_SSE_FLAG="--no-transport-sse-enabled"
|
||||
shift
|
||||
;;
|
||||
--no-transport-streamable-http-enabled)
|
||||
MCP_TRANSPORT_STREAMABLE_HTTP_FLAG="--no-transport-streamable-http-enabled"
|
||||
shift
|
||||
;;
|
||||
--no-json-response)
|
||||
MCP_JSON_RESPONSE_FLAG="--no-json-response"
|
||||
shift
|
||||
;;
|
||||
--consumer-no-beg=*)
|
||||
CONSUMER_NO_BEG="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--consumer-no-end=*)
|
||||
CONSUMER_NO_END="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--workers=*)
|
||||
WORKERS="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--host-id=*)
|
||||
HOST_ID="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Replace env variables in the service_conf.yaml file
|
||||
# -----------------------------------------------------------------------------
|
||||
CONF_DIR="/ragflow/conf"
|
||||
TEMPLATE_FILE="${CONF_DIR}/service_conf.yaml.template"
|
||||
CONF_FILE="${CONF_DIR}/service_conf.yaml"
|
||||
|
||||
rm -f "${CONF_FILE}"
|
||||
DEF_ENV_VALUE_PATTERN="\$\{([^:]+):-([^}]+)\}"
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
if [[ "$line" =~ DEF_ENV_VALUE_PATTERN ]]; then
|
||||
varname="${BASH_REMATCH[1]}"
|
||||
default="${BASH_REMATCH[2]}"
|
||||
|
||||
if [ -n "${!varname}" ]; then
|
||||
eval "echo \"$line"\" >> "${CONF_FILE}"
|
||||
else
|
||||
echo "$line" | sed -E "s/\\\$\{[^:]+:-([^}]+)\}/\1/g" >> "${CONF_FILE}"
|
||||
fi
|
||||
else
|
||||
eval "echo \"$line\"" >> "${CONF_FILE}"
|
||||
fi
|
||||
done < "${TEMPLATE_FILE}"
|
||||
|
||||
export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/"
|
||||
PY=python3
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Select Nginx Configuration based on API_PROXY_SCHEME
|
||||
# -----------------------------------------------------------------------------
|
||||
NGINX_CONF_DIR="/etc/nginx/conf.d"
|
||||
if [ -n "$API_PROXY_SCHEME" ]; then
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]]; then
|
||||
cp -f "$NGINX_CONF_DIR/ragflow.conf.hybrid" "$NGINX_CONF_DIR/ragflow.conf"
|
||||
echo "Applied nginx config: ragflow.conf.hybrid"
|
||||
elif [[ "${API_PROXY_SCHEME}" == "go" ]]; then
|
||||
cp -f "$NGINX_CONF_DIR/ragflow.conf.golang" "$NGINX_CONF_DIR/ragflow.conf"
|
||||
echo "Applied nginx config: ragflow.conf.golang (default)"
|
||||
else
|
||||
cp -f "$NGINX_CONF_DIR/ragflow.conf.python" "$NGINX_CONF_DIR/ragflow.conf"
|
||||
echo "Applied nginx config: ragflow.conf.python"
|
||||
fi
|
||||
else
|
||||
# Default to python backend
|
||||
cp -f "$NGINX_CONF_DIR/ragflow.conf.python" "$NGINX_CONF_DIR/ragflow.conf"
|
||||
echo "Default: applied nginx config: ragflow.conf.python"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Function(s)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
function task_exe() {
|
||||
local consumer_id="$1"
|
||||
local host_id="$2"
|
||||
|
||||
JEMALLOC_PATH="$(pkg-config --variable=libdir jemalloc)/libjemalloc.so"
|
||||
while true; do
|
||||
LD_PRELOAD="$JEMALLOC_PATH" \
|
||||
"$PY" rag/svr/task_executor.py -i "${host_id}_${consumer_id}" -t "common" &
|
||||
wait;
|
||||
sleep 1;
|
||||
done
|
||||
}
|
||||
|
||||
function start_mcp_server() {
|
||||
echo "Starting MCP Server on ${MCP_HOST}:${MCP_PORT} with base URL ${MCP_BASE_URL}..."
|
||||
"$PY" "${MCP_SCRIPT_PATH}" \
|
||||
--host="${MCP_HOST}" \
|
||||
--port="${MCP_PORT}" \
|
||||
--base-url="${MCP_BASE_URL}" \
|
||||
--mode="${MCP_MODE}" \
|
||||
--api-key="${MCP_HOST_API_KEY}" \
|
||||
"${MCP_TRANSPORT_SSE_FLAG}" \
|
||||
"${MCP_TRANSPORT_STREAMABLE_HTTP_FLAG}" \
|
||||
"${MCP_JSON_RESPONSE_FLAG}" &
|
||||
}
|
||||
|
||||
function ensure_docling() {
|
||||
[[ "${USE_DOCLING}" == "true" ]] || { echo "[docling] disabled by USE_DOCLING"; return 0; }
|
||||
DOCLING_PIN="${DOCLING_VERSION:-==2.71.0}"
|
||||
"$PY" -c "import importlib.util,sys; sys.exit(0 if importlib.util.find_spec('docling') else 1)" \
|
||||
|| uv pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --extra-index-url https://pypi.org/simple --no-cache-dir "docling${DOCLING_PIN}"
|
||||
}
|
||||
|
||||
function ensure_db_init() {
|
||||
echo "Initializing database tables..."
|
||||
"$PY" -c "from api.db.db_models import init_database_tables as init_web_db; init_web_db()"
|
||||
echo "Database tables initialized."
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Start components based on flags
|
||||
# -----------------------------------------------------------------------------
|
||||
#ensure_docling
|
||||
#ensure_db_init
|
||||
|
||||
run_with_restart() {
|
||||
local process_name="$1"
|
||||
shift
|
||||
|
||||
while true; do
|
||||
echo "Attempt to start ${process_name}..."
|
||||
set +e
|
||||
"$@"
|
||||
local exit_code=$?
|
||||
set -e
|
||||
echo "${process_name} exited with code ${exit_code}. Restarting in 1 second..."
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
if [[ "${INIT_MODEL_PROVIDER_TABLES}" -eq 1 ]]; then
|
||||
DB_TYPE_NORMALIZED="${DB_TYPE:-mysql}"
|
||||
DB_TYPE_NORMALIZED="${DB_TYPE_NORMALIZED,,}"
|
||||
if [[ "${DB_TYPE_NORMALIZED}" == "gaussdb" || "${DB_TYPE_NORMALIZED}" == "gauss" ]]; then
|
||||
# This migration script contains MySQL-only SQL and cannot run against
|
||||
# a GaussDB metadata database.
|
||||
echo "Skipping MySQL-specific model provider table migrations for DB_TYPE=${DB_TYPE:-mysql}."
|
||||
else
|
||||
tools/scripts/run_migrations.sh
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${ENABLE_ADMIN_SERVER}" -eq 1 ]]; then
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "python" ]]; then
|
||||
echo "Attempt to start Admin python server..."
|
||||
run_with_restart "Admin python server" "$PY" admin/server/admin_server.py &
|
||||
fi
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "go" ]]; then
|
||||
echo "Starting Admin go server..."
|
||||
run_with_restart "Admin go server" bin/ragflow_server --admin &
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${ENABLE_WEBSERVER}" -eq 1 ]]; then
|
||||
echo "Starting nginx..."
|
||||
/usr/sbin/nginx -c /etc/nginx/nginx.conf
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "python" ]]; then
|
||||
echo "Attempt to start RAGFlow python server..."
|
||||
run_with_restart "RAGFlow python server" "$PY" api/ragflow_server.py ${INIT_SUPERUSER_ARGS} &
|
||||
fi
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "go" ]]; then
|
||||
echo "Starting RAGFlow go server..."
|
||||
run_with_restart "RAGFlow go server" bin/ragflow_server --api &
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${ENABLE_DATASYNC}" -eq 1 ]]; then
|
||||
echo "Starting data sync..."
|
||||
run_with_restart "RAGFlow go server" bin/ragflow_server --syncer &
|
||||
fi
|
||||
|
||||
#if [[ "${ENABLE_MCP_SERVER}" -eq 1 ]]; then
|
||||
# start_mcp_server
|
||||
#fi
|
||||
|
||||
|
||||
if [[ "${ENABLE_TASKEXECUTOR}" -eq 1 ]]; then
|
||||
if [[ "${CONSUMER_NO_END}" -gt "${CONSUMER_NO_BEG}" ]]; then
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "python" ]]; then
|
||||
echo "Starting python task executors on host '${HOST_ID}' for IDs in [${CONSUMER_NO_BEG}, ${CONSUMER_NO_END})..."
|
||||
for (( i=CONSUMER_NO_BEG; i<CONSUMER_NO_END; i++ ))
|
||||
do
|
||||
task_exe "${i}" "${HOST_ID}" &
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "go" ]]; then
|
||||
echo "Starting go ingestor..."
|
||||
run_with_restart "ingestor" bin/ragflow_server --ingestor &
|
||||
fi
|
||||
else
|
||||
# Otherwise, start a fixed number of workers
|
||||
echo "Starting ${WORKERS} task executor(s) on host '${HOST_ID}'..."
|
||||
for (( i=0; i<WORKERS; i++ ))
|
||||
do
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "python" ]]; then
|
||||
echo "Starting python task executor..."
|
||||
task_exe "${i}" "${HOST_ID}" &
|
||||
sleep 1;
|
||||
fi
|
||||
|
||||
if [[ "${API_PROXY_SCHEME}" == "hybrid" ]] || [[ "${API_PROXY_SCHEME}" == "go" ]]; then
|
||||
echo "Starting go ingestor..."
|
||||
run_with_restart "ingestor" bin/ragflow_server --ingestor &
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
wait
|
||||
Reference in new issue
Block a user