Self-hosting
Go completely off-grid
A 100% local Oatmilk: accounts, books, files and AI models on one machine, even with no internet.
An off-grid Oatmilk keeps everything on one machine: accounts in your own database, books and files on your disk, and AI models on your own hardware. Once it is built, it runs with the network cable unplugged.
1. Set up local models first
Follow Use local AI models to install Ollama or LM Studio and pull the models, then check that the server answers:
curl http://localhost:11434/v1/models # Ollama; LM Studio is on port 12342. Run setup with every piece local
git clone https://github.com/AGI-Ventures-Canada/oatmilk.git
cd oatmilk
bun install
bun run self-host setup| Question | Off-grid answer |
|---|---|
| Where will Oatmilk run? | On this computer, at oatmilk.localhost |
| Which PostgreSQL database? | Run one here |
| Which Redis? | Run one here |
| Where should files be kept? | On this machine |
| How should people sign in? | Accounts kept here |
| Which AI models…? | Ollama on this computer or LM Studio on this computer |
| Should Oatmilk send email? | No |
After writing the settings, setup confirms: "Everything stays on this machine: accounts, files, the database and AI models." If it doesn't say so, one of the answers sends something elsewhere.
Then trust the local certificate as in Run it on your computer, and sign in at <https://oatmilk.localhost>.
3. Check that nothing leaves the machine
bun run self-host doctorIt checks every service, the address, the certificate and that the app reaches your model server. Then turn off Wi-Fi and upload a receipt: it is read and categorized by your local models.
What works with no internet
- Reading and categorizing statements, receipts and documents.
- Ask AI, with your local models.
- The five-minute background jobs.
- Team members, roles, invitations and outside accountants. Without email, copy an invitation link from Settings › Team and send it yourself.
- The REST API, API keys, MCP for AI apps on the same machine or network, and the command line.
- These developer docs, at
https://oatmilk.localhost/docs.
What needs the internet
These stay off until you turn them on, each in Settings for a company or in self-host/.env:
- live bank feeds and payouts (Wise), Stripe, and data connections (Notion, Google Drive, Microsoft);
- email in and out;
- hosted AI models (Vercel AI Gateway), and web research for compliance;
- Discord.
Install on a machine that never goes online
Building the image needs the internet once: it downloads Docker's base images, the npm packages, and the public list of AI models the agents' build reads. To install on a machine that never connects, build on one that does and carry the images across.
On the connected machine, in an Oatmilk checkout with your settings:
bun run self-host up # builds oatmilk:better-auth and pulls the other images
bun run self-host down
docker save -o oatmilk-images.tar $(docker compose -f self-host/compose.yaml config --images | sort -u)Copy oatmilk-images.tar, the Oatmilk folder (with node_modules and self-host/.env) and your model files to the offline machine. Ollama keeps its models in ~/.ollama/models. Then, on the offline machine:
docker load -i oatmilk-images.tar
echo "OATMILK_IMAGE=oatmilk:better-auth" >> self-host/.env # use the loaded image instead of building
bun run self-host up
bun run self-host user add --email you@example.com --first-name Ada # the database here starts emptyWith OATMILK_IMAGE set, up starts the image you loaded and never tries to build. Remove that line when you want to build a newer version.
Keep it safe
An off-grid install is only as safe as the one machine it runs on.
- Run
bun run self-host backupon a schedule, and copyself-host/backupsandself-host/.envto another disk. The.envfile holds the keys that decrypt connector credentials and contractor details, so keep it as private as the backups. - Turn on two-step sign-in in your profile.
- Use full-disk encryption (FileVault, BitLocker or LUKS).