Skip to content

Deployment

std-tools is designed to run inside a container that your application controls (see Security). This page gives the container patterns.

A base image

# syntax=docker/dockerfile:1
FROM python:3.12-slim

# git, for pip to install std-tools from its repository. LibreOffice, for
# convert_document and to render Word, Excel and PowerPoint pages as images; leave it
# out if the agent only reads and renders PDFs.
RUN apt-get update && apt-get install -y --no-install-recommends \
        git \
        libreoffice-core libreoffice-writer libreoffice-calc libreoffice-impress \
    && rm -rf /var/lib/apt/lists/*

# std-tools with every extra, pinned to a release tag, in the same pip command as your
# application's own requirements so pip resolves them together. The repository is
# private: the GitHub token arrives as a build secret and git adds it to the URL for
# this one command, so it is stored in no layer and not in pip's install record.
COPY requirements.txt .
RUN --mount=type=secret,id=github_token \
    GIT_CONFIG_COUNT=1 \
    GIT_CONFIG_KEY_0="url.https://x-access-token:$(cat /run/secrets/github_token)@github.com/.insteadOf" \
    GIT_CONFIG_VALUE_0="https://github.com/" \
    pip install --no-cache-dir -r requirements.txt \
        "doc-processing-std-tools[all] @ git+https://github.com/rzoeb/doc-processing-std-tools.git@v0.6.1"

# Run as a non-root user.
RUN useradd -m agent
USER agent
WORKDIR /workspace

Notes:

  • Installing from the repository needs read access to it at build time. Build with a GitHub token passed as a build secret (Docker 23 or later; a fine-grained token with read-only Contents access is enough):

    GITHUB_TOKEN=<token> docker build --secret id=github_token,env=GITHUB_TOKEN -t my-agent-image .
    

    Never put the token in a RUN command, an ARG or an ENV: those are kept in the image. - Choose extras instead of [all] to keep the image small: docs for document and image tools, ocr, web, extract (trafilatura, for cleaner page text), screenshot, browser, computer. See Quickstart. - Fonts. LibreOffice renders with the fonts installed in the image. For documents in Chinese, Japanese or Korean, add a CJK font package such as fonts-noto-cjk, or pages render with missing characters. - If LibreOffice is installed somewhere other than PATH, point DPTTOOLS_SOFFICE_BIN at its soffice executable. - The repository also contains docker/integration.Dockerfile, a Linux image for running the integration tests (LibreOffice, Xvfb, xdotool, CJK fonts). It is a test image, not a deployment pattern. - take_screenshot needs a display; in a headless container it returns an error, so the screenshot extra is rarely useful there.

Running it

Pattern How
In your agent's process Install std-tools in the agent's image and attach the servers in-process (Using with the Toolkit)
A launcher your agent starts Start python -m doc_processing_std_tools over stdio from your application, passing configuration in env
A separate HTTP service python -m doc_processing_std_tools --transport http --host 0.0.0.0 --port 8000 in its own container, reachable only by your agent, behind an authenticating proxy or network policy

A docker run for the first pattern:

docker run --rm \
  --user agent \
  -v /host/project:/workspace:rw \
  -v /host/memory:/workspace/.memory:rw \
  -v /host/skills:/workspace/.agent_skills:ro \
  --memory=2g --cpus=2 \
  --env-file agent.env \
  my-agent-image python run_agent.py

where agent.env holds, for example:

DPTTOOLS_MEMORY_DIR=/workspace/.memory
DPTTOOLS_SKILLS_DIR=/workspace/.agent_skills
DPTTOOLS_WEB_SEARCH_PROVIDER=tavily
DPTTOOLS_WEB_SEARCH_API_KEY=tvly-xxx
  • Memory should live on a persistent volume, or it is lost with the container.
  • Skills can be mounted read-only unless the agent should create skills.
  • Network. Add --network=none when the agent needs no internet; the Web server and OCR need outbound access.
  • Configuration is read once per process, so restart after changing it. The Configuration page lists every variable.

To check what is installed in a running container:

python -c "import doc_processing_std_tools as d; print(d.__version__)"

__version__ (new in 0.6.0) comes from the installed package metadata.

With the browser and a virtual desktop

The same pattern with Chromium for the browser server and an Xvfb desktop for the computer server added. Playwright keeps its browsers per user, so Chromium itself is installed as the agent user (or set PLAYWRIGHT_BROWSERS_PATH to a shared directory):

# syntax=docker/dockerfile:1
FROM python:3.12-slim

# git for the install, a virtual desktop for the computer server (add x11vnc if a
# person should watch), fonts, and the desktop applications the agent should use
RUN apt-get update && apt-get install -y --no-install-recommends \
        git \
        xvfb xdotool openbox fonts-dejavu-core fonts-liberation \
        libreoffice-core libreoffice-writer libreoffice-calc libreoffice-impress \
    && rm -rf /var/lib/apt/lists/*

# Installed as in the base image: the token is a build secret
COPY requirements.txt .
RUN --mount=type=secret,id=github_token \
    GIT_CONFIG_COUNT=1 \
    GIT_CONFIG_KEY_0="url.https://x-access-token:$(cat /run/secrets/github_token)@github.com/.insteadOf" \
    GIT_CONFIG_VALUE_0="https://github.com/" \
    pip install --no-cache-dir -r requirements.txt \
        "doc-processing-std-tools[all] @ git+https://github.com/rzoeb/doc-processing-std-tools.git@v0.6.1"
# Chromium's system libraries (as root)
RUN python -m playwright install-deps chromium

RUN useradd -m agent
USER agent
WORKDIR /workspace
# The browser itself (as the agent user)
RUN python -m playwright install chromium
ENV DPTTOOLS_ENABLE_BROWSER=true \
    DPTTOOLS_ENABLE_COMPUTER=true

The browser server needs network access to the sites it visits, so it does not combine with --network=none; narrow it with DPTTOOLS_BROWSER_ALLOWED_DOMAINS. The virtual desktop needs no network. Leave out either half if you need only one server: the xvfb xdotool openbox packages and DPTTOOLS_ENABLE_COMPUTER for the desktop, the two playwright install lines and DPTTOOLS_ENABLE_BROWSER for the browser. In-process, pass browser_server or computer_server instead of setting the ENABLE variables.

For the browser:

  • The default launch mode is headless and needs no display.
  • Give the container outbound network access; the browser's own egress proxy then applies the domain lists and the private-address block. Set DPTTOOLS_BROWSER_ALLOWED_DOMAINS for the sites your use case needs.
  • Mount a volume for DPTTOOLS_BROWSER_DOWNLOAD_DIR if downloads must outlive the container.
  • Chromium needs memory and shared memory: size the container for the number of sessions you allow (DPTTOOLS_BROWSER_MAX_SESSIONS, default 4).

For the desktop:

  • Each MCP session gets its own Xvfb display, up to DPTTOOLS_COMPUTER_MAX_SESSIONS (default 2); size the container for the applications the agent runs on them.
  • Install the applications the agent should use, and fonts for the documents it opens.
  • To let a person watch, add x11vnc and set DPTTOOLS_COMPUTER_VNC_PORT. The VNC server has no password and listens only on 127.0.0.1 inside the container, so reach it through a tunnel you control rather than by exposing it.
  • The host backend does not belong in a container: it operates the real screen of the machine std-tools runs on (Isolated vs Attached).