# OpenKedai > A free, open-source, offline-first point of sale for Malaysian cafés, restaurants, kiosks and small retail: a POS app for tablets and phones, an optional self-hosted hub, and a web back office. Every page is Markdown at its address plus `.md`. All of them in one file: https://docs.openkedai.com/llms-full.txt ## Using OpenKedai - [Running a hub](https://docs.openkedai.com/hub.md): A hub lets several tablets and phones work as one shop. A waiter's phone opens a table that the counter tablet charges, held orders show on every device, and… - [The back office](https://docs.openkedai.com/back-office.md): The back office is a website for owners and managers, served by the hub on the same address and port as everything else (for example http://192.168.1.20:8080).… - [Printing](https://docs.openkedai.com/printing.md): OpenKedai prints receipts and kitchen tickets on ESC/POS thermal printers. It talks to printers directly, with no printer apps or drivers to install, and… ## Self-hosting - [Self-hosting OpenKedai](https://docs.openkedai.com/self-hosting.md): A hub lets several tablets and phones work as one shop, and serves the web back office. The POS app works without one (single-device mode); add a hub when a… - [Docker](https://docs.openkedai.com/self-hosting/docker.md): The image ghcr.io/openkedai/openkedai runs on linux/amd64 and linux/arm64 (Raspberry Pi 4/5, ARM servers, most NAS boxes). Everything the hub keeps is in /data. - [Linux server or Raspberry Pi (no Docker)](https://docs.openkedai.com/self-hosting/linux.md): The installer sets the hub up as a system service on a 64-bit Linux with systemd: Debian, Ubuntu, Raspberry Pi OS (64-bit) and most others. - [A hub on the shop's network](https://docs.openkedai.com/self-hosting/lan-hub.md): A hub at the shop keeps every device in step without the internet: a waiter's phone sends an order to the counter, and held orders show everywhere, even when… - [Fly.io](https://docs.openkedai.com/self-hosting/fly.md): Fly runs the hub's image close to you (Singapore by default) with a small volume for its data. The machine stops when nothing is connected, for example… - [Render](https://docs.openkedai.com/self-hosting/render.md): The button creates a web service from render.yaml: it builds the image from deploy/Dockerfile and attaches a 1 GB disk for the hub's data. - [Railway](https://docs.openkedai.com/self-hosting/railway.md): Railway builds the hub from the repository (railway.json points it at deploy/Dockerfile). - [DigitalOcean](https://docs.openkedai.com/self-hosting/digitalocean.md): Use a Droplet (a small virtual server). DigitalOcean's App Platform doesn't keep files between deploys, so it can't hold the hub's data. - [Backups](https://docs.openkedai.com/self-hosting/backups.md): Every POS device also keeps a full copy of its shop's sales, so a lost hub doesn't lose sales. Backups of the hub keep the rest: the menu and staff as the back… - [HTTPS and remote access](https://docs.openkedai.com/self-hosting/https.md): On the shop's network, the hub speaks plain HTTP on port 8080. That's normal for equipment on a private network. Anything reached over the internet should use… - [Configuration](https://docs.openkedai.com/self-hosting/configuration.md): Every setting is an environment variable with a safe default; the hub needs none of them to run. Set them in compose.yaml (Docker),… ## Extending - [Plugins](https://docs.openkedai.com/plugins.md): Plugins add features to an OpenKedai server without changing OpenKedai itself. Examples: syncing sales to an accounting package, awarding loyalty points,… ## Design decisions - [Architecture decision records](https://docs.openkedai.com/adr.md): Decisions that are hard to reverse. Each record says what was decided and why. To change one, write a new record that supersedes it. - [0001. License: AGPL-3.0-only](https://docs.openkedai.com/adr/0001-license-agpl.md): OpenKedai is free software that shops can run themselves. We want anyone to be able to self-host it, and we want improvements made by people who run modified… - [0002. Offline-first](https://docs.openkedai.com/adr/0002-offline-first.md): Many Malaysian shops have unreliable internet. A point of sale that stalls at the counter when the connection drops loses sales and trust. - [0003. Money is integer sen](https://docs.openkedai.com/adr/0003-money-integer-sen.md): Floating-point arithmetic cannot represent most decimal amounts exactly, which causes rounding errors in totals, tax and reports. - [0004. The event log is the source of truth](https://docs.openkedai.com/adr/0004-event-log-source-of-truth.md): Orders change many times between opening and closing, often on devices that are offline. We need a full audit trail, safe retries and a simple way to merge… - [0005. Three ways to run, one codebase](https://docs.openkedai.com/adr/0005-three-ways-to-run.md): A small café with one tablet needs no server. A busier restaurant wants several devices sharing orders through a hub on its own network. Others prefer a server… - [0006. Country rules are data](https://docs.openkedai.com/adr/0006-country-rules-are-data.md): Tax rates, rounding rules and receipt requirements differ by country and change over time. Hard-coding Malaysian rules would make every other country a fork. - [0007. Who is authoritative](https://docs.openkedai.com/adr/0007-authority.md): When several devices and a hub compute totals, they could disagree, through bugs, stale catalog data or tampering. - [0008. Telemetry is opt-in](https://docs.openkedai.com/adr/0008-telemetry-opt-in.md): Usage data could help improve OpenKedai, but shops handle customer and sales data covered by Malaysia's Personal Data Protection Act (PDPA), and unexpected… - [0009. Two apps sharing one core](https://docs.openkedai.com/adr/0009-two-apps-shared-core.md): Counter staff need a fast, native-feeling app with on-device storage that works offline, on the counter and on the floor. Managers need full-size screens for… - [0010. App-store distribution and the CLA](https://docs.openkedai.com/adr/0010-app-store-distribution-and-cla.md): Apple's App Store terms conflict with GPL-family licenses, which would stop us distributing the POS app through the stores shops actually use. We also want to… - [0011. Self-hosting is a product feature](https://docs.openkedai.com/adr/0011-self-hosting-is-a-feature.md): The more places OpenKedai can be deployed in a few minutes, the more people will try it. Complicated deployments put off the small shops and helpers we are… - [0012. Cheap by design](https://docs.openkedai.com/adr/0012-cheap-by-design.md): Small shops cannot pay for large servers or managed databases. A hosted fork would also need to fit many shops onto small machines. - [0013. This is the public open-source repository](https://docs.openkedai.com/adr/0013-public-repository.md): OpenKedai will be developed in the open. A hosted version, if one is offered, needs operational features that do not belong in the community project. - [0014. Business rules are configurable](https://docs.openkedai.com/adr/0014-configurable-business-rules.md): Shops differ in how they price and charge, even within one country: whether modifiers are charged per item or once per order line, whether service charge is… - [0015. Event ordering and conflicts](https://docs.openkedai.com/adr/0015-event-ordering-and-conflicts.md): Events for one order can come from several devices, arrive late after time offline, arrive twice, or contradict each other (a waiter adds an item on a phone… - [0016. Printing](https://docs.openkedai.com/adr/0016-printing.md): Shops use many brands of thermal printer, mostly cheap ESC/POS models from China plus Epson, and Sunmi Android terminals with built-in printers. Printer… - [0017. Shifts and Z-reports](https://docs.openkedai.com/adr/0017-shifts.md): At the end of the day a shop counts its cash drawer and prints a Z-report: what was sold, what tax was charged, how customers paid, and whether the drawer is… - [0018. Plugins and extension points](https://docs.openkedai.com/adr/0018-plugins.md): Shops and integrators want OpenKedai to do things the core project will never ship: sync to an accounting package, award loyalty points, print a survey QR on… - [0019. Hub sync and pairing](https://docs.openkedai.com/adr/0019-hub-sync-and-pairing.md): In hub mode several POS devices share one shop: a waiter's phone opens a table that the counter tablet charges, and every device sees held orders as they… - [0020. Back office sign-in](https://docs.openkedai.com/adr/0020-back-office-sign-in.md): The back office (M7) is a web app served by the hub, for owners and managers on a laptop or phone. It edits the menu, staff and settings that every device… - [0021. Languages and Chinese printing](https://docs.openkedai.com/adr/0021-languages-and-chinese-printing.md): Malaysian shops work in English, Malay and Chinese, often all three in one shop: a cashier reads Malay, the kitchen reads Chinese, and customers want receipts… - [0022. Finding the hub on the network](https://docs.openkedai.com/adr/0022-finding-the-hub-on-the-network.md): A hub on a shop's LAN usually gets its IP address from the router. After a power cut or a router change, the address can change, and every paired device loses… - [0023. Shipping the server, and backups](https://docs.openkedai.com/adr/0023-shipping-the-server-and-backups.md): M9 ships the hub to people who are not developers, on whatever they already have: - a Raspberry Pi or mini PC at the shop; - a $5 VPS; - Docker; - a hosting… - [0024. The website and the docs site](https://docs.openkedai.com/adr/0024-website-and-docs-site.md): OpenKedai needs a landing page at openkedai.com and a documentation site at docs.openkedai.com. The domain is on Cloudflare. The docs change with almost every…