GICT knowledge base
Self-hosted OCR on Your VPS: Extracting Text from Images with Tesseract
Published
A scanned invoice lands in your inbox. A user uploads a photo of a receipt. You have a folder of screenshots and you need the text out of them. The obvious move is a cloud OCR API, but those charge per page, and they mean sending your documents (sometimes sensitive ones) to a third party. There is a better option for most jobs, and it is probably one apt install away.
Tesseract is a mature, open-source OCR engine that turns images of text into actual text. It runs on plain CPU, needs no GPU, no API key, and no per-page fee. This article shows you how to use it on a server: install it, run it on a real image, read the confidence scores, and use the one trick that makes or breaks OCR accuracy. Every command below was run before publishing.
What Tesseract is (and what it needs)
Tesseract started at HP, was open-sourced, and is now maintained with backing from Google. Modern versions (4 and 5) use an LSTM neural network engine that is genuinely accurate on clean printed text, and it supports over 100 languages.
The important part for a server operator: it is CPU-only and lightweight. There is no GPU code path, so a GPU does nothing for it. It is a small C++ binary plus a language data file (English is about 15 MB). It installs in seconds and OCRs a normal page in a fraction of a second. This is a tool that runs comfortably on the cheapest VPS you have.
Install it
On Debian or Ubuntu:
sudo apt-get install -y tesseract-ocr
Check the version and the installed languages:
tesseract --version
tesseract --list-langs
tesseract 5.3.0
...
eng
osd
You get English (eng) and the orientation/script detection data (osd) by default. Additional languages are their own packages, for example apt-get install tesseract-ocr-fra for French.
Hands-on: OCR an image
Point Tesseract at an image and send the result to your terminal. Here we run it on an image of an invoice:
tesseract receipt.png stdout
InterServer VPS Hosting
Invoice #A-1042 Total: $49.00
Due date: 2026-09-01
Every line came out correct, including the invoice number, the dollar amount, and the date. To write the result to a file instead, give an output basename and Tesseract appends the extension:
tesseract receipt.png out
# creates out.txt
That is the entire core workflow. On a normal page image it is fast:
time tesseract receipt.png out
real 0m0.151s
About 150 milliseconds. You can OCR thousands of pages an hour on a single core.
Confidence scores and structured output
Plain text is not the only thing Tesseract can produce. Ask for TSV output and you get every word with a confidence score, which is invaluable when you need to flag uncertain results:
tesseract receipt.png stdout tsv
InterServer conf=92.4
VPS conf=96.4
Invoice conf=93.1
#A-1042 conf=91.8
Total: conf=96.3
$49.00 conf=95.8
Confidence in the low-to-mid 90s on this clean image. In a real pipeline you would route anything below, say, 80 to a human for review. Tesseract can also output:
- hOCR and ALTO (XML with bounding boxes) for layout-aware processing.
- A searchable PDF, where the original image is kept and an invisible text layer is added on top so the PDF becomes selectable and searchable:
tesseract receipt.png searchable pdf
# creates searchable.pdf
That one command turns a folder of scanned images into searchable documents.
The one thing that makes or breaks accuracy: preprocessing
Here is the lesson that separates good OCR results from garbage. Tesseract is only as good as the image you feed it. Clean, high-contrast, straight text reads almost perfectly. Noisy, low-resolution, or skewed images can fail completely.
To prove it, here is a small, noisy image. Run raw OCR on it:
tesseract noisy.png stdout
Nothing. Tesseract returned an empty result because the noise drowned the text. Now clean the image first with ImageMagick (upscale it, convert to grayscale, remove speckle noise, and threshold to pure black and white), then OCR the cleaned version:
convert noisy.png -resize 300% -colorspace Gray -despeckle -threshold 55% clean.png
tesseract clean.png stdout
Server load: 0.75 Uptime 99.98%
Same source image, but now it reads perfectly. The OCR engine did not change; the input did. This is the single highest-leverage thing you can do. A good preprocessing recipe for scanned or photographed text:
- Upscale small images (Tesseract likes text around 300 DPI).
- Convert to grayscale, then threshold to clean black-on-white.
- Despeckle or blur slightly to kill noise.
- Deskew if the page is tilted (
convert -deskew 40%).
Spend your effort here, not on tweaking the OCR itself.
Handling layout with page segmentation
Tesseract assumes a normal page of text by default. For unusual inputs, the --psm (page segmentation mode) flag tells it what to expect:
tesseract --help-psm
Common ones: --psm 6 treats the image as a single uniform block of text (great for a cropped label), --psm 7 for a single line, and --psm 3 (the default) for full automatic page analysis. If a receipt or a single line is coming out jumbled, changing the --psm is often the fix.
When Tesseract is the right tool
Tesseract shines on clean, printed text: invoices, forms, book pages, screenshots, generated PDFs. For batch processing your own documents on a server, it is hard to beat on cost and privacy.
It struggles with handwriting, heavily stylized fonts, and text in messy real-world photos. If that is your workload, a newer engine like PaddleOCR, or a cloud vision API, will do better, at the cost of more setup or per-page fees. Know which problem you have before you pick.
Wrapping up
OCR does not require a GPU, an API key, or a subscription. Tesseract turns images into text on any CPU, fast enough to batch thousands of pages, and private because nothing leaves your server. Install it, remember that preprocessing is where the accuracy actually comes from, reach for --psm when the layout is unusual, and you have a production-grade text-extraction pipeline for the price of the server you already run.
Related guides
How to Self-Host DocuSeal for Document Signing
Self-host DocuSeal with private administrator setup, PostgreSQL and HTTPS. Test signing, understand email data flows and create consistent backups.
Self HostedHow to Self-Host Docmost with Docker on Ubuntu 24.04
Install Docmost with Docker, PostgreSQL and Redis. Set up a private workspace and verify editing, live updates and attachment retrieval.
Self HostedHow to Remove Image Backgrounds Locally with rembg
Remove image backgrounds locally with rembg. Preserve originals, check PNG transparency and inspect cutout quality on both light and dark backgrounds.
Self HostedHow to Translate Text Offline with Argos Translate
Translate plain text locally with Argos Translate. Install a language pair, prepare caches, verify offline operation and review translation quality.
