Sign inSign up

yavadmin/skribe

By yavadmin

•Updated about 2 months ago

Self-hosted, AI-powered voice notes and tasks

Buildkit cache
Image
0

2.0K

yavadmin/skribe repository overview

⁠Self-hosted, AI-powered voice notes and tasks

Hit record and say what's on your mind. Skribe works out whether it was a task — with a real due date, a priority and a project — or a note to be tidied into structured markdown, and files it in the right place.

Nothing is written until you accept it. The pipeline produces a proposal that sits on the recording until a human says yes.

Everything runs on your own machine, against your own database, pointed at whichever AI provider you choose — including a model running on the same box.

⁠Tags

TagWhat it is
latestThe head of main. Moves.
sha-<short>One commit, immutable. What to pin, and what to roll back to.
vX.Y.ZA release, once tagged.

⁠One image, one port

nginx inside the image serves the built frontend and reverse-proxies /api to Node on loopback, both under supervisord. Only 8080 is exposed. Put TLS in front of it and you are done — there is no second container to route between.

⁠Quick start

docker run -d --name skribe -p 8080:8080 \
  -e DATABASE_URL="postgres://user:pass@host:5432/skribe" \
  -e JWT_SECRET="$(openssl rand -base64 48)" \
  -e APP_URL="http://localhost:8080" \
  -e AI_API_KEY="sk-…" \
  -v skribe-uploads:/data/uploads \
  yavadmin/skribe:latest

Migrations run at start. Open http://localhost:8080⁠ and the first person to arrive is offered a setup screen and becomes the administrator.

⁠With Compose
services:
  app:
    image: yavadmin/skribe:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://skribe:skribe@postgres:5432/skribe
      JWT_SECRET: change-me-openssl-rand-base64-48
      APP_URL: http://localhost:8080
      AI_API_KEY: sk-…
    volumes:
      - uploads:/data/uploads
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    # pgvector, not plain postgres — semantic search will not migrate without it.
    image: pgvector/pgvector:pg17
    restart: unless-stopped
    environment:
      POSTGRES_USER: skribe
      POSTGRES_PASSWORD: skribe
      POSTGRES_DB: skribe
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U skribe -d skribe"]
      interval: 5s
      retries: 10

volumes:
  pgdata:
  uploads:

⁠Requirements

  • PostgreSQL with pgvector. The plain postgres image does not have it, and migrations will fail against one.
  • Somewhere for uploads: the volume at /data/uploads, or any S3-compatible store when S3_* is configured.
  • An AI provider — OpenAI, Anthropic, or anything OpenAI-compatible you run yourself.
  • For speech-to-text: an OpenAI or Groq key, or an OpenAI-compatible Whisper server of your own pointed at with STT_BASE_URL.

⁠Configuration

Variable
DATABASE_URLRequired. Postgres with pgvector.
JWT_SECRETRequired. openssl rand -base64 48. Back it up — see below.
APP_URLThe address the browser actually uses. Reset links, OAuth redirect URIs and invitations are built from it.
AI_API_KEYYour provider key.
AI_PROVIDERopenai (default), anthropic, or local.
ADMIN_EMAIL / ADMIN_PASSWORDCreates the administrator at boot, skipping the setup screen.
ALLOW_REGISTRATIONfalse once your account exists. Invitations still work.
COOKIE_SECUREtrue behind TLS.
STORAGE_DRIVERInferred. Set S3_ENDPOINT or S3_ACCESS_KEY_ID to use an object store.
SMTP_*Without it, password resets and invitations are logged, not sent.

Every option is documented inline in .env.example⁠.

⁠Health

GET /healthz returns JSON and 200. Use it as your platform's health check.

⁠Two things worth knowing

Back up JWT_SECRET with your database. It signs sessions, reset links, OAuth state and attachment URLs. Restoring a database without it signs everyone out and turns every image already written into a note into a broken link.

APP_URL causes more failed deployments than anything else. If sign-in works but "Continue with Google" fails, or reset emails point at localhost, that is what to check first.

⁠Platforms

linux/amd64. linux/arm64 is published when the repository opts in.

Tag summary

Content type

Image

Digest

sha256:69ab9e74e…

Size

214.9 MB

Last updated

about 2 months ago

docker pull yavadmin/skribe