diff --git a/readme.md b/readme.md index fdc39001..3983c510 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. +[](https://github.com/perber/leafwiki/stargazers) [](https://github.com/perber/leafwiki/releases) [](https://github.com/perber/leafwiki/actions/workflows/backend.yml) [](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.  -## 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
+## Good fit / not a fit
-Revision history and link refactoring are currently available behind feature flags: `--enable-revision` and `--enable-link-refactor`.
+**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
-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.
-
-## What LeafWiki is not
-
-- 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 (make sure your reverse proxy forwards `X-Forwarded-Proto: 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.
-### Quick start with the installer
+### Docker Compose
-The easiest way to install LeafWiki is using the provided installation script:
+```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 # Required for plain HTTP. Omit for HTTPS (ensure `X-Forwarded-Proto: https` is forwarded).
+ volumes:
+ - ${HOME}/leafwiki-data:/app/data
+ restart: unless-stopped
+```
+
+### 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.
-#### Installer script options
+> Only works if you installed with the script above. Not compatible with Docker or binary installs.
-**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.
-LeafWiki can be configured using command-line flags or environment variables.
-These options control how the server runs after installation.
+See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
-If you are just getting started, the most important options are usually:
+---
+
+## Configuration
+
+### Required
+
+| 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