Install and run

Docker#

Docker runs Flint only. Ollama stays the normal app on your machine, where it already has your GPU and your models, and the container talks to it. The image is published at ghcr.io/lusan-sapkota/flint (see Image tags), and the compose files in the repository root are ready-to-use examples. Download one; there's no need to clone the repository.

Linux:

mkdir flint && cd flint && mkdir data
curl -O https://raw.githubusercontent.com/Lusan-sapkota/Flint/main/docker-compose.yml
docker compose up -d

The container uses host networking, so it reaches Ollama at localhost:11434 exactly as a native Flint would, and Ollama never has to listen beyond localhost.

Mac and Windows (Docker Desktop):

mkdir flint && cd flint && mkdir data
curl -O https://raw.githubusercontent.com/Lusan-sapkota/Flint/main/docker-compose.desktop.yml
docker compose -f docker-compose.desktop.yml up -d

Host networking doesn't work there the same way, because Docker runs in a small VM. This file uses ordinary port mapping, and reaches Ollama through host.docker.internal, which Docker Desktop forwards to your machine. This setup is untested so far, since it was built on Linux; if it doesn't reach Ollama, please open an issue.

Then open http://localhost:3141. Notes:

  • Port: 3141 is deliberately uncommon, since 8080 is where most dev servers go. Set FLINT_PORT to use another (FLINT_PORT=4000 docker compose up -d). Either way it's published on 127.0.0.1 only.
  • Data: everything Flint stores (chats, memories, summaries, settings, attachments) lives in the data/ folder next to the compose file. It's a plain folder, not a Docker volume, so it survives docker compose down -v and rebuilds, and you can back it up like any other files. It's gone only when you delete the folder. Create it yourself before the first start: if Docker creates it, it's owned by root and the container can't write to it. The container runs as uid 1000, the usual first user on Linux. It's separate from backend/data/, which a native go run . uses.
  • Folders: the compose files mount your home folder into the container at the same path (/home/you on Linux, /Users/you on a Mac), so the folder browser starts there and a path you attach is the real one. Commands you approve run inside the container but can reach that folder, as they would with Flint running natively. To expose less, set FLINT_FOLDERS to one folder (FLINT_FOLDERS=/home/you/project docker compose up -d): only that folder is mounted, and the browser starts in it. On Windows the paths inside the container can't match C:\... paths, so set FLINT_FOLDERS and attach folders by their Linux path, or run Flint natively.
  • Shell: the image is Alpine (23.5 MB), not scratch, because the shell tool needs sh. Commands only have the tools Alpine ships.
  • Listening address: the image sets HOST=0.0.0.0, so a plain docker run -p works. The Linux compose file narrows it back to 127.0.0.1, since host networking would otherwise expose it to the network.

  • Updating: docker compose pull && docker compose up -d fetches the newest latest, and ./data is kept. latest only moves for normal releases, not pre-releases like v0.3.0-beta. To stay on one version, change the tag in the compose file, for example ghcr.io/lusan-sapkota/flint:0.2 (patch releases of 0.2) or :0.2.0 (exactly that one). Nothing updates automatically.

From source#

Requires Go (see backend/go.mod) and a running Ollama.

ollama serve                 # or the system service
cd backend
go run .                     # must run from backend/: assets resolve via ../frontend

Open http://localhost:8080, sign up, and pick a model.

To build a static binary (no cgo, any OS):

cd backend && CGO_ENABLED=0 go build -o flint .

Environment variables#

Variable Default
HOST 127.0.0.1 address to listen on; localhost only by default, since commands run on this machine and signup is open
PORT 8080
DB_PATH data/chat.db SQLite file, relative to backend/
ATTACHMENTS_DIR data/attachments uploaded files
OLLAMA_BASE_URL http://localhost:11434 server default; each user can override it in Settings
FLINT_ABLATE empty benchmark only: switches scaffolding off, see benchmark.md. Leave unset.

Image tags#

A new image is published for every release, for linux/amd64 and linux/arm64:

Tag Follows
latest the newest normal release (never a pre-release like v0.3.0-beta)
0.2 the newest 0.2.x patch release
0.2.0 exactly that release

The compose files use latest. To stay on one version, change the tag in the compose file. A published version always means the same code: a broken release is fixed by the next version, never by republishing one. How a release is made (for maintainers) is in CONTRIBUTING.md.

Updates & offline philosophy#

Flint has a strict zero-telemetry, offline-first design. It never checks for updates in the background, sends analytics, or displays an unsolicited "new version available" banner. The only external network call Flint ever makes is when you explicitly ask for an @web <query> search.

Because Flint never phones home, updates are entirely user-controlled:

  • Docker: Run docker compose pull && docker compose up -d in your Flint directory. Your accounts, chats, settings, and memories stored in ./data are fully preserved across image updates.
  • Source: Run git switch main && git pull and rebuild or run with go run ..

Settings → About shows the version you're running and these same commands. A release image carries its tag and commit; a build from source shows dev and its commit.

To stay notified when new releases are published:

Health#

GET /healthz checks the database and Ollama's /api/version. It returns 200 with {"db":"ok","ollama":"ok"}, or 503 naming what failed.

Shutdown#

SIGINT and SIGTERM stop accepting requests and give in-flight ones up to 10 seconds to finish. A background summarization cut short by shutdown is just redone later.

Models#

Anything Ollama serves works for chat. What Flint uses:

  • Tool calling (folder attach) needs a model with the tools capability, such as qwen2.5-3b-instruct or qwen3.5-4b.
  • Images need vision (qwen3.5-4b).
  • Thinking needs thinking (qwen3.5-4b).
  • @web re-ranking uses nomic-embed-text, and it's optional, not a dependency. Without it @web still works, using Brave's own ranking. With it, the model only loads for the moment a search runs: Flint asks Ollama to unload it as soon as the results are ranked, not after Ollama's default 5 minutes. Flint never pulls it on its own: Settings → Connection offers a Pull button when a Brave key is set and the model is missing, and the Installed list marks it.

By default a plain chat runs with a 4096-token window, a folder chat with 8192, and a chat with an Ollama cloud model with 32768. Each account can set its own window for local and for cloud models in Settings → Connection, and no model is given more than the context_length it reports; see context-management.md.