Kamra PMS
Kamra는 오픈소스 AI 기반 호텔 PMS로 프런트 데스크·예약·하우스키핑·청구·GST를 지원하고 역할별 원터치 데모 로그인 제공
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Multi-tenant ISP billing SaaS: M-Pesa, FreeRADIUS, MikroTik over OpenVPN. Architecture + real CI/CD (GitHub Actions → GHCR → VPS), Docker Compose, Caddy.
README 전체를 불러오는 중입니다.
README 전문 보기 ↗eazyBill runs the business side of small internet service providers: PPPoE and hotspot customers, packages, M-Pesa payments, RADIUS authentication, and MikroTik routers connected over OpenVPN. One platform owner runs it for many ISPs, and each ISP gets its own staff workspace and customer portal.
It is the product version of the billing platform I built for an ISP with 7,000+ active subscribers, which runs its billing, provisioning and support every day. A multi-tenant deployment is live at uplink.skylinknetworks.co.ke.
This repo is a showcase. The application code is private because it's a commercial product. This repo holds the architecture and the real deployment setup (CI/CD workflow, Docker Compose, Caddy, server setup and backup scripts). I'm happy to walk through the code on a call.
my.<domain>/<isp>, with sign-in by one-time code.flowchart LR
subgraph Internet
staff[ISP staff] --> caddy
cust[PPPoE customers] --> caddy
hs[Hotspot users] --> caddy
mpesa[M-Pesa / MoMo / Selcom] -- callbacks --> caddy
end
subgraph VPS["One VPS (Docker Compose)"]
caddy[Caddy<br/>auto HTTPS, subdomain routing]
caddy --> fe[Staff app<br/>Next.js]
caddy --> portal[Customer portal<br/>Next.js]
caddy --> api[API + crons<br/>Node.js / Express]
caddy --> relay[Hotspot captive portal]
api --> mongo[(MongoDB)]
api --> redis[(Redis)]
radius[FreeRADIUS] --> mysql[(RADIUS DB<br/>MySQL)]
api --> mysql
vpn[OpenVPN server]
end
routers[MikroTik routers<br/>at each ISP] -- OpenVPN tunnel --> vpn
routers -- RADIUS via 10.8.0.1 --> radius
api -- RouterOS API over VPN --> routers
| Site | Service |
|---|---|
<domain>, app.<domain> | landing page and staff workspace |
my.<domain>/<isp> | customer portal |
relay.<domain> | hotspot captive portal |
vpn.<domain>:1194/tcp | routers' OpenVPN |
server/.env; the API serves it at GET /api/platform. Frontends call /api on their own address, so there's no CORS and cookies stay first-party.vpn.<domain> and reach RADIUS at 10.8.0.1 inside the tunnel, so moving to a new server is a DNS change, with nothing to reconfigure on hundreds of routers..github/workflows/deploy.yml: on push to main, it works out which services changed, builds only those Docker images in parallel, pushes them to GHCR, copies server/ to the VPS over SSH, and restarts only the changed containers. Nothing is built on the server. Roll back by pinning IMAGE_TAG to an earlier commit.server/docker-compose.yml: the whole platform as one Compose stack.server/Caddyfile: subdomain routing and automatic HTTPS.server/setup.sh: one-command, re-runnable setup of a fresh Ubuntu server: Docker, swap, firewall, generated secrets, registry login, nightly backup cron.server/backup.sh: nightly MongoDB archive, RADIUS dump and OpenVPN keys, kept for 14 days, with optional off-site copy through rclone.Node.js, Express, Next.js, React, TypeScript, MongoDB, MySQL, Redis, FreeRADIUS, OpenVPN, MikroTik RouterOS API, Docker, GitHub Actions, GHCR, Caddy, Jest and Supertest (unit, integration and end-to-end tests).
Built by Charles Njoroge · github.com/c-njoro · linkedin.com/in/charles-njoroge-dev