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 chekiapp.vercel.app, 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
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/docsThat'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
| Endpoint | Method | Description |
|---|---|---|
| /api/verify | POST | Verify a single receipt |
| /api/verify/batch | POST | Verify up to 50 receipts at once |
| /api/banks | GET | List supported banks and status |
| /api/health | GET | Check API and per-bank endpoint health |
| /api/receipt | GET | Download 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.
X-Forwarded-For bypass (non-Ethiopian servers)
If you can't host in Ethiopia but have a server with a non-blocked IP (some residential or less-known hosting ranges work), you can try the X-Forwarded-For header bypass:
# cheki already sends these headers for geo-blocked banks:
# X-Forwarded-For: 197.156.96.83 (Ethiopian IP)
# X-Real-IP: 197.156.96.83
# This works with some proxies and residential connections
# but NOT with cloud datacenter IPs (AWS, GCP, Azure, Vercel)Not reliable on cloud
Ethiopian banks actively block cloud provider IP ranges. The X-Forwarded-For header is ignored when the TCP connection itself is blocked. This bypass only works from IPs that aren't already blocked.
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
# 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