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
RUNcommand, anARGor anENV: those are kept in the image. - Choose extras instead of[all]to keep the image small:docsfor 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 asfonts-noto-cjk, or pages render with missing characters. - If LibreOffice is installed somewhere other thanPATH, pointDPTTOOLS_SOFFICE_BINat itssofficeexecutable. - The repository also containsdocker/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_screenshotneeds a display; in a headless container it returns an error, so thescreenshotextra 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=nonewhen 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
launchmode 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_DOMAINSfor the sites your use case needs. - Mount a volume for
DPTTOOLS_BROWSER_DOWNLOAD_DIRif 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
x11vncand setDPTTOOLS_COMPUTER_VNC_PORT. The VNC server has no password and listens only on127.0.0.1inside the container, so reach it through a tunnel you control rather than by exposing it. - The
hostbackend does not belong in a container: it operates the real screen of the machine std-tools runs on (Isolated vs Attached).