Documentation is the backbone of any team or organization. Whether it is runbooks, API documentation, onboarding guides, or internal knowledge bases, having a centralized, searchable wiki is essential. Confluence has long dominated this space, but its pricing, complexity, and Atlassian's push toward cloud-only hosting have driven teams to explore self-hosted alternatives.

Three open-source wiki platforms stand out: Bookstack (structured, book-based organization), Wiki.js (modern, Git-backed), and Outline (Notion-like collaborative editor). Each takes a fundamentally different approach to organizing knowledge.

Feature Comparison

Feature Bookstack Wiki.js Outline
Language PHP (Laravel) Node.js Node.js (React)
Organization model Shelves > Books > Chapters > Pages Flat with folders and tags Collections > Documents (nested)
Editor WYSIWYG + Markdown Multiple (Markdown, Visual, Code) Block editor (Notion-like)
Real-time collaboration No No Yes
Full-text search Yes (database) Yes (Elasticsearch, PostgreSQL FTS) Yes (PostgreSQL FTS)
Git integration No Yes (sync to/from Git repos) No
API REST API GraphQL + REST REST API
SSO / OAuth LDAP, SAML, OIDC LDAP, OAuth, SAML, OIDC OIDC required (Slack, Google, Azure AD)
Diagrams Draw.io integration Draw.io, PlantUML, Mermaid Mermaid
RAM usage ~150 MB ~300 MB (+Elasticsearch if used) ~250 MB
License MIT AGPL-3.0 BSL 1.1 (source available)

Docker Deployment: Bookstack

# docker-compose.yml for Bookstack
version: "3.8"
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    restart: unless-stopped
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - APP_URL=https://wiki.example.com
      - DB_HOST=bookstack-db
      - DB_PORT=3306
      - DB_USER=bookstack
      - DB_PASS=${DB_PASSWORD}
      - DB_DATABASE=bookstackapp
      # SMTP configuration
      - MAIL_DRIVER=smtp
      - MAIL_HOST=smtp.example.com
      - MAIL_PORT=587
      - [email protected]
      - MAIL_PASSWORD=${SMTP_PASSWORD}
      - MAIL_ENCRYPTION=tls
      - [email protected]
    volumes:
      - bookstack_config:/config
    ports:
      - "6875:80"
    depends_on:
      - bookstack-db

  bookstack-db:
    image: mariadb:10.11
    container_name: bookstack-db
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=${DB_PASSWORD}
    volumes:
      - bookstack_db:/var/lib/mysql

volumes:
  bookstack_config:
  bookstack_db:

Docker Deployment: Wiki.js

# docker-compose.yml for Wiki.js
version: "3.8"
services:
  wikijs:
    image: ghcr.io/requarks/wiki:2
    container_name: wikijs
    restart: unless-stopped
    environment:
      - DB_TYPE=postgres
      - DB_HOST=wikijs-db
      - DB_PORT=5432
      - DB_USER=wikijs
      - DB_PASS=${DB_PASSWORD}
      - DB_NAME=wiki
    volumes:
      - wikijs_data:/wiki/data
    ports:
      - "3000:3000"
    depends_on:
      - wikijs-db

  wikijs-db:
    image: postgres:16-alpine
    container_name: wikijs-db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=wiki
      - POSTGRES_USER=wikijs
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - wikijs_db:/var/lib/postgresql/data

volumes:
  wikijs_data:
  wikijs_db:

Docker Deployment: Outline

# docker-compose.yml for Outline
version: "3.8"
services:
  outline:
    image: outlinewiki/outline:latest
    container_name: outline
    restart: unless-stopped
    env_file: ./outline.env
    ports:
      - "3000:3000"
    depends_on:
      - outline-db
      - outline-redis

  outline-db:
    image: postgres:16-alpine
    container_name: outline-db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=outline
      - POSTGRES_USER=outline
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - outline_db:/var/lib/postgresql/data

  outline-redis:
    image: redis:7-alpine
    container_name: outline-redis
    restart: unless-stopped
    volumes:
      - outline_redis:/data

volumes:
  outline_db:
  outline_redis:
# outline.env - key configuration
NODE_ENV=production
SECRET_KEY=generated-secret-key-min-32-chars
UTILS_SECRET=generated-utils-secret-min-32-chars
DATABASE_URL=postgres://outline:password@outline-db:5432/outline
REDIS_URL=redis://outline-redis:6379
URL=https://docs.example.com
PORT=3000
FILE_STORAGE=local
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data

# Authentication (OIDC required - no local auth)
# Example with Keycloak, Authentik, or similar
OIDC_CLIENT_ID=outline
OIDC_CLIENT_SECRET=your-client-secret
OIDC_AUTH_URI=https://auth.example.com/authorize
OIDC_TOKEN_URI=https://auth.example.com/token
OIDC_USERINFO_URI=https://auth.example.com/userinfo
OIDC_DISPLAY_NAME=SSO Login
Warning: Outline requires OIDC authentication; it has no built-in username/password login. You will need an identity provider like Keycloak, Authentik, Google Workspace, Slack, or Azure AD. This adds deployment complexity but provides better security for team environments.

Search Capabilities

Bookstack

Bookstack uses database-level full-text search (MySQL/MariaDB FULLTEXT indexes). It works well for small to medium knowledge bases but does not support fuzzy matching or relevance ranking as sophisticated as dedicated search engines.

Wiki.js

Wiki.js offers the most flexible search with multiple backend options:

# Wiki.js search engine options (configured in admin panel):
# 1. Database (PostgreSQL FTS) - good default, no extra services
# 2. Elasticsearch - best for large wikis, fuzzy search, relevance
# 3. Algolia - cloud-based, fast but not self-hosted
# 4. Azure Search
# 5. Manticore Search - open-source Elasticsearch alternative

# Adding Elasticsearch to Docker Compose:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    container_name: wikijs-search
    restart: unless-stopped
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - wikijs_search:/usr/share/elasticsearch/data

Outline

Outline uses PostgreSQL full-text search with good performance and relevance ranking. Search results include snippets and are ranked by relevance. It supports searching within document content, titles, and comments.

Access Control

Feature Bookstack Wiki.js Outline
Role-based access Yes (granular, per-shelf/book/chapter/page) Yes (per-group, per-path) Yes (per-collection)
Public pages Yes Yes Yes (share links)
Guest access Yes (configurable) Yes No (auth required)
LDAP groups Yes (group sync) Yes No (OIDC groups)
Page-level permissions Yes Yes (regex path rules) Collection-level only

API Integration

All three wikis provide APIs for automation:

# Bookstack REST API
curl -X GET "https://wiki.example.com/api/pages" \
  -H "Authorization: Token ${BOOKSTACK_TOKEN_ID}:${BOOKSTACK_TOKEN_SECRET}"

# Create a page
curl -X POST "https://wiki.example.com/api/pages" \
  -H "Authorization: Token ${TOKEN_ID}:${TOKEN_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "book_id": 1,
    "name": "Deployment Guide",
    "markdown": "# Deployment Guide\n\nStep 1: ..."
  }'

# Wiki.js GraphQL API
curl -X POST "https://docs.example.com/graphql" \
  -H "Authorization: Bearer ${WIKIJS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ pages { list { id title path } } }"
  }'

# Outline REST API
curl -X POST "https://docs.example.com/api/documents.search" \
  -H "Authorization: Bearer ${OUTLINE_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"query": "deployment"}'

Backup and Migration

#!/bin/bash
# wiki-backup.sh - Backup any wiki platform
set -euo pipefail

BACKUP_DIR="/backups/wiki/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

# Bookstack backup
docker exec bookstack-db mysqldump -u bookstack -p"${DB_PASSWORD}" bookstackapp | \
  gzip > "$BACKUP_DIR/bookstack_db.sql.gz"
docker run --rm -v bookstack_config:/source:ro -v "$BACKUP_DIR":/backup \
  alpine tar czf /backup/bookstack_config.tar.gz -C /source .

# Wiki.js backup
docker exec wikijs-db pg_dump -U wikijs wiki | \
  gzip > "$BACKUP_DIR/wikijs_db.sql.gz"

# Outline backup
docker exec outline-db pg_dump -U outline outline | \
  gzip > "$BACKUP_DIR/outline_db.sql.gz"

echo "Wiki backup complete: $BACKUP_DIR"
Tip: Wiki.js has a unique advantage for backup and version control: it can sync bidirectionally with a Git repository. This means your entire wiki content is stored in a Git repo, providing version history, branching, and the ability to edit content directly in your code editor. Configure this under Administration > Storage > Git.

Which One Should You Choose?

  • Choose Bookstack if you want structured documentation organized into books and chapters. Ideal for operations runbooks, technical documentation, and knowledge bases where a hierarchical organization makes sense. Lowest resource usage and simplest to maintain.
  • Choose Wiki.js if you want the most flexible and feature-rich wiki with Git integration, multiple editor modes, and powerful search. Ideal for developer teams who want documentation as code.
  • Choose Outline if you want a modern, Notion-like editing experience with real-time collaboration. Ideal for teams that find traditional wikis too rigid and want a more fluid, document-centric approach. Requires OIDC setup.

A wiki is only as good as the documentation people actually write in it. The best wiki platform is the one your team will actually use. If your team prefers Markdown, choose Wiki.js. If they want a Notion-like experience, choose Outline. If they want structure, choose Bookstack.

For managing wiki containers alongside your other self-hosted services, platforms like usulnet give you visibility into container health, resource usage, and backup status, ensuring your knowledge base stays available and protected.