From ad8303fe48844a1f2a0fa0c21fa47c529168a9cb Mon Sep 17 00:00:00 2001 From: Patrick Erber Date: Tue, 26 May 2026 12:03:34 +0200 Subject: [PATCH 1/4] docs: update readme --- readme.md | 586 ++++++++++++++++++++---------------------------------- 1 file changed, 212 insertions(+), 374 deletions(-) diff --git a/readme.md b/readme.md index fdc39001..e7059d7a 100644 --- a/readme.md +++ b/readme.md @@ -1,78 +1,64 @@ # 🌿 LeafWiki -**LeafWiki helps engineers, self-hosters, and small teams keep long-lived documentation structured, portable, and easy to operate.** -Self-hosted. Single Go binary. SQLite-based. Markdown stored on disk. +[![GitHub Stars](https://img.shields.io/github/stars/perber/leafwiki?style=flat-square)](https://github.com/perber/leafwiki/stargazers) [![Latest Release](https://img.shields.io/github/v/release/perber/leafwiki?style=flat-square)](https://github.com/perber/leafwiki/releases) [![Backend CI](https://github.com/perber/leafwiki/actions/workflows/backend.yml/badge.svg)](https://github.com/perber/leafwiki/actions/workflows/backend.yml) [![Frontend CI](https://github.com/perber/leafwiki/actions/workflows/frontend.yml/badge.svg)](https://github.com/perber/leafwiki/actions/workflows/frontend.yml) -If you want something lighter than a large wiki suite, but more structured than scattered notes, LeafWiki is built for that middle ground. +Self-hosted wiki. Single Go binary. SQLite + Markdown stored on disk. -LeafWiki is a real wiki application built around Markdown, not a plain Markdown file browser. It provides structured navigation, editing, search, roles, and managed content workflows inside the app. +For engineers and self-hosters who want structured, long-lived documentation. No Node.js, no Redis, no Postgres β€” just a binary and a data directory. ![LeafWiki](./assets/preview.png) -## Why it exists +If you've looked at Wiki.js or Outline and thought "this is too much to operate for what I need" β€” this is the alternative. -LeafWiki is for documentation that needs to stay understandable over time: runbooks, internal docs, personal knowledge bases, and operational notes. +β†’ Try it without installing: **[demo.leafwiki.com](https://demo.leafwiki.com)** Β· `Ctrl+E` edit Β· `Ctrl+S` save Β· resets hourly +β†’ If it fits, [a star](https://github.com/perber/leafwiki) helps others find it. -The goal is not to become an all-in-one workspace. The goal is to give you a wiki that is small enough to operate comfortably and structured enough to trust for long-lived documentation. - -## Quick facts - -- Single Go binary -- SQLite-based runtime storage -- Markdown-first editing and content portability -- Works with Docker or direct binary install -- Multi-platform builds for Linux, macOS, Windows, and ARM64 -- Reverse-proxy friendly with `--base-path` -- Public read-only mode available -- Optional revision history and link refactoring behind feature flags - -## Why it fits this workflow - -- Explicit tree navigation instead of flat note feeds -- Markdown content that is easy to back up, move, and version -- Public read-only docs with authenticated editing -- Optimistic locking for concurrent edits -- Optional revision history and safe link refactoring -- Small operational footprint without external database setup - -## Good fit - -- Personal wikis and engineering notebooks -- Internal team documentation -- Internal documentation archives and historical knowledge bases -- Runbooks, SOPs, and operational guides -- Existing Markdown documentation sets or Obsidian-style vaults that need a more structured internal wiki -- Homelab and self-hosted environments -- Teams that prefer explicit tree navigation over flat note feeds - -## Probably not a fit - -- Large organizations needing complex enterprise permissions or workflow engines -- Real-time collaborative editing -- Knowledge management setups that expect databases, automations, and approval flows everywhere -- Teams looking for a Confluence or Notion clone +```bash +docker run -p 8080:8080 -v ~/leafwiki-data:/app/data \ + ghcr.io/perber/leafwiki:latest \ + --jwt-secret=yoursecret --admin-password=yourpassword --allow-insecure=true +``` -LeafWiki is intentionally narrower than those systems. That focus is part of the value. +β†’ [All install options](#install) (Docker Compose, Linux installer, binary) --- -## Live Demo +## Features -A public demo of LeafWiki is available here: - -🌐 **[demo.leafwiki.com](https://demo.leafwiki.com)** -πŸ—ΊοΈ **[Roadmap](https://leafwiki.com/roadmap)** - -Try: `Ctrl+E` to edit, `Ctrl+S` to save, `Ctrl+Shift+F` to open the search. +**Operations:** +- Single Go binary β€” no external database, no runtime dependencies +- Markdown on disk β€” page content is readable outside the app, backup is `cp -r` (stop the app first) +- Runs on Linux, macOS, Windows, Raspberry Pi (x86_64 and ARM64) +- Reverse-proxy friendly with `--base-path` +- Reverse-proxy authentication via trusted HTTP header (v0.10+) +- Public read-only mode with authenticated editing +- Roles: admin, editor, viewer + +**Core functionality:** +- Tree navigation β€” explicit hierarchy, not flat note feeds +- Full-text search across titles and content, with tag-based filtering +- Tags on pages β€” searchable and filterable across the wiki +- Backlinks and link status per page (incoming, outgoing, broken links) +- Built-in Markdown editor with live preview, keyboard shortcuts, and autocomplete for internal page links +- Optimistic locking for concurrent edits +- Markdown: tables, task lists, footnotes, callouts (`:::info` / `:::warning`), Mermaid diagrams, sanitized inline HTML -Login credentials are displayed on the demo site. -The demo instance resets automatically every hour, so all changes are temporary. +**Customization:** +- Custom stylesheet (`--custom-stylesheet`, v0.8.5+) +- Inject HTML/JS into `` for analytics or custom CSS +- Branding: logo, favicon, site name +- Dark mode and mobile-friendly UI ---- +**Opt-in via feature flags:** +- Revision history (`--enable-revision`) +- Automatic link rewriting when pages are renamed or moved (`--enable-link-refactor`) -**Mobile View:** +**Markdown import:** +- ZIP-based importer for editors and admins +- Supports Obsidian-style wiki link rewriting on import +- Best results with a reasonably clean folder structure; not a fully automatic converter for all source formats -Mobile-friendly UI for reading (and editing) docs & runbooks on the go. +**Mobile:**

@@ -82,71 +68,27 @@ Mobile-friendly UI for reading (and editing) docs & runbooks on the go. --- -## Keep internal links intact - -Renaming or moving pages often breaks internal documentation. - -LeafWiki can rewrite internal links when: -- a page is renamed -- a page is moved in the tree - -This helps keep long-lived documentation coherent as the structure changes. - -> Revision history and link refactoring are currently available behind feature flags: `--enable-revision` and `--enable-link-refactor`. - ---- - -## Import existing Markdown - -LeafWiki includes a built-in Markdown importer for editors and admins. - -This is especially relevant if you already have a Markdown archive, a historical document collection, or an Obsidian-style vault that you want to bring into a self-hosted internal wiki. - -What to expect: -- ZIP-based import workflow -- review the generated import plan before running it -- best results when the source already has a reasonably clean folder structure -- linked Markdown pages and local assets can be imported together -- Obsidian-style wiki links can be rewritten during import -- metadata preservation is a relevant migration use case, but more advanced metadata workflows are still evolving - -It is intended as a pragmatic migration helper, not a fully automatic migration system for every source format. - ---- - -## What LeafWiki supports - -- Fast writing flow with keyboard shortcuts -- Built-in Markdown editor with live preview -- Full-text search across page titles and content -- Images, files, Mermaid diagrams, and practical Markdown extensions -- Admin, editor, and viewer roles -- Branding options such as logo, favicon, and site name -- Dark mode and mobile-friendly UI - -Revision history and link refactoring are currently available behind feature flags: `--enable-revision` and `--enable-link-refactor`. - -LeafWiki's editor and live preview support standard Markdown plus practical documentation features such as tables, task lists, footnotes, shoutouts, Mermaid diagrams, embedded audio/video, and a sanitized subset of inline HTML. +## Good fit / not a fit -## What LeafWiki is not +**Good fit:** +- Personal wikis, engineering notebooks, and runbooks +- Internal team or homelab documentation +- Existing Markdown or Obsidian vaults that need a structured wiki UI +- Small teams that want tree navigation over flat note feeds +- Self-hosted environments with low operational overhead -- Not a full Confluence replacement -- Not real-time collaborative editing -- Not a workflow, approval, or document-control platform -- Not a database-heavy documentation stack +**Probably not a fit:** +- Organizations needing complex enterprise permissions or approval workflows +- Real-time collaborative editing +- Teams looking for a Confluence or Notion replacement -LeafWiki is designed to stay focused, predictable, and easy to operate. +LeafWiki is intentionally narrower than those systems. That focus is part of the value. --- -## Installation - -LeafWiki is distributed as a single Go binary and can be run directly on the host or via Docker. -Start with the quickest path below. The more detailed deployment and configuration options follow after that. +## Install -### Quick start - -If you already run self-hosted apps with containers, start here: +### Docker ```bash docker run -p 8080:8080 \ @@ -157,18 +99,9 @@ docker run -p 8080:8080 \ --allow-insecure=true ``` -The container stores data in `/app/data` and binds to `0.0.0.0` by default. -For plain HTTP setups, `--allow-insecure=true` is required for login cookies to work. -If you serve LeafWiki behind HTTPS or a reverse proxy that forwards HTTPS headers, omit `--allow-insecure=true`. - -### Other deployment options +`--allow-insecure=true` is required for plain HTTP. Omit it when serving over HTTPS. -- Use the installer if you want a system service on a Linux host -- Use Docker Compose if you prefer a compose-based setup -- Use the binary if you want the smallest and most direct install - -**Running as non-root user** -To avoid running the container as root, specify a user ID: +**Non-root:** ```bash docker run -p 8080:8080 \ @@ -180,44 +113,44 @@ docker run -p 8080:8080 \ --allow-insecure=true ``` -Make sure that the mounted data directory is writable by the specified user. +The data directory must be writable by the specified user. + +### Docker Compose -### Quick start with the installer +```yaml +services: + leafwiki: + image: ghcr.io/perber/leafwiki:latest + container_name: leafwiki + user: 1000:1000 + ports: + - "8080:8080" + environment: + - LEAFWIKI_JWT_SECRET=yourSecret + - LEAFWIKI_ADMIN_PASSWORD=yourPassword + - LEAFWIKI_ALLOW_INSECURE=true # For HTTPS deployments, omit this. + volumes: + - ~/leafwiki-data:/app/data + restart: unless-stopped +``` -The easiest way to install LeafWiki is using the provided installation script: +### Linux installer ```bash sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/perber/leafwiki/main/install.sh)" ``` -To update LeafWiki, you can use the following command: +Installs LeafWiki as a system service. Tested on Ubuntu, Debian, and Raspbian. + +**Update:** ```bash sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/perber/leafwiki/main/update.sh)" ``` -> **Note:** This update script only works if you installed LeafWiki using the classic installer script above. It is not compatible with Docker or manual binary installations. - -This installs LeafWiki as a system service on the target machine. -The service is started automatically after installation. -> The installation script has been tested on Ubuntu, Debian, and Raspbian. -> Feedback for other distributions is welcome via GitHub issues. - -#### Deployment examples -- [Install LeafWiki with nginx on Ubuntu](docs/install/nginx.md) -- [Install LeafWiki on a Raspberry Pi](docs/install/raspberry.md) - -#### Security notes -In interactive mode, environment variables appear in plain text in file `/etc/leafwiki/.env`. -Make sure that this file is accessible only to authorized users. +> Only works if you installed with the script above. Not compatible with Docker or binary installs. -#### Installer script options - -**Non-interactive mode** - -The script supports non-interactive mode for automated deployments. Use the `--non-interactive` flag and provide configuration via an `.env` file. - -An `.env.example` file is included showing all available environment variables. Copy and customize it as needed: +**Non-interactive mode:** ```bash cp .env.example .env @@ -225,157 +158,131 @@ cp .env.example .env sudo ./install.sh --non-interactive --env-file ./.env ``` ---- +> Security: in interactive mode, environment variables are written in plain text to `/etc/leafwiki/.env`. Restrict access to that file. -### Docker Compose +**Deployment examples:** +- [Install with nginx on Ubuntu](docs/install/nginx.md) +- [Install on a Raspberry Pi](docs/install/raspberry.md) -```yaml -services: - leafwiki: - image: ghcr.io/perber/leafwiki:latest - container_name: leafwiki - user: 1000:1000 # Run as non-root (specify your {UID}:{GID}) - ports: - - "8080:8080" - environment: - - LEAFWIKI_JWT_SECRET=yourSecret - - LEAFWIKI_ADMIN_PASSWORD=yourPassword - - LEAFWIKI_ALLOW_INSECURE=true # WARNING: Enables HTTP by disabling Secure/HttpOnly cookies; for HTTPS deployments, omit this variable. HTTPS is the preferred method. - volumes: - - ~/leafwiki-data:/app/data - restart: unless-stopped -``` - -Make sure the mounted data directory (`~/leafwiki-data`) is writable by the user specified in the `user` field. - -### Quick start with a binary - -Download the latest release binary from GitHub, make it executable, and start the server: +### Binary ```bash chmod +x leafwiki ./leafwiki --jwt-secret=yoursecret --admin-password=yourpassword --allow-insecure=true ``` -**Note:** By default, the server listens on `127.0.0.1`, which means it will only be accessible from localhost. If you want to access the server from other machines on your network, add `--host=0.0.0.0` to the command: +The server binds to `127.0.0.1:8080` by default. To expose it on the network: ```bash ./leafwiki --jwt-secret=yoursecret --admin-password=yourpassword --host=0.0.0.0 --allow-insecure=true ``` -Default port is `8080`, and the default data directory is `./data`. -You can change the data directory with the `--data-dir` flag. +Default data directory is `./data`. Change with `--data-dir`. -The JWT secret is required for authentication and should be kept secure. -For plain HTTP setups such as localhost testing or direct LAN access, `--allow-insecure=true` is required so the browser accepts login and CSRF cookies. -When LeafWiki is served over HTTPS, leave `--allow-insecure` disabled. +### Reset admin password -### Operations notes +```bash +./leafwiki reset-admin-password +``` -- Default bind address is `127.0.0.1` unless you set `--host` or use the official Docker image -- Default data directory is `./data` on direct binary installs and `/app/data` in the container -- `--public-access` allows public read-only access while keeping editing authenticated -- `--disable-auth` is only appropriate for trusted internal networks or local development +--- -These defaults are intentionally conservative so a fresh install does not become network-exposed by accident. +## Dev Setup +**Stack:** Go Β· React (Vite) Β· SQLite -## Authentication and admin user +```bash +git clone https://github.com/perber/leafwiki.git +cd leafwiki +``` -### Reset Admin Password -If you need to reset the admin password: +**Terminal 1 β€” Frontend:** +```bash +cd ui/leafwiki-ui +npm install +npm run dev +``` +**Terminal 2 β€” Backend:** ```bash -./leafwiki reset-admin-password +cd cmd/leafwiki +go run main.go --jwt-secret=yoursecret --allow-insecure=true --admin-password=yourpassword ``` -## Runtime Configuration +Vite starts on `http://localhost:5173`. The backend binds to `127.0.0.1` by default. + +See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. + +--- + +## Configuration -LeafWiki can be configured using command-line flags or environment variables. -These options control how the server runs after installation. +### Required -If you are just getting started, the most important options are usually: +| Flag | Description | +|------|-------------| +| `--jwt-secret` | Secret for signing JWTs. Keep it secure. | +| `--admin-password` | Initial admin password (only applied if no admin exists yet). | -- `--jwt-secret` -- `--admin-password` -- `--host` -- `--data-dir` -- `--public-access` -- `--base-path` -- `--allow-insecure` +For plain HTTP: add `--allow-insecure=true` so login and CSRF cookies work. ### CLI Flags -| Flag | Description | Default | Available since | -|---------------------------------|------------------------------------------------------------------------|---------------|-------------------| -| `--jwt-secret` | Secret used for signing JWTs (required) | – | – | -| `--host` | Host/IP address the server binds to | `127.0.0.1` | – | -| `--port` | Port the server listens on | `8080` | – | -| `--data-dir` | Directory where data is stored | `./data` | – | -| `--admin-password` | Initial admin password *(used only if no admin exists)* (required) | – | – | -| `--public-access` | Allow public read-only access | `false` | – | -| `--hide-link-metadata-section` | Hide link metadata section | `false` | – | -| `--inject-code-in-header` | Raw HTML/JS code injected into tag (e.g., analytics, custom CSS)| `""` | v0.6.0 | -| `--custom-stylesheet` | Path to a `.css` file inside the data dir, served publicly as `/custom.css` or `${base-path}/custom.css` | `""` | v0.8.5 | -| `--allow-insecure` | ⚠️ Allows insecure HTTP usage for auth cookies (required for plain HTTP) | `false` | v0.7.0 | -| `--access-token-timeout` | Access token timeout duration (e.g. 24h, 15m) | `15m` | v0.7.0 | -| `--refresh-token-timeout` | Refresh token timeout duration (e.g. 168h, 7d) | `7d` | v0.7.0 | -| `--disable-auth` | ⚠️ Disable authentication & authorization (internal networks only!) | `false` | v0.7.0 | -| `--base-path` | URL prefix when served behind a reverse proxy (e.g. /wiki) | `""` | v0.8.2 | -| `--max-asset-upload-size` | Maximum size for asset uploads (e.g. `50MiB`, `50MB`, `52428800`) | `50MiB` | v0.8.5 | -| `--enable-revision` | Enable revision history / page history | `false` | v0.9.0 | -| `--enable-link-refactor` | Enable link refactoring dialog and rewrite flow | `false` | v0.9.0 | -| `--max-revision-history` | Maximum revisions kept per page; `0` means unlimited | `100` | v0.9.0 | -| `--enable-http-remote-user` | Enable reverse-proxy authentication via trusted HTTP header | `false` | v0.10.0 | -| `--http-remote-user-header-name` | Header name carrying the username from a trusted proxy | `Remote-User` | v0.10.0 | -| `--trusted-proxy-ips` | Comma-separated trusted proxy IPs/CIDRs allowed to supply that header | `""` | v0.10.0 | -| `--http-remote-user-logout-url` | Frontend logout redirect URL when reverse-proxy auth is active | `""` | v0.10.0 | - - -> When using the official Docker image, `LEAFWIKI_HOST` defaults to `0.0.0.0` if neither a `--host` flag nor `LEAFWIKI_HOST` is provided, as the container entrypoint sets this automatically. +| Flag | Description | Default | Since | +|----------------------------------|-------------------------------------------------------------------------|---------------|---------| +| `--host` | Host/IP the server binds to | `127.0.0.1` | – | +| `--port` | Port the server listens on | `8080` | – | +| `--data-dir` | Directory where data is stored | `./data` | – | +| `--public-access` | Allow public read-only access | `false` | – | +| `--base-path` | URL prefix for reverse proxy setups (e.g. `/wiki`) | `""` | v0.8.2 | +| `--allow-insecure` | ⚠️ Enables HTTP for auth cookies (required for plain HTTP) | `false` | v0.7.0 | +| `--disable-auth` | ⚠️ Disable all authentication (internal networks only) | `false` | v0.7.0 | +| `--access-token-timeout` | Access token duration (e.g. `24h`, `15m`) | `15m` | v0.7.0 | +| `--refresh-token-timeout` | Refresh token duration (e.g. `168h`, `7d`) | `7d` | v0.7.0 | +| `--max-asset-upload-size` | Max upload size (e.g. `50MiB`, `52428800`) | `50MiB` | v0.8.5 | +| `--custom-stylesheet` | Path to a `.css` file inside the data dir | `""` | v0.8.5 | +| `--inject-code-in-header` | Raw HTML/JS injected into `` | `""` | v0.6.0 | +| `--hide-link-metadata-section` | Hide backlinks and link status panel | `false` | – | +| `--enable-revision` | Enable revision history | `false` | v0.9.0 | +| `--enable-link-refactor` | Enable link rewriting on rename/move | `false` | v0.9.0 | +| `--max-revision-history` | Max revisions per page; `0` = unlimited | `100` | v0.9.0 | +| `--enable-http-remote-user` | Enable reverse-proxy auth via HTTP header | `false` | v0.10.0 | +| `--http-remote-user-header-name` | Header name carrying the username from the proxy | `Remote-User` | v0.10.0 | +| `--trusted-proxy-ips` | Trusted proxy IPs/CIDRs for remote-user header | `""` | v0.10.0 | +| `--http-remote-user-logout-url` | Logout redirect when reverse-proxy auth is active | `""` | v0.10.0 | + +> Docker image default: `LEAFWIKI_HOST` is set to `0.0.0.0` automatically by the container entrypoint if neither `--host` nor `LEAFWIKI_HOST` is provided. ### Environment Variables -The same configuration options can also be provided via environment variables. -This is especially useful in containerized or production environments. - -| Variable | Description | Default | Available since | -|----------------------------------------|-------------------------------------------------------------------------|------------|-----------------| -| `LEAFWIKI_HOST` | Host/IP address the server binds to | `127.0.0.1`| - | -| `LEAFWIKI_PORT` | Port the server listens on | `8080` | - | -| `LEAFWIKI_DATA_DIR` | Path to the data storage directory | `./data` | - | -| `LEAFWIKI_ADMIN_PASSWORD` | Initial admin password *(used only if no admin exists yet)* (required) | – | - | -| `LEAFWIKI_JWT_SECRET` | Secret used to sign JWT tokens *(required)* | – | - | -| `LEAFWIKI_PUBLIC_ACCESS` | Allow public read-only access | `false` | - | -| `LEAFWIKI_HIDE_LINK_METADATA_SECTION` | Hide link metadata section | `false` | - | -| `LEAFWIKI_INJECT_CODE_IN_HEADER` | Raw HTML/JS code injected into tag (e.g., analytics, custom CSS) | `""` | v0.6.0 | -| `LEAFWIKI_CUSTOM_STYLESHEET` | Path to a `.css` file inside the data dir, served publicly as `/custom.css` or `${LEAFWIKI_BASE_PATH}/custom.css` | `""` | v0.8.5 | -| `LEAFWIKI_ALLOW_INSECURE` | ⚠️ Allows insecure HTTP usage for auth cookies (required for plain HTTP) | `false` | v0.7.0 | -| `LEAFWIKI_ACCESS_TOKEN_TIMEOUT` | Access token timeout duration (e.g. 24h, 15m) | `15m` | v0.7.0 | -| `LEAFWIKI_REFRESH_TOKEN_TIMEOUT` | Refresh token timeout duration (e.g. 168h, 7d) | `7d` | v0.7.0 | -| `LEAFWIKI_DISABLE_AUTH` | ⚠️ Disable authentication & authorization (internal networks only!) | `false` | v0.7.0 | -| `LEAFWIKI_BASE_PATH` | URL prefix when served behind a reverse proxy (e.g. /wiki) | `""` | v0.8.2 | -| `LEAFWIKI_MAX_ASSET_UPLOAD_SIZE` | Maximum size for asset uploads (e.g. `50MiB`, `50MB`, `52428800`) | `50MiB` | v0.8.5 | -| `LEAFWIKI_ENABLE_REVISION` | Enable revision history / page history | `false` | v0.9.0 | -| `LEAFWIKI_ENABLE_LINK_REFACTOR` | Enable link refactoring dialog and rewrite flow | `false` | v0.9.0 | -| `LEAFWIKI_MAX_REVISION_HISTORY` | Maximum revisions kept per page; `0` means unlimited | `100` | v0.9.0 | -| `LEAFWIKI_ENABLE_HTTP_REMOTE_USER` | Enable reverse-proxy authentication via trusted HTTP header | `false` | v0.10.0 | -| `LEAFWIKI_HTTP_REMOTE_USER_HEADER_NAME` | Header name carrying the username from a trusted proxy | `Remote-User` | v0.10.0 | -| `LEAFWIKI_TRUSTED_PROXY_IPS` | Comma-separated trusted proxy IPs/CIDRs allowed to supply that header | `""` | v0.10.0 | -| `LEAFWIKI_HTTP_REMOTE_USER_LOGOUT_URL` | Frontend logout redirect URL when reverse-proxy auth is active | `""` | v0.10.0 | - - -These environment variables override the default values and are especially useful in containerized or production environments. - -> When using the official Docker image, `LEAFWIKI_HOST` defaults to `0.0.0.0` if neither a `--host` flag nor `LEAFWIKI_HOST` is provided, as the container entrypoint sets this automatically. +| Variable | Description | Default | Since | +|-----------------------------------------|------------------------------------------------------|---------------|---------| +| `LEAFWIKI_HOST` | Host/IP address | `127.0.0.1` | – | +| `LEAFWIKI_PORT` | Port | `8080` | – | +| `LEAFWIKI_DATA_DIR` | Data directory path | `./data` | – | +| `LEAFWIKI_ADMIN_PASSWORD` | Initial admin password *(required)* | – | – | +| `LEAFWIKI_JWT_SECRET` | JWT signing secret *(required)* | – | – | +| `LEAFWIKI_PUBLIC_ACCESS` | Allow public read-only access | `false` | – | +| `LEAFWIKI_BASE_PATH` | URL prefix for reverse proxy | `""` | v0.8.2 | +| `LEAFWIKI_ALLOW_INSECURE` | ⚠️ HTTP auth cookies | `false` | v0.7.0 | +| `LEAFWIKI_DISABLE_AUTH` | ⚠️ Disable authentication | `false` | v0.7.0 | +| `LEAFWIKI_ACCESS_TOKEN_TIMEOUT` | Access token duration | `15m` | v0.7.0 | +| `LEAFWIKI_REFRESH_TOKEN_TIMEOUT` | Refresh token duration | `7d` | v0.7.0 | +| `LEAFWIKI_MAX_ASSET_UPLOAD_SIZE` | Max upload size | `50MiB` | v0.8.5 | +| `LEAFWIKI_CUSTOM_STYLESHEET` | Path to `.css` file inside data dir | `""` | v0.8.5 | +| `LEAFWIKI_INJECT_CODE_IN_HEADER` | HTML/JS injected into `` | `""` | v0.6.0 | +| `LEAFWIKI_HIDE_LINK_METADATA_SECTION` | Hide backlinks and link status panel | `false` | – | +| `LEAFWIKI_ENABLE_REVISION` | Revision history | `false` | v0.9.0 | +| `LEAFWIKI_ENABLE_LINK_REFACTOR` | Link rewriting on rename/move | `false` | v0.9.0 | +| `LEAFWIKI_MAX_REVISION_HISTORY` | Max revisions per page; `0` = unlimited | `100` | v0.9.0 | +| `LEAFWIKI_ENABLE_HTTP_REMOTE_USER` | Reverse-proxy auth via header | `false` | v0.10.0 | +| `LEAFWIKI_HTTP_REMOTE_USER_HEADER_NAME` | Username header from proxy | `Remote-User` | v0.10.0 | +| `LEAFWIKI_TRUSTED_PROXY_IPS` | Trusted proxy IPs/CIDRs | `""` | v0.10.0 | +| `LEAFWIKI_HTTP_REMOTE_USER_LOGOUT_URL` | Logout redirect URL | `""` | v0.10.0 | ### Custom Stylesheet -The custom stylesheet feature is available since `v0.8.5`. - -To use it, place a `.css` file inside your configured data directory and pass its path via `--custom-stylesheet` or `LEAFWIKI_CUSTOM_STYLESHEET`. - -Example: +Place a `.css` file inside your data directory and pass its path: ```bash ./leafwiki \ @@ -385,33 +292,13 @@ Example: --admin-password=yourpassword ``` -With the example above: - -- The file must exist at `./data/custom.css` -- Without a base path, it is served as `/custom.css` -- With `--base-path=/wiki`, it is served as `/wiki/custom.css` -- The stylesheet endpoint is publicly accessible +- File must exist at `./data/custom.css` +- Served as `/custom.css` (or `${base-path}/custom.css` with `--base-path`) +- The endpoint is publicly accessible ### Reverse-Proxy Authentication -Reverse-proxy authentication is available since `v0.10.0`. - -Use it when an upstream proxy or auth gateway authenticates the user and forwards the username to LeafWiki in an HTTP header. - -The relevant options are: - -- `--enable-http-remote-user` -- `--http-remote-user-header-name` -- `--trusted-proxy-ips` -- `--http-remote-user-logout-url` - -Important security note: - -- LeafWiki only trusts the configured user header when the request originates from a trusted proxy IP or CIDR listed in `--trusted-proxy-ips` -- Requests from untrusted source IPs do not get authenticated from that header -- If the trusted proxy sends a username that does not exist in LeafWiki, the request is rejected - -Example: +Available since v0.10.0. Use when an upstream proxy authenticates users and forwards the username via HTTP header. ```bash ./leafwiki \ @@ -423,113 +310,64 @@ Example: --http-remote-user-logout-url=https://auth.example.com/logout ``` -This mode is intended for trusted reverse-proxy setups. Do not enable it without restricting `--trusted-proxy-ips`. - -### Security Overview - Since v0.7.0 - -LeafWiki includes several built-in security mechanisms enabled by default: - -- **Secure, HttpOnly cookies** for session handling -- **Session-based authentication** backed by a local database -- **CSRF protection** for all state-changing requests -- **Rate limiting** on authentication-related endpoints -- **Role-based access** (admin, editor, viewer) - -These defaults are intended to be safe for normal deployments. If you weaken them with `--disable-auth` or `--allow-insecure`, do so only in trusted environments. +- Only trusts the header from IPs listed in `--trusted-proxy-ips` +- If the forwarded username doesn't exist in LeafWiki, the request is rejected +- Do not enable without configuring `--trusted-proxy-ips` ---- - -### Security warning: `--disable-auth` - -`--disable-auth` completely disables authentication and authorization. +### Security -Only use it for: -- local development -- trusted internal networks -- isolated environments protected elsewhere +Enabled by default since v0.7.0: -Do not use it on public or internet-facing deployments. +- Secure, HttpOnly cookies for session handling +- CSRF protection on all state-changing requests +- Rate limiting on auth endpoints +- Role-based access: admin, editor, viewer -Safe local example: +**`--disable-auth`** removes all authentication. Only use for local development, trusted internal networks, or isolated environments. ```bash +# Safe local-only example: ./leafwiki --disable-auth --host=127.0.0.1 ``` -For most setups, prefer: -- Authentication enabled (default) -- `--public-access` for read-only public access -- Viewer role for read-only access - ---- +For most setups, prefer `--public-access` for read-only public access and the viewer role for restricted accounts. -## Quick Start (Dev) - -```bash -git clone https://github.com/perber/leafwiki.git -cd leafwiki - -cd ui/leafwiki-ui -npm install -npm run dev - -cd ../../cmd/leafwiki -go run main.go --jwt-secret=yoursecret --allow-insecure=true --admin-password=yourpassword -``` - -Vite starts on `http://localhost:5173`. -The backend binds to `127.0.0.1` by default. Use `--host=0.0.0.0` only if you intentionally need network access. - ---- - -### Keyboard Shortcuts - -| Action | Shortcut | -|----------------------------|--------------------------------------------| -| Switch to Edit Mode | `Ctrl + E` (or `Cmd + E`) | -| Save Page | `Ctrl + S` (or `Cmd + S`) | -| Switch to Search Pane | `Ctrl + Shift + F` (or `Cmd + Shift + F`) | -| Switch to Navigation Pane | `Ctrl + Shift + E` (or `Cmd + Shift + E`) | -| Go to Page | `Ctrl + Alt + P` (or `Cmd + Option + P`) | -| Bold Text | `Ctrl + B` (or `Cmd + B`) | -| Italic Text | `Ctrl + I` (or `Cmd + I`) | -| Headline 1 | `Ctrl + Alt + 1` (or `Cmd + Alt + 1`) | -| Headline 2 | `Ctrl + Alt + 2` (or `Cmd + Alt + 2`) | -| Headline 3 | `Ctrl + Alt + 3` (or `Cmd + Alt + 3`) | - -`Ctrl+V` / `Cmd+V` for pasting images or files is also supported in the editor. -`Esc` can be used to exit modals, dialogs or the edit mode. +### Operations notes -More shortcuts may be added in future releases. +- Default bind: `127.0.0.1` (binary) / `0.0.0.0` (Docker image) +- Default data dir: `./data` (binary) / `/app/data` (container) +- Defaults are intentionally conservative β€” a fresh install does not become network-exposed by accident --- -### Available Builds +## Keyboard Shortcuts -LeafWiki is available as a native binary for the following platforms: +| Action | Shortcut | +|-----------------------|----------------------------------------| +| Edit mode | `Ctrl + E` / `Cmd + E` | +| Save | `Ctrl + S` / `Cmd + S` | +| Search | `Ctrl + Shift + F` / `Cmd + Shift + F` | +| Navigation pane | `Ctrl + Shift + E` / `Cmd + Shift + E` | +| Go to page | `Ctrl + Alt + P` / `Cmd + Option + P` | +| Bold | `Ctrl + B` / `Cmd + B` | +| Italic | `Ctrl + I` / `Cmd + I` | +| Headline 1–3 | `Ctrl + Alt + 1–3` / `Cmd + Alt + 1–3` | -- **Linux (x86_64 and ARM64)** -- **macOS (x86_64 and ARM64)** -- **Windows (x86_64)** -- **Raspberry Pi (tested with 64-bit OS)** +`Ctrl+V` / `Cmd+V` for pasting images and files works in the editor. +`Esc` closes modals, dialogs, and edit mode. --- -## Support LeafWiki - -If LeafWiki is useful to you or your team, consider sponsoring the project on GitHub. +## Support this project -Sponsorship helps fund maintenance, bug fixes, documentation, and improvements like tags and properties. +LeafWiki is maintained in spare time. If it's useful to you: -πŸ‘‰ https://github.com/sponsors/perber +- ⭐ **[Star the repo](https://github.com/perber/leafwiki)** β€” helps others find it +- πŸ’› **[Sponsor on GitHub](https://github.com/sponsors/perber)** β€” supports ongoing maintenance, bug fixes, and new features --- ## Contributing -Contributions, discussions, and feedback are very welcome. -If you have ideas, questions, or run into issues, feel free to open an issue or start a discussion. - -## Stay in the loop - -Follow the repository to get updates about new releases and ongoing development. +Contributions, discussions, and feedback are welcome. +Open an issue or start a discussion on GitHub. Follow the repository to get notified about new releases. From fa8bb12de1561d475aefd29888119e8635076fbc Mon Sep 17 00:00:00 2001 From: perber Date: Tue, 26 May 2026 12:10:07 +0200 Subject: [PATCH 2/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index e7059d7a..cb3bf4bf 100644 --- a/readme.md +++ b/readme.md @@ -130,7 +130,7 @@ services: - LEAFWIKI_ADMIN_PASSWORD=yourPassword - LEAFWIKI_ALLOW_INSECURE=true # For HTTPS deployments, omit this. volumes: - - ~/leafwiki-data:/app/data + - ${HOME}/leafwiki-data:/app/data restart: unless-stopped ``` From 8e1cba5b36956828d3c6eed5c696c7050e6e158f Mon Sep 17 00:00:00 2001 From: perber Date: Tue, 26 May 2026 12:10:30 +0200 Subject: [PATCH 3/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cb3bf4bf..0d460bf6 100644 --- a/readme.md +++ b/readme.md @@ -99,7 +99,7 @@ docker run -p 8080:8080 \ --allow-insecure=true ``` -`--allow-insecure=true` is required for plain HTTP. Omit it when serving over HTTPS. +`--allow-insecure=true` is required for plain HTTP. Omit it when serving over HTTPS (make sure your reverse proxy forwards `X-Forwarded-Proto: https`). **Non-root:** From 818e26c3ea14b7e29b1443785449d3e3517d4471 Mon Sep 17 00:00:00 2001 From: perber Date: Tue, 26 May 2026 12:10:58 +0200 Subject: [PATCH 4/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 0d460bf6..3983c510 100644 --- a/readme.md +++ b/readme.md @@ -128,7 +128,7 @@ services: environment: - LEAFWIKI_JWT_SECRET=yourSecret - LEAFWIKI_ADMIN_PASSWORD=yourPassword - - LEAFWIKI_ALLOW_INSECURE=true # For HTTPS deployments, omit this. + - LEAFWIKI_ALLOW_INSECURE=true # Required for plain HTTP. Omit for HTTPS (ensure `X-Forwarded-Proto: https` is forwarded). volumes: - ${HOME}/leafwiki-data:/app/data restart: unless-stopped