mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-10-24 23:12:53 +08:00
Host-runtime plugins (runtime: { type: host, kind: binary }) now install and
run. Each node's host starts the package's binary for its OS and arch as a
child process and only lets calls through once the process printed its
handshake, answers health checks, and reports the installed plugin ID,
version and protocol and every code contribution plugin.yaml declares. A
crash or three failed health checks restarts it with backoff; the node
reports the plugin degraded meanwhile. An upgrade starts the new process
before stopping the old one. Linux children die with WeKnora.
Isolation: the child gets a private unix socket and a random token, an
environment built from scratch so WeKnora's own secrets never reach plugin
code, and HTTP(S)_PROXY pointing at a per-plugin egress proxy that forwards
only to the hosts in permissions.egress, through the SSRF-safe dialer.
Manifests of code plugins must declare apiVersion weknora.plugin/v1, and
egress entries must be host names or *.domain wildcards. Web search and data
source connectors are open to third-party code plugins. The installer
accepts host packages that carry a binary for the server's OS and arch.
159 lines
5.7 KiB
Docker
159 lines
5.7 KiB
Docker
# Build extension and daemon from the same pinned source on the runtime architecture.
|
|
FROM --platform=$TARGETPLATFORM node:24-bookworm-slim@sha256:ba849c60be29959425b8734d57b8b4b7d56f98edd9504c9af091d5281095a71e AS browserskill
|
|
WORKDIR /build
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends git python3 ca-certificates curl build-essential cmake pkg-config && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo
|
|
ENV PATH=/usr/local/cargo/bin:$PATH
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable
|
|
COPY scripts/build_browserskill.sh scripts/browserskill-release.json ./scripts/
|
|
ARG TARGETOS
|
|
ARG TARGETARCH
|
|
RUN bash scripts/build_browserskill.sh /opt/weknora/browserskill "${TARGETOS}/${TARGETARCH}"
|
|
|
|
# Build stage
|
|
FROM golang:1.26-bookworm AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
# 通过构建参数接收敏感信息
|
|
ARG GOPRIVATE_ARG
|
|
ARG GOPROXY_ARG
|
|
ARG GOSUMDB_ARG=off
|
|
ARG APK_MIRROR_ARG
|
|
|
|
# 设置Go环境变量
|
|
ENV GOPRIVATE=${GOPRIVATE_ARG}
|
|
ENV GOPROXY=${GOPROXY_ARG}
|
|
ENV GOSUMDB=${GOSUMDB_ARG}
|
|
|
|
# Install dependencies
|
|
RUN if [ -n "$APK_MIRROR_ARG" ]; then \
|
|
sed -i "s@deb.debian.org@${APK_MIRROR_ARG}@g" /etc/apt/sources.list.d/debian.sources; \
|
|
fi && \
|
|
apt-get update && \
|
|
apt-get install -y git build-essential libsqlite3-dev curl
|
|
|
|
# Install migrate tool
|
|
RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
|
|
|
|
# Copy go mod files. go.mod replace-points anydoc at ./third_party/anydoc-go
|
|
# and the plugin SDK at ./pluginsdk, so their go.mod files must exist before
|
|
# `go mod download`.
|
|
COPY go.mod go.sum ./
|
|
COPY third_party/anydoc-go/go.mod third_party/anydoc-go/go.mod
|
|
COPY pluginsdk/go.mod pluginsdk/go.mod
|
|
RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
|
COPY cmd/download cmd/download
|
|
RUN go run cmd/download/duckdb/duckdb.go
|
|
COPY . .
|
|
RUN --mount=type=cache,target=/go/pkg/mod bash ./scripts/copy-licenses.sh /license-bundle
|
|
|
|
# Get version and commit info for build injection
|
|
ARG VERSION_ARG
|
|
ARG COMMIT_ID_ARG
|
|
ARG BUILD_TIME_ARG
|
|
ARG GO_VERSION_ARG
|
|
|
|
# Set build-time variables
|
|
ENV VERSION=${VERSION_ARG}
|
|
ENV COMMIT_ID=${COMMIT_ID_ARG}
|
|
ENV BUILD_TIME=${BUILD_TIME_ARG}
|
|
ENV GO_VERSION=${GO_VERSION_ARG}
|
|
|
|
# Link the anydoc parser engine (office docs converted in-process, no
|
|
# Python docreader). Default on so Hub / compose images ship a working
|
|
# engine; pass WITH_ANYDOC=0 to skip the Rust toolchain (~few minutes and
|
|
# ~1 GB of build-stage layers).
|
|
ARG WITH_ANYDOC=1
|
|
ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo
|
|
ENV PATH=/usr/local/cargo/bin:$PATH
|
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,target=/usr/local/cargo/git \
|
|
if [ "$WITH_ANYDOC" = "1" ]; then \
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
|
| sh -s -- -y --profile minimal --default-toolchain stable && \
|
|
./scripts/build-anydoc-lib.sh; \
|
|
fi
|
|
|
|
# Build the application with version info
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
if [ "$WITH_ANYDOC" = "1" ]; then \
|
|
make build-prod GO_BUILD_TAGS=anydoc; \
|
|
else \
|
|
make build-prod; \
|
|
fi
|
|
RUN --mount=type=cache,target=/go/pkg/mod cp -r /go/pkg/mod/github.com/yanyiwu/ /app/yanyiwu/
|
|
|
|
# Final stage
|
|
FROM debian:12.12-slim
|
|
|
|
WORKDIR /app
|
|
|
|
ARG APK_MIRROR_ARG
|
|
|
|
# Pairing derives the gateway URL from the user's page origin by default.
|
|
ENV BROWSERSKILL_BINARY=/opt/weknora/browserskill/bsk \
|
|
BROWSERSKILL_EXTENSION_PATH=/opt/weknora/browserskill/browser-skill-weknora-0.3.1.zip
|
|
COPY --from=browserskill /opt/weknora/browserskill /opt/weknora/browserskill
|
|
|
|
# Create a non-root user first
|
|
RUN useradd -m -s /bin/bash appuser
|
|
|
|
# First, install ca-certificates without mirror to ensure HTTPS works
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends ca-certificates && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Then switch to mirror if specified and install other packages
|
|
RUN if [ -n "$APK_MIRROR_ARG" ]; then \
|
|
sed -i "s@deb.debian.org@${APK_MIRROR_ARG}@g" /etc/apt/sources.list.d/debian.sources; \
|
|
fi && \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
build-essential postgresql-client default-mysql-client tzdata sed curl bash vim wget \
|
|
libsqlite3-0 \
|
|
python3 python3-pip python3-dev libffi-dev libssl-dev \
|
|
nodejs npm \
|
|
gosu \
|
|
ffmpeg && \
|
|
python3 -m pip install --break-system-packages --upgrade pip setuptools wheel && \
|
|
mkdir -p /home/appuser/.local/bin && \
|
|
curl -LsSf https://astral.sh/uv/install.sh | CARGO_HOME=/home/appuser/.cargo UV_INSTALL_DIR=/home/appuser/.local/bin sh && \
|
|
chown -R appuser:appuser /home/appuser && \
|
|
ln -sf /home/appuser/.local/bin/uvx /usr/local/bin/uvx && \
|
|
chmod +x /usr/local/bin/uvx && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create data directories and set permissions
|
|
RUN mkdir -p /data/files && \
|
|
chown -R appuser:appuser /app /data/files
|
|
|
|
# Copy migrate tool from builder stage
|
|
COPY --from=builder /go/bin/migrate /usr/local/bin/
|
|
COPY --from=builder /app/yanyiwu/ /go/pkg/mod/github.com/yanyiwu/
|
|
|
|
# Copy the binary from the builder stage
|
|
COPY --from=builder /app/config ./config
|
|
COPY --from=builder /app/scripts ./scripts
|
|
COPY --from=builder /app/migrations ./migrations
|
|
COPY --from=builder /app/dataset/samples ./dataset/samples
|
|
COPY --from=builder /root/.duckdb /home/appuser/.duckdb
|
|
COPY --from=builder /app/WeKnora .
|
|
COPY --from=builder /license-bundle/ ./
|
|
|
|
# Copy and make entrypoint script executable
|
|
COPY --from=builder /app/scripts/docker-entrypoint.sh ./scripts/docker-entrypoint.sh
|
|
|
|
# Make scripts executable
|
|
RUN chmod +x ./scripts/*.sh
|
|
|
|
# Expose ports
|
|
EXPOSE 8080
|
|
|
|
|
|
ENTRYPOINT ["./scripts/docker-entrypoint.sh"]
|
|
CMD ["./WeKnora"]
|