Skip to content

Docker

Run DocTranslater in Linux containers for local use, CI, or deployment. Images are defined in the repository Dockerfile. Build targets and ARGs are listed in Docker image profiles.

Requirements

  • Docker 23+ with BuildKit (DOCKER_BUILDKIT=1).
  • Linux amd64 or arm64 (buildx for multi-arch: docker buildx build --platform linux/amd64,linux/arm64 …).

Serverless containers

For Cloud Run, ECS Fargate, App Runner, Modal, Runpod, and related patterns (image choice, warm assets, ephemeral disk, worker vs HTTP service), see:

Profiles: use runtime-api for the optional HTTP service; runtime-cpu / runtime-vision for CLI or worker-style batch. Warm variants (runtime-cpu-warm, runtime-vision-warm) reduce runtime downloads but need network at image build time.

Prebuilt images (GitHub Container Registry)

On push to main, .github/workflows/docker.yml builds and pushes amd64 images to GitHub Packages (ghcr.io). Use your GitHub username or organization name in lowercase as OWNER (GHCR requires a lowercase owner in the image path).

Image Dockerfile target Typical use
ghcr.io/OWNER/doctranslater-base runtime-base Schemas / minimal CLI
ghcr.io/OWNER/doctranslater-cpu runtime-cpu Default translate path (PDF + LLM + layout ONNX)
ghcr.io/OWNER/doctranslater-vision runtime-vision Full optional stack (OCR, Hyperscan glossary path, …)
ghcr.io/OWNER/doctranslater-api runtime-api HTTP API (serve on port 8000); see HTTP API.
ghcr.io/OWNER/doctranslater-dev runtime-dev Development / CI parity

Tags

  • main — tip of the default branch when the workflow ran.
  • sha-<short> — commit SHA for reproducible pulls.
  • latest — only on doctranslater-cpu (the default runtime profile).

Pull and run (example for this fork; replace OWNER if you use a fork):

docker pull ghcr.io/miguelenes/doctranslater-cpu:main
docker run --rm ghcr.io/miguelenes/doctranslater-cpu:main --help

Private packages require docker login ghcr.io (PAT with read:packages, or GITHUB_TOKEN in CI). For anonymous pulls, keep the package visibility public in the repo’s Packages settings.

Build targets

Target Contents
runtime-base Base PyPI dependencies only (doctranslate.schemas, minimal CLI).
runtime-cpu PDF + CLI + LLM + TM + vision (layout ONNX). No full meta-extra; no Hyperscan in the default runtime layer.
runtime-cpu-warm Same as runtime-cpu with fonts/models/cmaps pre-populated under /home/doctranslater/.cache/doctranslate.
runtime-api Same Python extras as runtime-cpu plus api (FastAPI/Uvicorn); default CMD is serve on port 8000. See HTTP API.
runtime-vision DocTranslater[full] — matches default CI optional stack (OCR, Hyperscan glossary path, etc.).
runtime-vision-warm Same as runtime-vision with warm cache.
runtime-dev full + dev dependencies (pytest, ruff, mkdocs, …).

Why runtime-cpu includes vision: the default translate path loads the doclayout ONNX model unless you use an RPC doclayout flag. Install only pdf+cli+llm without vision is not sufficient for typical doctranslate translate runs.

OCR-heavy workloads: use runtime-vision (includes ocr) or rebuild runtime-cpu with --build-arg INCLUDE_OCR=1 and extend system packages if needed.

Quick start

Build the CPU image:

docker build --target runtime-cpu -t doctranslater:cpu .

Show CLI help (default command):

docker run --rm doctranslater:cpu

Translate a PDF (mount input/output and pass secrets at runtime, not in the image):

docker run --rm \
  -e OPENAI_API_KEY \
  -v "$PWD/examples/ci:/in:ro" \
  -v "$PWD/out:/out" \
  doctranslater:cpu \
  translate /in/test.pdf --provider openai \
  --source-lang en --target-lang zh -o /out

Router or local mode with TOML on the host:

docker run --rm \
  -v "$PWD:/work" \
  -w /work \
  doctranslater:cpu \
  translate ./doc.pdf --translator router -c ./doctranslate.toml -o ./out

Mount a persistent cache (models, fonts, TM SQLite, tiktoken cache):

docker run --rm \
  -v doctranslate-cache:/home/doctranslater/.cache/doctranslate \
  doctranslater:cpu-warm \
  translate /in/doc.pdf --provider openai --source-lang en --target-lang zh -o /out

Warm assets at runtime (slim images):

docker run --rm \
  -v doctranslate-cache:/home/doctranslater/.cache/doctranslate \
  doctranslater:vision \
  assets warmup

Air-gapped or pinned asset trees: use doctranslate assets pack-offline / restore-offline (see Verification and CI in .github/workflows/test.yml).

Entrypoint and signals

The image entrypoint runs tini so PID 1 forwards SIGTERM/SIGINT to the CLI. Override the command after the image name as usual.

An optional HTTP API is included (DocTranslater[api]); see HTTP API, HTTP API workers (Redis + doctranslate worker when DOCTRANSLATE_API_QUEUE_BACKEND=arq), HTTP API storage, and the runtime-api image target. You can still embed with doctranslate.api from your own process or wrap the CLI.

Health checks

Images declare HEALTHCHECK using doctranslate --version. For readiness that includes downloaded assets, use a warm target or mount a populated cache volume.

For HTTP services (runtime-api), you can also scrape /metrics and ship JSON logs from stdout when observability is enabled; see Observability.

Security

  • Images run as user doctranslater (UID 1000).
  • Do not bake API keys into images; use -e / secrets and api_key_env in TOML (Configuration).
  • For read-only root filesystems, mount writable volumes for HOME/.cache/doctranslate, job output (-o), and optional --working-dir.

HTTP API (runtime-api)

The optional HTTP API supports a shared secret for inbound requests (separate from LLM provider keys). See HTTP API — Authentication.

docker run --rm -p 8000:8000 \
  -e DOCTRANSLATE_API_AUTH_MODE=required \
  -e DOCTRANSLATE_API_AUTH_TOKEN \
  -e OPENAI_API_KEY \
  ghcr.io/OWNER/doctranslater-api:main
  • With DOCTRANSLATE_API_AUTH_MODE=disabled (default), clients need no Authorization header.
  • With required, pass Authorization: Bearer $DOCTRANSLATE_API_AUTH_TOKEN or X-API-Key on every protected call (see HTTP API for probe exceptions and CORS).

Local LLM connectivity

Containers cannot reach localhost on the host. Point --local-base-url (or TOML) at:

  • host.docker.internal (Docker Desktop; Linux may need --add-host=host.docker.internal:host-gateway), or
  • Another Compose service name, e.g. http://ollama:11434.

See Local translation and Troubleshooting.

Troubleshooting

ImportError / missing .so in the container

Match the image profile to your flags (OCR → runtime-vision or INCLUDE_OCR=1). See Package layers.

Permission denied on cache or output

Ensure mounted directories are writable by UID 1000, or run with --user matching your volume ownership.

Warm build fails in CI or offline build hosts

Warm stages need outbound HTTPS (fonts, ONNX, Hugging Face). Use runtime-* (non-warm) and run assets warmup at deploy time, or ship an offline bundle.

Hyperscan / glossary errors on runtime-cpu

Hyperscan is in the glossary extra and needs libhyperscan5 at runtime. Default runtime-cpu does not install that library. Use runtime-vision or customize the Dockerfile.