Setup

Up and running in about a minute.

Cruxwire is a single container that talks to your Ollama instance and keeps its state on a local volume. Run it on your own Mac or PC with Docker Desktop, or on a homelab box. If you can run docker compose up, you can run Cruxwire.

Step 1

Requirements

Two things, whether you run it on your own computer or a homelab box.

Docker + Docker Compose

Docker Desktop on your Mac or PC, or any container host: a NAS, mini-PC, VM, or Raspberry Pi class box. Docker Desktop already bundles Compose, so docker compose up works out of the box. The app has no build step and no Python dependencies, it's pure standard library inside the image.

An Ollama instance

A reachable Ollama endpoint over HTTP, with a chat model and an embedding model pulled. It can run natively on the same machine (on a Mac, the right setup, so Ollama can use the GPU) or anywhere on your network; you point Cruxwire at it with OLLAMA_HOST. For usable speed, run it on an NVIDIA GPU or an Apple Silicon Mac with enough memory; CPU-only works but is slow.

pull the models
# chat: score / summarize / categorize
ollama pull qwen3:8b

# embeddings: clustering / taste / semantic search
ollama pull nomic-embed-text

Step 2

Quick start

Clone the repo, point it at your Ollama instance, and bring it up.

terminal
# 1: get the source
git clone https://github.com/philoking/cruxwire
cd cruxwire

# 2: configure .env (mainly OLLAMA_HOST and TZ)
cp .env.example .env
# point OLLAMA_HOST at your Ollama; set TZ for your zone

# 3: build and run
docker compose up -d --build
docker-compose.yaml
services:
  cruxwire:
    build: .
    container_name: cruxwire
    restart: unless-stopped
    ports:
      - "${PORT:-8090}:8090"
    environment:
      OLLAMA_HOST: ${OLLAMA_HOST:-http://localhost:11434}
      PORT: 8090
      TZ: ${TZ:-America/Los_Angeles}
    volumes:
      - cruxwire-data:/data
    env_file:
      - path: .env        # overrides: OLLAMA_HOST, OLLAMA_MODEL, TZ, …
        required: false
volumes:
  cruxwire-data:
.env, the lines you actually touch
# point this at your Ollama. Same machine via Docker Desktop?
# use host.docker.internal, not localhost.
OLLAMA_HOST=http://localhost:11434

# timezone for the scheduler's active-hours window (set yours)
TZ=America/Los_Angeles

# already the recommended models; change only to use others
OLLAMA_MODEL=qwen3:8b
EMBED_MODEL=nomic-embed-text

# ranking, ingestion, schedule, and retention all ship with
# sensible defaults; leave them or tune later in Settings.

Then open http://<host>:8090/

On first run Cruxwire seeds its feed list from a sample and the pipeline generates the first digest, give it about a minute. Manage feeds in the UI's Feeds screen, or trigger a refresh with curl -X POST http://<host>:8090/refresh.

Running Ollama on the same machine?

Two things, not one. Point Cruxwire at the host with OLLAMA_HOST=http://host.docker.internal:11434 (inside the container, localhost is the container itself), and make sure Ollama itself is listening on 0.0.0.0:11434, not just loopback, or the container's connection is refused even when the hostname resolves. The Docker Desktop notes in the docs walk through both, with per-platform commands.

Step 3 · important

Keep it on a trusted network

Cruxwire's trust model is simple: the network is trusted, nothing more.

Cruxwire has no authentication

Every endpoint, including the ones that change settings, feeds, and categories or trigger pipeline runs, is reachable by anyone who can reach the port. Do not expose port 8090 directly to the internet. If you want remote access, put it behind a reverse proxy that adds auth: Caddy/nginx with basic auth, Authelia, Tailscale, Cloudflare Access, and similar.

Trusted feeds only

The pipeline fetches every feed you add and, for TL;DRs, the linked article pages. Treat your feed list as trusted input, and don't give the container network access to internal services it has no reason to reach.

No rate limiting or CSRF

The mutating endpoints have no rate limiting or CSRF protection. The trust model is "the network is trusted", keep it on a homelab LAN, a tailnet, or localhost.

Data is unencrypted

Runtime data, read history, Read Later, learned source preferences, is stored unencrypted on the Docker volume. Back it up, and protect it, accordingly.

Tuning

A few knobs worth knowing

Infrastructure wiring lives in docker-compose.yaml / .env; everything else is editable live in the Settings UI and applies on the next run without a restart.

Variable / settingDefaultPurpose
OLLAMA_HOSThttp://localhost:11434Ollama base URL for chat and embeddings.
Chat / embedding modelqwen3:8b / nomic-embed-textWhich Ollama models to use. Managed in Settings → Models.
Merge similarity0.74Cosine threshold to collapse same-topic articles into one card.
Lookback36 hHow far back fresh items are first discovered.
Retention floor / ceiling25 / 60Keep at least / at most this many unread stories.
Schedule0622, every 2 hWhen pipeline runs fire (active-hours window + interval).
History retention3 daysHow long read History is kept before it ages out. Read Later is never aged.
PORT8090Container HTTP port.

The repo's TUNING.md documents every adjustable knob, how they interact, and recipes for common situations ("it goes dry on weekends", "I'm seeing duplicate cards", "surface more of what I read"). Categories, their labels, colors, and the interest descriptions the scorer ranks against, are data you edit in categories.json or the Settings UI.

Data & persistence

Mutable data lives on the cruxwire-data volume (/data): state.json, feeds.json, digest.json, settings.json, runs.json, categories.json, and article embeddings. Rebuilds preserve it; back up the volume to keep your feed list, read history, and learned preferences.

Develop without Docker

No dependencies means you can run the server directly against local files with a handful of env vars pointed at your Ollama host. To iterate on the layout without a live feed setup, point the feeds file at a nonexistent path and drop in a real digest.json.

Grab the source and go

The repository has the full SPEC, the tuning guide, and sample feeds and categories to start from.