Tesseract in Docker: 6 base images, tested
58 MB
Alpine with the fast model: smallest, most words
The Dockerfile for pytesseract
The Python slim images are Debian. Install the program with apt and the wrapper with pip:
FROM python:3.13-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends tesseract-ocr \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir pytesseract pillow
Then pass a file path, as you would outside Docker:
import pytesseract
print(pytesseract.image_to_string("scan.jpg", config="--dpi 300"))
293 MB the image
5.5.0 the Tesseract it gets
On 55 book scans it wrote the same text as the
tesseract command, page for page.
Each base image ships its own version
apt and apk install the version the distro froze. Sizes with Tesseract added, on arm64:
| Base image | Tesseract | Size |
|---|---|---|
ubuntu:22.04 |
4.1.1 | 161 MB |
ubuntu:24.04 |
5.3.4 | 205 MB |
debian:bookworm-slim |
5.3.0 | 207 MB |
debian:trixie-slim |
5.5.0 | 214 MB |
python:3.13-slim |
5.5.0 | 259 MB |
alpine:3.24 |
5.5.2 | 77 MB |
Every apt image came with the small tessdata_fast English model. Alpine's is the larger standard model.
Tesseract 4 or 5: the same words
Words found in order, of 14,693 on 55 proofread book scans:
13,857 4.1.1, on ubuntu:22.04
13,849 5.3.0 to 5.5.0, every other apt image
The text still moves. Debian 13 and Alpine, with the same model, wrote the same text on 12 of 55 pages. Pin the image tag if a test compares OCR text.
ubuntu:22.04 took 2.4 times as long
Tesseract 4.1.1 has no arm64 (NEON) code for its math. That came in 5.0.0. On an arm64 server, start from ubuntu:24.04 or newer.
Alpine: 58 MB with the fast model
Alpine's own model read fewer words, and slower. Swap it for the fast one, checked by SHA-256:
FROM alpine:3.24
RUN apk add --no-cache tesseract-ocr \
&& wget -q -O /usr/share/tessdata/eng.traineddata \
https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/4.1.0/eng.traineddata \
&& echo "7d4322bd2a7749724879683fc3912cb542f19906c83bcc1a52132556427170b2 /usr/share/tessdata/eng.traineddata" \
| sha256sum -c -
13,858 words with the fast model
13,747 with Alpine's own model
--oem 1 also gets the words back, 13,848,
but not the speed. Need page rotation, like
--psm 0? Add
tesseract-ocr-data-osd.
How I tested it
- Pages: 55 proofread Wikisource scans from 11 printed books, 1,920 pixels wide. The same set as the tessdata test, without its handwritten book.
- Score: true words found in order, with the same scorer as that test.
-
Each image is its base plus the distro's Tesseract, nothing else.
Size is the files in it, by
du. -
Docker 29.8.2 on an arm64 Mac, 8 CPUs,
OMP_THREAD_LIMIT=1,--dpi 300. Times are the median of 3 rounds, with other jobs running. - Not the JPEG decoder: PNG copies split the text the same way. A repeat run gave the same bytes on 55 of 55 pages.
- Our Actor uses the Debian setup: Tesseract 5.5.0 and the fast models, checked by SHA-256.
What I did not test
- x86 servers. 4.1.1 has AVX2 code there, so its gap can shrink.
- Other languages, tessdata_best, and GPUs.
- Images from Docker Hub, and Tesseract built from source.
- A PPA for Tesseract 5 on Ubuntu 22.04.
Sources
Two ways to skip the work
Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.
Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.
Questions people ask
Is Tesseract 5 more accurate than Tesseract 4?
Not on these 55 scans. 4.1.1 found 8 more words of 14,693, and by page it won 14, lost 10 and tied 31. Version 5 was much faster on arm64.
How do I add a language in Docker?
Install its model package next to the program:
tesseract-ocr-deu on Debian and Ubuntu,
tesseract-ocr-data-deu on Alpine. Swap deu for your
language code. The
language test has the
apt line I ran.
Why does pytesseract say Tesseract is not installed?
pip installs only the wrapper. The program must be in the same image that runs your code, as in the Dockerfile above. Other causes are on the TesseractNotFoundError page.