Skip to content

YavLabs/docx

docx

Self-hosted, offline-first document management and file manager

License Version Docker PWA


Features

  • Notion-style document editor — block-based rich text with headings, callouts, tables, code blocks, embeds, slash commands, and drag-and-drop reordering via BlockNote
  • File manager — upload, organize, preview, and download files; ZIP extraction; breadcrumb navigation; card and list view
  • Document versioning — full revision history with author attribution and restore
  • Rich previews — PDF, images, Markdown, plain text; Office documents converted via LibreOffice/Gotenberg headless pipeline
  • AI search and Q&A — semantic search powered by pgvector; conversational Q&A over your document corpus via Claude or OpenAI (auto-selected); offline fallback via Ollama
  • Workspaces with RBAC — multi-tenant; per-workspace roles: owner, admin, member, viewer
  • Auth — email + password (argon2) and Google OAuth; JWT access + rotating refresh tokens; super-admin seeded from environment on first boot
  • Sharing — share documents and files with users inside or outside your workspace via public links or direct invite
  • Offline-first PWA — full local-first operation via Dexie (IndexedDB); all writes are queued through an outbox and synced when back online; installable via browser
  • Dark mode out of the box
  • Docker Compose deployment — single port exposed via nginx; everything else is internal

Tech Stack

Layer Technology
Backend Python 3.12 + FastAPI
ORM / Migrations SQLAlchemy 2.x + Alembic
Frontend Vite + React (JSX, no TypeScript) + shadcn/ui + Tailwind CSS
Editor BlockNote
Database PostgreSQL 16 + pgvector
Auth argon2-cffi, JWT (access + refresh), Google OAuth
AI (cloud) Anthropic Claude (LLM) + OpenAI text-embedding-3-small
AI (offline) Ollama (llama3.1 + nomic-embed-text)
Job Queue Arq (Redis-backed)
Cache Redis 7
File Storage Pluggable — bundled MinIO, AWS S3, Cloudflare R2, Backblaze B2, or Azure Blob Storage (presigned URLs everywhere)
Offline Sync Dexie (IndexedDB) + outbox pattern
PWA vite-plugin-pwa
Reverse Proxy Nginx (single host-exposed port)
Office Conversion Gotenberg (LibreOffice headless)

Quick Start

Prerequisites

  • Docker and Docker Compose v2+
  • Git

1. Clone the repository

git clone https://github.com/YavLabs/docx.git
cd docx

2. Configure environment

cp .env.example .env

Open .env and fill in the required values. At minimum, set:

  • APP_BASE_URL — the public URL users open in their browser (e.g. http://localhost:8080, http://10.6.30.16:8080, or https://docx.example.com). Every emitted URL (emails, OAuth callback, presigned downloads) derives from this.
  • POSTGRES_PASSWORD — database password
  • JWT_SECRET — generate with openssl rand -hex 32
  • MINIO_ROOT_PASSWORD — MinIO root credentials (only required when using the bundled MinIO)
  • SUPERADMIN_EMAIL and SUPERADMIN_PASSWORD — initial super-admin account

Public URL behind a reverse proxy

When you run docx behind NGINX Proxy Manager, Caddy, Cloudflare, or any other TLS-terminating front-end, just point that proxy at the docker host on ${APP_PORT} and set APP_BASE_URL to the public address. The backend rebuilds all outbound links — verification emails, password resets, share links, OAuth redirects, and presigned download URLs — using that value.

Choosing an object-storage backend

STORAGE_BACKEND selects the driver:

Backend Use when Required env
s3 (default) Bundled MinIO, AWS S3, Cloudflare R2, Backblaze B2, etc. STORAGE_BUCKET, STORAGE_ACCESS_KEY, STORAGE_SECRET_KEY, STORAGE_ENDPOINT_URL (blank → fall back to the bundled MinIO), STORAGE_REGION, STORAGE_SECURE
azure Azure Blob Storage STORAGE_BUCKET (= container), STORAGE_AZURE_ACCOUNT_NAME, STORAGE_AZURE_ACCOUNT_KEY, optional STORAGE_AZURE_ENDPOINT

Same call sites everywhere — the rest of the codebase goes through one ObjectStore interface so the bucket name, credentials, and endpoint are all you need to switch.

STORAGE_PRESIGN_REWRITE_TO_PUBLIC controls whether presigned URLs are made same-origin (true, the right choice for MinIO behind nginx) or kept absolute (false, for AWS / R2 / Azure). The default auto picks the right behavior based on the endpoint hostname.

3. Start the stack

docker compose up -d --build

This starts: PostgreSQL, Redis, MinIO, the FastAPI backend, an Arq worker, the Vite frontend, Gotenberg, and an Nginx reverse proxy.

4. Run database migrations

docker compose exec api uv run alembic upgrade head

The super-admin account is seeded automatically on first boot using SUPERADMIN_EMAIL / SUPERADMIN_PASSWORD.

5. (Optional) Enable local AI

docker compose --profile ai-local up -d ollama

When OLLAMA_BASE_URL is reachable the AI provider falls back to local models automatically — no cloud credentials required.

6. Access docx

Open http://localhost:8080 in your browser (or your configured APP_PORT).

Log in with the super-admin credentials from your .env file.

7. Going to production

For pointing the app at a real domain, swapping object storage, publishing Docker images, and using the prebuilt docker-compose.prod.yml, see DEPLOY.md. Highlights:

  • Single APP_BASE_URL change → emails, CORS, OAuth, presigned URLs all switch.
  • STORAGE_BACKEND + STORAGE_* → external MinIO, AWS S3, R2, B2, or Azure Blob.
  • scripts/reset.sh → nukes volumes, brings the stack back up looking like first boot.
  • scripts/publish-images.sh + .github/workflows/publish-images.yml → publish yavadmin/docx-* to Docker Hub.
  • docker-compose.prod.yml → deploy with prebuilt images.

Development Setup

Backend

cd apps/api
cp ../../.env.example ../../.env   # if not already done
uv sync
uv run alembic upgrade head
uv run uvicorn app.main:app --reload --port 8000

Frontend

cd apps/web
npm install
npm run dev

The Vite dev server runs on port 5173. In development the full stack is accessible through nginx on APP_PORT (default 8080), which proxies HMR WebSocket connections automatically.

Running tests

# Backend
cd apps/api && uv run pytest

# Frontend
cd apps/web && npm test

Environment Variables

All variables are documented in .env.example. The file is organized into sections:

  • AppAPP_PORT (nginx host port, default 8080) and APP_BASE_URL (the single public origin every emitted URL derives from)
  • CORSEXTRA_CORS_ORIGINS for extra allowed origins; APP_BASE_URL is allowed automatically
  • PostgreSQL — database connection
  • Object storageSTORAGE_BACKEND (s3 or azure), STORAGE_BUCKET, plus the backend-specific credentials
  • MinIO — legacy block kept as a default fallback for the s3 backend
  • Redis — Arq job queue and cache
  • Gotenberg — Office-to-PDF conversion service
  • EncryptionSETTINGS_ENC_KEY for app settings stored in the database
  • JWTJWT_SECRET, access / refresh token lifetimes
  • Super AdminSUPERADMIN_EMAIL / SUPERADMIN_PASSWORD seeded on first boot
  • Google OAuth — optional; GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET (the redirect URI auto-derives from APP_BASE_URL)
  • AI providersANTHROPIC_API_KEY, OPENAI_API_KEY, OLLAMA_BASE_URL; the provider is auto-selected; all three are optional but at least one is needed for AI features

Architecture

                    +-------------+
                    |    Nginx    |  port APP_PORT  (public via APP_BASE_URL)
                    +------+------+
                      /    |    \        \
              +------+  +--+--+  +-------+-------+
              |  Web  |  | API |  | Object Store  |
              | :5173 |  |:8000|  | (MinIO / S3 / |
              +-------+  +--+--+  |  R2 / Azure)  |
                            |     +---------------+
                   +--------+--------+
                   |                 |
            +------+------+   +------+------+
            | PostgreSQL  |   |    Redis    |
            | + pgvector  |   | (queue/cache|
            +-------------+   +------+------+
                                     |
                              +------+------+
                              |   Worker    |
                              |   (Arq)     |
                              +------+------+
                                     |
                  +------------------+------------------+
                  |                                     |
           +------+------+                      +-------+------+
           |  Gotenberg  |                      |    Ollama    |
           | (Office PDF)|                      | (local AI,   |
           +-------------+                      |  optional)   |
                                                +--------------+

Key design principles:

  • Offline-first — every write is queued via an outbox; every read has a Dexie fallback; the app is fully functional with no network
  • One public originAPP_BASE_URL is the single canonical URL; CORS, OAuth callbacks, email links, and presigned download URLs all derive from it
  • Pluggable object storage — a single ObjectStore interface backs MinIO, AWS S3, R2/B2 (any S3-compatible service), and Azure Blob — picked by env, no code changes
  • Provider abstraction for AI — Claude, OpenAI, and Ollama all satisfy a single AIProvider protocol; the app picks the best available at runtime
  • Single ingress — only nginx is exposed to the host; all other services communicate on the internal Docker network
  • RBAC-first — every API endpoint enforces role permissions before executing

Project Structure

docx/
  apps/
    api/
      app/
        auth/          # JWT, OAuth, password hashing
        workspaces/    # Workspace RBAC + membership
        documents/     # BlockNote doc storage + versioning
        files/         # MinIO upload/download/preview
        ai/            # AIProvider protocol + Claude/OpenAI/Ollama impls
        search/        # pgvector semantic search
        sync/          # Outbox + sync API for offline clients
        core/          # DB session, settings, middleware
      alembic/         # Database migrations
      tests/
    web/
      src/
        components/    # Reusable UI (shadcn/ui + Radix primitives)
        pages/         # Route-level page components
        hooks/         # Custom React hooks
        db/            # Dexie schema + offline storage
        outbox/        # Offline write queue + sync engine
        services/      # API client functions
        lib/           # Utilities and formatters
      public/
  packages/
    ui/                # Shared shadcn/Radix primitives (JSX)
  nginx/
    nginx.conf
  docker-compose.yml
  .env.example

Build Phases

Phase Status Description
0 Done Scaffold — monorepo, Docker Compose, nginx routing
1 Done Auth + workspaces + RBAC + super-admin seed
2 Done Files — object-storage upload/download + file manager UI
3 Done Documents — BlockNote editor + versioning
4 Done Preview pipeline — PDF, images, Office, text/MD
5 Done AI search and Q&A (cloud)
6 Done Sharing, exports, permissions UI
7 In progress Offline — PWA + Dexie + outbox + sync API
8 Planned Ollama fallback (local AI)
9 Planned Full AI provider compatibility — first-class adapters for Anthropic, OpenAI, Azure OpenAI, Google Gemini, Mistral, Groq, Together, OpenRouter, Cohere, vLLM, and any OpenAI-compatible endpoint; per-workspace provider selection; cost/usage telemetry
10 Planned MCP (Model Context Protocol) — expose docx as an MCP server (documents, files, search, Q&A as tools/resources) so external agents and IDEs can read/write the corpus, plus inbound MCP-client support so docx's AI can call external MCP tools

Contributing

Contributions are welcome. Please see CONTRIBUTING.md for guidelines on how to get started.

Security

If you discover a security vulnerability, do not open a public issue. Please refer to SECURITY.md for responsible disclosure instructions.

License

docx is licensed under the GNU Affero General Public License v3.0.

Copyright 2026 YavLabs / Yash.

Screenshots

Coming soon.

About

docx — document management + file manager with offline-first PWA

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors