technical · 5 min read

Self-Hosting cheki with Docker: Complete Guide

Run your own free Ethiopian receipt verification API with Docker. Bypass geo-blocks, keep data in-house, and customize for your needs.

Self-hosting cheki gives you three advantages over the hosted version: full control over your data, no dependency on cheki.et, and the ability to bypass Telebirr and M-Pesa geo-blocking by running on an Ethiopian IP address.

Prerequisites

  • Docker and Docker Compose installed
  • A server with internet access (an Ethiopian IP for Telebirr/M-Pesa support)
  • Git

Quick start

bash
git clone https://github.com/1RB/cheki.git
cd cheki
docker-compose up -d

# API is now available at http://localhost:3000
# Web UI is at http://localhost:3000
# API docs at http://localhost:3000/docs
✓

That's it

The Docker image includes everything: Next.js, the API routes, PDF parsing, and all bank integrations. No external database or API keys needed.

What you get

EndpointMethodDescription
/api/verifyPOSTVerify a single receipt
/api/verify/batchPOSTVerify up to 20 receipts at once
/api/banksGETList supported banks and status
/api/healthGETCheck API and per-bank endpoint health
/api/receiptGETDownload raw receipt file from bank

Bypassing Telebirr and M-Pesa geo-blocks

Telebirr (transactioninfo.ethiotelecom.et) and M-Pesa (m-pesabusiness.safaricom.et) block all non-Ethiopian IP addresses at the TCP level. This means cloud servers on AWS, Vercel, Cloudflare, and most international hosting providers cannot reach these endpoints.

If you self-host cheki on a server with an Ethiopian IP address, Telebirr and M-Pesa verification will work without any workarounds. This is the cleanest solution.

💡

Ethiopian hosting options

Ethio Telecom and various local ISPs offer fixed IP addresses. A small VPS or dedicated server in Ethiopia can run cheki for a few hundred birr per month, with unlimited verification.

⚠

No header tricks

The block is on the real network address, so headers like X-Forwarded-For change nothing and cheki does not send them. From a server outside Ethiopia, cheki makes one quick attempt and then gives the user the bank's own receipt link to open.

Customizing cheki

Since cheki is open source, you can modify it for your needs:

  • Add custom bank parsers in src/app/api/verify/route.ts
  • Change the UI in src/app/page.tsx
  • Add authentication if you want to restrict access
  • Add a database for duplicate detection and audit trails
  • Modify the Python library in /python for custom integrations

Production deployment

For production, consider:

  • Put cheki behind a reverse proxy (nginx, Caddy) with TLS
  • Add rate limiting to protect the underlying bank endpoints
  • Monitor with the /api/health endpoint
  • Set up logging for audit trails
  • Use a process manager (PM2, systemd) if not using Docker
code
# Example docker-compose override for production
services:
  cheki:
    restart: always
    ports:
      - "127.0.0.1:3000:3000"  # Only listen on localhost
    environment:
      - NODE_ENV=production

Frequently asked questions

Edit this article on GitHubReport an issue →

Continue reading