SSD Nodes Learn Hosting plans →
Guides Matt ConnorBy Matt Connor

Self-hosted wiki: BookStack, Wiki.js, Outline

Three self-hosted wiki apps compared on setup weight, editing model, login options and search, with a clear pick for solo admins and for teams.

Which self-hosted wiki should you run

A self-hosted wiki puts your team's documents in one searchable place on a server you control. BookStack, Wiki.js and Outline all do that job. They differ most in how much you have to assemble before the first page loads, and in who is allowed to log in.

BookStack is the lightest to stand up and the most opinionated about structure. Wiki.js gives you the widest choice of editors over one page tree. Outline has the best writing experience of the three, and its documented production setup requires an outside identity provider to create the initial workspace.

Everything below is read from the projects' own documentation and their published configuration files. This is a capability comparison, not a benchmark. Version numbers and requirements are stamped with a date because all three move.

Structure is the real choice

BookStack fixes the shape of your content. A page lives inside a book, a book may hold chapters, and shelves group books. You cannot invent a fifth level. That limit is the product: a new writer knows where a page goes because there is only one place it can go. The cost is that content which does not fit the shape gets forced into it.

Wiki.js uses a path tree, like folders on a disk. A page at ops/backup/restic sits wherever you put it, and you pick the depth. Nothing stops two people filing the same subject under two different branches, so a Wiki.js instance needs one person who owns the tree.

Outline uses collections with documents nested inside documents. Moving a document is a drag with the mouse. It is the most flexible of the three, so it is also the easiest to let drift.

BookStack: the smallest install

BookStack is a PHP application backed by MySQL. As of October 2026 the documented requirements are PHP 8.2 or newer and either MySQL 8.0 or MariaDB 10.6 or newer, plus Composer 2.2 or newer if you install from source. The current release line is 26.09, released on September 24, 2026, and the newest stable release is 26.09.2, a security release from October 20, 2026. From 26.09 on, an APP_KEY value must be set, which the container steps below already cover. BookStack also published a critical PHP security notice on October 21, 2026: update the underlying PHP packages or pull and recreate the container with a patched image, because the BookStack version alone does not confirm that PHP is patched.

The project officially supports installation scripts and guidance for its listed Ubuntu LTS releases, currently 22.04, 24.04 and 26.04, and sometimes publishes unsupported guides and scripts for other environments. The 24.04 script installs Apache, MySQL 8.0 and PHP 8.3 for you. On 26.04, use installation-ubuntu-26.04.sh in the commands below instead; it installs MySQL 8.4 and PHP 8.5.

wget https://codeberg.org/bookstack/devops/raw/branch/main/scripts/installation-ubuntu-24.04.sh
chmod a+x installation-ubuntu-24.04.sh
sudo ./installation-ubuntu-24.04.sh

Read the warning on that script before you run it. The documentation states it is "ONLY FOR A FRESH OS, it will install Apache, MySQL 8.0 & PHP 8.3 and could OVERWRITE any existing web setup on the machine". The 24.04 script checks for existing Apache configuration and MySQL data and aborts before installation if it finds either. Use containers there instead, or install BookStack by hand on top of an existing LAMP stack on Ubuntu 24.04.

The container route uses the LinuxServer.io image, one of the two community container setups the BookStack documentation lists. BookStack needs a session encryption key and will not serve pages without one, so generate it first.

docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey

Copy the printed value into APP_KEY, then write the service. This service also needs an existing MySQL or MariaDB database; set the DB_* values to match it, because the snippet does not create a database service.

services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - APP_URL=https://wiki.example.com
      - APP_KEY=paste_the_generated_key_here
      - DB_HOST=bookstack_db
      - DB_PORT=3306
      - DB_USERNAME=bookstack
      - DB_PASSWORD=change_me
      - DB_DATABASE=bookstackapp
    volumes:
      - ./config:/config
    ports:
      - 6875:80
    restart: unless-stopped

APP_URL has to match the address readers actually type, including the scheme and any port. Set it to http://localhost and then serve the site over HTTPS, and generated links and redirects point at the wrong host, which readers see as a login page that loops back to itself. If compose files are new to you, start with Docker Compose basics on a VPS before this one.

Bring it up and check that the application answers, not only that the container is running:

docker compose up -d
docker compose ps
curl -sI http://127.0.0.1:6875/login

A 200 OK means the PHP application booted and reached the database. A 500 needs the application error log to diagnose. By default BookStack writes its errors to a log file rather than to the container output, so open ./config/log/bookstack/laravel.log on the host to see the cause. docker compose logs bookstack shows the container's own startup messages, which may not include the application error.

Wiki.js: one tree, several editors

Wiki.js is a Node.js application. The documented Docker setup pairs it with PostgreSQL, though the software also accepts MySQL, MariaDB, MSSQL and SQLite. This is the compose file from the project's own Docker page:

services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: wiki
      POSTGRES_PASSWORD: wikijsrocks
      POSTGRES_USER: wikijs
    logging:
      driver: none
    restart: unless-stopped
    volumes:
      - db-data:/var/lib/postgresql/data
  wiki:
    image: ghcr.io/requarks/wiki:2
    depends_on:
      - db
    init: true
    environment:
      DB_TYPE: postgres
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: wikijs
      DB_PASS: wikijsrocks
      DB_NAME: wiki
    restart: unless-stopped
    ports:
      - "80:3000"
volumes:
  db-data:

Change POSTGRES_PASSWORD and DB_PASS together before you run it, because they are one credential and the sample value is public. The tag is pinned to ghcr.io/requarks/wiki:2 on purpose. The documentation recommends against latest, since a major version jump changes the database schema under a running instance.

Version 2 is the line to run. As of October 27, 2026 the newest version 2 release is 2.5.317, a bug-fix build from October 23, 2026 that rebuilds the image with the latest Node security updates. Version 2 releases are now published from a separate requarks/wiki-v2 repository, and the :2 image tag still tracks them. Version 3 is in public beta. Its installation documentation says its images are tagged 3.0.0-beta and that the plain 3 and 3.0 tags will not work until the beta phase ends. Treat it as a preview, not a production target. The previous release, 2.5.316 from October 2, 2026, added an export utility for moving content to version 3 later.

On first load Wiki.js walks you through an in-browser setup that creates the administrator account. Until you finish it, anyone who reaches the port gets that wizard, so put the service behind your reverse proxy and TLS (transport layer security) before you open the firewall. A wiki on its own hostname sits naturally behind Traefik in front of several Docker apps when the server hosts more than this one service.

The editor choice is the reason people pick Wiki.js. One instance can hold Markdown pages, visual editor pages, raw HTML pages and AsciiDoc pages side by side. That helps when you are importing old content in a format you would rather not convert. It is also a way to end up with four house styles in one wiki, so decide the default editor on day one and write that decision down.

Outline: the best editor, the heaviest prerequisites

Outline is what people usually mean when they say they want something that feels like a commercial notes tool. It is a Node.js application, and the current release as of October 27, 2026 is 1.12.0, from October 23, 2026. That release moves its Docker image to a Node version that fixes several recently disclosed Node vulnerabilities, so bring older installs up to date. Its sample environment file lists what it needs: PostgreSQL through DATABASE_URL, Redis through REDIS_URL, two random secrets, and a publicly reachable URL.

openssl rand -hex 32
openssl rand -hex 32

Run that twice and keep both values. The first becomes SECRET_KEY, the second UTILS_SECRET. The core of the environment file then looks like this:

NODE_ENV=production
URL=https://docs.example.com
PORT=3000
SECRET_KEY=<first openssl value>
UTILS_SECRET=<second openssl value>
DATABASE_URL=postgres://outline:change_me@postgres:5432/outline
PGSSLMODE=disable
REDIS_URL=redis://redis:6379
FILE_STORAGE=local
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data

PGSSLMODE=disable is only correct when the database sits on the same machine or the same Docker network. Leave it out for a database reached across a network, or the connection travels in the clear. Attachments no longer force you into object storage: FILE_STORAGE=local writes uploads to the directory above, which must be a volume the container can write to and something your backups include. Set FILE_STORAGE=s3 with the AWS_* values instead if you want those files in an S3 compatible bucket.

Now the part that surprises people. Outline has no built-in username and password login. Its own sample configuration says third party sign-in credentials are required: "at least ONE OF these is required for a working installation or you'll have no sign-in options". The documented providers include Google, Slack, Microsoft Entra, Discord, and any generic OpenID Connect (OIDC) server through OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_AUTH_URI, OIDC_TOKEN_URI and OIDC_USERINFO_URI. Existing workspaces can also enable passkeys and email links or codes; email login needs SMTP and does not bypass SSO for accounts linked to an SSO provider.

So the honest cost of Outline's documented production setup is Outline plus PostgreSQL plus Redis plus an identity provider. If your team already signs in with Google Workspace or Microsoft Entra, Outline becomes very attractive. If it does not, you are also self-hosting something like Keycloak or Authentik, which is a second service to patch and back up. Budget memory accordingly: Outline's own guidance is roughly 512 MB per web process, set by WEB_CONCURRENCY, on top of the database and Redis.

How each one handles who may read what

BookStack has local email and password accounts out of the box, and supports LDAP, SAML2 and OIDC as alternatives. Permissions are set per role and can be overridden on a single shelf, book, chapter or page. Book and chapter permissions inherit down to child content unless overridden; shelf permissions must be copied to books explicitly.

Wiki.js also ships local accounts and adds a long list of strategies you enable in the admin area. Its page rules grant or deny by path pattern. That is powerful and easy to get wrong, because a rule written for ops/* silently covers every page you file under that path later.

Outline uses your identity provider for SSO membership, and inside Outline you control access by collection, document and group. Users removed from the identity provider are logged out when they next load Outline; suspend them in Outline to end existing sessions immediately.

How search works in each

Search is where a wiki either earns its place or turns into a folder of forgotten files.

BookStack searches the database and gives readers a query language they can learn in a minute. Quoting a phrase, as in "london meeting", requires that exact string. Square brackets search tags: [location=london] matches by tag name, value or both, with comparisons including !=, >= and like. Curly braces filter on metadata, as in {created_after:2016-12-30}. Any exact, tag or filter term can be negated by prefixing it with -. BookStack caps how many terms of each type one query may hold, so a very long query is trimmed rather than run.

Wiki.js treats search as a pluggable module. The documented engines are a basic database engine, a PostgreSQL engine, Elasticsearch, Algolia, AWS CloudSearch and Azure Search. The basic engine matches titles, descriptions and paths rather than page bodies. If you run PostgreSQL, switch to the PostgreSQL engine in the admin area, because it uses the database's own full text index instead of simple matching. Keep Elasticsearch for a wiki large enough that you accept running and patching a second search service.

Outline searches PostgreSQL full text indexes. Its built-in keyword search needs no separate search service. For a team wiki in the low thousands of documents that is the least work of the three.

Which one fits you

Pick BookStack if you want the wiki running this afternoon and you would rather argue about content than about structure. It has the fewest moving parts: one PHP application and one MySQL database. It suits internal runbooks and customer documentation, and it suits teams where most writers are not engineers. It is also the easiest of the three to back up, because the state is one database dump plus the uploaded files and the .env configuration, including APP_KEY.

Pick Wiki.js if you need a specific editor or a specific authentication strategy the others do not offer, or if you are importing a large body of existing Markdown or AsciiDoc and want the path structure preserved. Accept that you are running a heavier stack, and pin the major version tag.

Pick Outline if writing quality matters most, the wiki is for a team rather than for the public, and you already have an identity provider. It rewards that setup with the editor people actually enjoy using. Do not pick it as your first self-hosted application.

If none of the three fits, the mismatch is usually the content type. Scanned invoices and contracts belong in a document management system such as Paperless-ngx rather than in a wiki, and forcing them into one is why so many wikis end up abandoned. The other common mismatch is wanting a workspace rather than a wiki, with documents, tables and a whiteboard on one canvas, which is where a self-hosted AFFiNE workspace fits better than any of the three above. For a wider view of what else earns a place on your own server, see the self-hosting shortlist for 2026.

Sizing and backups

All three fit on a small VPS, and the realistic floor differs because of what sits behind each one. BookStack is one application process and MySQL. Wiki.js is a Node process and PostgreSQL. Outline is a Node process, PostgreSQL and Redis, usually with an identity provider alongside, which is why it is the one to give extra memory.

Back up the database and the uploads together, and restore both into a throwaway instance once before you rely on that backup. A wiki backup nobody has restored is a guess. For BookStack that means a mysqldump plus the /config volume. For Wiki.js and Outline it means pg_dump plus the data volume, and for Outline also whatever sits in FILE_STORAGE_LOCAL_ROOT_DIR.

FAQ

Which self-hosted wiki is easiest to install?

BookStack. It is a single PHP application with a MySQL database, and the project ships an installation script for Ubuntu 24.04 that sets up Apache, MySQL 8.0 and PHP 8.3 in one run. The container image needs an APP_KEY, an APP_URL and credentials for an existing database. Wiki.js adds a Node runtime and a PostgreSQL server, and Outline adds Redis and an outside identity provider for its documented initial setup.

Can I use Outline without Google or another SSO provider?

Its documented production setup requires a provider to create the initial workspace. Outline has no local username and password login. Its sample configuration states that at least one third party sign-in provider is required, or you will have no sign-in options at all. You can use Google, Slack, Microsoft Entra, Discord, or any generic OpenID Connect server such as a self-hosted Keycloak or Authentik. Existing workspaces can enable passkeys or email links and codes, with SMTP required for email login; accounts linked to SSO still use that provider.

Should I install Wiki.js 3 or Wiki.js 2?

Version 2. As of October 27, 2026 the newest version 2 release is 2.5.317, from October 23, 2026, and version 3 is still a beta whose images carry a 3.0.0-beta tag. Pin your image to ghcr.io/requarks/wiki:2 rather than latest, because a major version change alters the database schema under a running instance.

They are strong in different ways. BookStack gives readers a query language with exact phrases, tag filters such as [location=london] and metadata filters such as {created_after:2016-12-30}, and any of those terms can be negated with a leading -. Outline's built-in keyword search needs no separate search service. Wiki.js is the most tunable, since you choose the engine, and the PostgreSQL engine searches page bodies that the basic engine does not.

Can I move my content from one to another later?

Partly, and you should expect manual work. All three export Markdown, but BookStack's built-in import accepts its Portable ZIP format, so Markdown alone is not a direct import route into BookStack. Structure does not survive cleanly: BookStack books and chapters have no equivalent in Outline's nested documents, and Wiki.js paths do not map onto BookStack's fixed hierarchy. Attachments, permissions and page history are the parts most likely to be lost, so export a sample and check those before you commit to a migration.

Was this article useful?

#bookstack#wikijs#outline#wiki#self-hosting#knowledge-base