Files
OpenViking/Dockerfile
T
Hao Zheandzhiheng.liu c61471ddc4 fix(deploy): harden bot and server deployment configuration (#3547)
* fix(bot): only require VKE credentials when the TOS storage path needs them

Sweep findings: C-14. Gate AK/SK validation on an actual TOS deployment and drop the unused cluster ID.

(cherry picked from commit 8790ba509f)

* fix(server): apply configured temp_upload.default_mode to uploads

Sweep findings: B-11, D-01. Apply the documented configured upload mode when requests omit it.

(cherry picked from commit a0dc2498e8)

* fix(bot): make one-click Docker deployment generate a working config and port mapping

Sweep findings: C-12. Generate the active ov.conf and keep gateway and Docker ports aligned.

(cherry picked from commit c22af83ab6)

* fix(server): make --bot work and propagate bot flags to workers

Sweep findings: B-09, B-15. Honor the public Bot alias and replay resolved Bot settings in worker processes.

(cherry picked from commit 32a898ca14)

* fix(docker): derive entrypoint/health port from configured server port

Sweep findings: F-06. Keep server startup and every container health check on the same effective port.

(cherry picked from commit 000795c7e3)

---------

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>
2026-07-28 18:11:26 +08:00

130 lines
5.3 KiB
Docker

# syntax=docker/dockerfile:1.9
# Stage 1: provide Rust toolchain (required by setup.py -> build_ov_cli_artifact -> cargo build)
# ragfs-python's default S3-enabled dependency set currently requires rustc >= 1.91.1.
FROM rust:1.91.1-trixie AS rust-toolchain
# Stage 2: build Python environment with uv (builds Rust CLI + C++ extension + web-studio from source)
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS py-builder
# Reuse Rust toolchain from stage 1 so setup.py can compile ov CLI in-place.
COPY --from=rust-toolchain /usr/local/cargo /usr/local/cargo
COPY --from=rust-toolchain /usr/local/rustup /usr/local/rustup
# Provide Node.js so setup.py build_py can build web-studio SPA in-tree.
COPY --from=node:24-trixie-slim /usr/local/bin/node /usr/local/bin/
COPY --from=node:24-trixie-slim /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -sf ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& ln -sf ../lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
ENV CARGO_HOME=/usr/local/cargo
ENV RUSTUP_HOME=/usr/local/rustup
ENV PATH="/app/.venv/bin:/usr/local/cargo/bin:${PATH}"
ARG OPENVIKING_VERSION=
ARG TARGETPLATFORM
ARG UV_LOCK_STRATEGY=auto
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
ccache \
cmake \
git \
&& rm -rf /var/lib/apt/lists/*
# Route gcc/g++/cc through ccache so cmake (which asks shutil.which("gcc")) picks
# up /usr/lib/ccache/gcc and benefits from the BuildKit cache mount on /root/.ccache.
ENV PATH="/usr/lib/ccache:${PATH}"
ENV CCACHE_DIR=/root/.ccache
# Pin Cargo's target dir to a stable path so a BuildKit cache mount can persist
# build artifacts across layer reruns even when uv builds the wheel in an
# ephemeral isolated tempdir.
ENV CARGO_TARGET_DIR=/cargo-target
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy
ENV UV_NO_DEV=1
WORKDIR /app
# Copy source required for setup.py artifact builds and native extension build.
COPY Cargo.toml Cargo.lock ./
COPY pyproject.toml uv.lock setup.py README.md ./
COPY build_support/ build_support/
COPY bot/ bot/
COPY crates/ crates/
COPY openviking/ openviking/
COPY openviking_cli/ openviking_cli/
COPY src/ src/
COPY third_party/ third_party/
COPY web-studio/ web-studio/
# Install project and dependencies (triggers setup.py build_py → web-studio
# SPA build + build_ext → native extensions).
# Default to auto-refreshing uv.lock inside the ephemeral build context when it is
# stale, so Docker builds stay unblocked after dependency changes. Set
# UV_LOCK_STRATEGY=locked to keep fail-fast reproducibility checks.
RUN --mount=type=cache,target=/root/.cache/uv,id=uv-${TARGETPLATFORM} \
--mount=type=cache,target=/root/.npm,id=npm-${TARGETPLATFORM} \
--mount=type=cache,target=/cargo-target,id=cargo-target-${TARGETPLATFORM} \
--mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry-${TARGETPLATFORM} \
--mount=type=cache,target=/usr/local/cargo/git,id=cargo-git-${TARGETPLATFORM} \
--mount=type=cache,target=/root/.ccache,id=ccache-${TARGETPLATFORM} \
if [ -n "${OPENVIKING_VERSION:-}" ]; then \
export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENVIKING="${OPENVIKING_VERSION}"; \
elif [ -f openviking/_version.py ]; then \
export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENVIKING="$(python -c "import runpy; print(runpy.run_path('openviking/_version.py')['version'])")"; \
else \
echo "OPENVIKING_VERSION build arg is required when building without openviking/_version.py" >&2; \
exit 2; \
fi; \
case "${UV_LOCK_STRATEGY}" in \
locked) \
uv sync --locked --no-editable --extra bot --extra gemini \
;; \
auto) \
if ! uv lock --check; then \
uv lock; \
fi; \
uv sync --locked --no-editable --extra bot --extra gemini \
;; \
*) \
echo "Unsupported UV_LOCK_STRATEGY: ${UV_LOCK_STRATEGY}" >&2; \
exit 2 \
;; \
esac
# Stage 3: runtime
FROM python:3.13-slim-trixie
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
libstdc++6 \
ripgrep \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=py-builder /app/.venv /app/.venv
COPY docker/openviking-entrypoint.sh /usr/local/bin/openviking-entrypoint
COPY docker/pending_health_server.py /usr/local/bin/openviking-pending-health
RUN mkdir -p /app/.openviking \
&& chmod +x /usr/local/bin/openviking-entrypoint /usr/local/bin/openviking-pending-health
ENV HOME="/app" \
PATH="/app/.venv/bin:$PATH" \
OPENVIKING_CONFIG_FILE="/app/.openviking/ov.conf" \
OPENVIKING_CLI_CONFIG_FILE="/app/.openviking/ovcli.conf"
EXPOSE 1933
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD ["openviking-entrypoint", "--healthcheck"]
# All persistent state (ov.conf, ovcli.conf, workspace data) lives under
# /app/.openviking, which mirrors the host's ~/.openviking layout. Mount one
# volume there to persist everything across container restarts:
# docker run -v ~/.openviking:/app/.openviking <image>
# If ov.conf is absent on first start, set OPENVIKING_CONF_CONTENT to the full
# JSON, or `docker exec` in and run `openviking-server init`.
# Override command to run CLI, e.g.:
# docker run --rm -v ~/.openviking:/app/.openviking <image> openviking --help
ENTRYPOINT ["openviking-entrypoint"]