No description
Find a file
Jon Seager 4ee89e2336
style(ui): simplify scan input and normalize form text
- Remove check-in and add links from scan input partial
- Add "or" separator between camera and text input
- Remove redundant text-sm from input fields (now in .input-field CSS)
- Fix label text size and color in check-in form
2026-02-07 20:59:02 +00:00
.cargo perf(build): add release profile, lld linker, and defer script tags 2026-02-06 18:05:16 +00:00
.github fix(ci): match docker tag to Cargo.toml version in deploy workflow 2026-02-06 20:16:31 +00:00
migrations feat(brews): add brew time field 2026-02-07 11:24:07 +00:00
scripts feat(brews): add brew time field 2026-02-07 11:24:07 +00:00
src feat(brews): make Brew Again navigate to pre-filled add form 2026-02-07 19:57:23 +00:00
static style(ui): restyle buttons, tabs, and form inputs 2026-02-07 20:58:41 +00:00
templates style(ui): simplify scan input and normalize form text 2026-02-07 20:59:02 +00:00
tests feat(brews): add brew time field 2026-02-07 11:24:07 +00:00
.gitignore perf(db): enable WAL mode, add tuning pragmas and missing indexes 2026-02-06 18:04:58 +00:00
build.rs fix(build): pass git hash to Nix builds via env var 2026-02-07 11:17:03 +00:00
Cargo.lock build(deps): bump axum from 0.7.9 to 0.8.8 (#6) 2026-02-06 19:04:14 +00:00
Cargo.toml build(deps): bump axum from 0.7.9 to 0.8.8 (#6) 2026-02-06 19:04:14 +00:00
CLAUDE.md docs: document SQLite config and HTTP middleware stack in CLAUDE.md 2026-02-06 18:05:21 +00:00
flake.lock chore: update flake.lock file 2026-02-06 17:27:49 +00:00
flake.nix fix(build): pass git hash to Nix builds via env var 2026-02-07 11:17:03 +00:00
fly.toml fix(deploy): change healthcheck path 2026-02-06 20:51:47 +00:00
LICENSE docs: add LICENSE 2026-02-03 20:53:45 +00:00
README.md chore: remove unused ADMIN env vars, document BREWLOG_INSECURE_COOKIES 2026-02-06 17:52:21 +00:00

B{rew}log

B{rew}log is a self-hosted coffee logging platform for tracking roasters, roasts, brews, cafes and brewing gear. It ships as a single Rust binary that serves a web UI, a REST API, and a CLI client.

  • Web UI with reactive updates via Datastar and Tailwind CSS v4
  • REST API for programmatic access (reads are public, writes require auth)
  • CLI client for terminal-based workflows
  • AI extraction — scan a coffee bag label or type a description to auto-fill forms (via OpenRouter)
  • Nearby cafe search powered by Foursquare Places
  • SQLite database
  • Passkey authentication — no passwords, WebAuthn only

Quick Start

Install

cargo install --git https://github.com/jnsgruk/brewlog.git

Configure

Create a .env file (or export the variables). Four values are required:

BREWLOG_RP_ID="localhost"
BREWLOG_RP_ORIGIN="http://localhost:3000"
BREWLOG_OPENROUTER_API_KEY="sk-or-..."
BREWLOG_FOURSQUARE_API_KEY="fsq3..."

Run

brewlog serve

On first start with an empty database the server prints a one-time registration URL:

No users found. Register the first user at:
  http://localhost:3000/register/abc123...
This link expires in 1 hour.

Open that URL, choose a display name, and register a passkey. This creates your account and signs you in.

CLI Authentication

To use the CLI or API for write operations, create a token via browser handoff:

brewlog token create --name "my-cli-token"
# Browser opens → authenticate with your passkey → token printed once

export BREWLOG_URL="http://localhost:3000"
export BREWLOG_TOKEN="<token from above>"

# Now you can create data from the CLI
brewlog roaster add --name "Radical Roasters" --country "United Kingdom"

Run brewlog --help for the full command reference.

Configuration

All settings are read from environment variables or CLI flags. A .env file in the working directory is loaded automatically via dotenvy.

Server (brewlog serve)

Variable Purpose Default
BREWLOG_RP_ID WebAuthn Relying Party ID (your domain) required
BREWLOG_RP_ORIGIN WebAuthn Relying Party origin (full URL) required
BREWLOG_DATABASE_URL Database connection string sqlite://brewlog.db
BREWLOG_BIND_ADDRESS Server bind address 127.0.0.1:3000
BREWLOG_INSECURE_COOKIES Disable the Secure cookie flag (set true for local dev over HTTP) false
RUST_LOG Log level filter info
RUST_LOG_FORMAT Set to json for structured log output

CLI Client

Variable Purpose Default
BREWLOG_URL Server URL http://localhost:3000
BREWLOG_TOKEN API bearer token for write operations

Integrations

Variable Purpose Default
BREWLOG_OPENROUTER_API_KEY OpenRouter API key for AI extraction required
BREWLOG_OPENROUTER_MODEL LLM model for AI extraction openrouter/free
BREWLOG_FOURSQUARE_API_KEY Foursquare Places API key for nearby cafe search required

Database

SQLite is used for storage. Migrations run automatically on server startup.

Running with Docker

The Nix flake includes a Docker image built with dockerTools:

nix build .#brewlog-container
docker load < result

Create a docker.env file:

BREWLOG_OPENROUTER_API_KEY=sk-or-...
BREWLOG_OPENROUTER_MODEL=google/gemini-3-flash-preview
BREWLOG_FOURSQUARE_API_KEY=fsq3...
BREWLOG_RP_ID=localhost
BREWLOG_BIND_ADDRESS=0.0.0.0:3000
BREWLOG_RP_ORIGIN=http://localhost:4000
BREWLOG_INSECURE_COOKIES=true
mkdir data
docker run --rm -p 4000:3000 --env-file docker.env -v $PWD/data:/data brewlog:0.1.0

The database is stored at /data/brewlog.db inside the container — mount a host directory to /data to persist it.

Contributing

cargo build                           # Build
cargo clippy --allow-dirty --fix      # Lint
cargo fmt                             # Format
cargo test                            # Test

See CLAUDE.md for architecture, code patterns, and development conventions.

License

Apache License 2.0