Skip to main content

Eigene BookStack-Instanz installieren

ℹ️ Diese Anleitung startet ab dem Punkt, an dem du bereits einen Linux-Server hast und Docker installiert ist. Die „Schritte davor“ folgen später – es ist wirklich nicht schwer (besonders mit KI-Hilfe).


Überblick: Was wird hier eingerichtet?

Du bekommst am Ende:

  • BookStack (Wiki/Docs-System)
  • MariaDB als Datenbank
  • Caddy als Reverse Proxy mit automatischem HTTPS (Let’s Encrypt) 🌐

Hintergrund: Was ist Caddy? 🌐

Caddy ist ein moderner Webserver (ähnlich Nginx/Apache), geschrieben in Go, der „Security-by-default“ lebt und dir vor allem HTTPS extrem bequem macht.

Kernidee: „Webserver, der einfach funktioniert“ ✅

Wichtige Merkmale ✨

  1. Automatisches HTTPS (TLS)
    • Zertifikate werden automatisch bezogen und erneuert (typisch via Let’s Encrypt).
  2. Einfache Konfiguration
    • Über ein gut lesbares Caddyfile.
  3. Reverse Proxy & Load Balancing
    • Ideal, um Anfragen an Services (z. B. Docker-Container) weiterzuleiten.
  4. Gute Defaults
    • Viele sinnvolle Security-Standards sind direkt aktiv.
  5. Modular erweiterbar
    • Bei speziellen Anforderungen lässt sich Caddy ausbauen.

Typische Einsatzfälle 🧩

  • Websites hosten (statisch/dynamisch)
  • Reverse Proxy vor einer App (z. B. /api → Backend)
  • TLS-Termination
  • Lokale Dev-Setups mit HTTPS

Schritt 1: Verzeichnis & Dateien vorbereiten 🧱

Erstelle das Verzeichnis:

  • /opt/bookstack

Lege darin zwei Dateien an:

  • docker-compose.yml
  • Caddyfile

✍️ Wichtig: Du musst gleich ein paar Werte anpassen – du siehst im YAML sehr deutlich, wo.


Schritt 2: Docker Compose konfigurieren (docker-compose.yml) 🐳

Füge folgenden Inhalt ein (und passe ihn an, wo nötig):

services:
  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: bookstack-mariadb
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - MYSQL_ROOT_PASSWORD=PW_OF_MYSQL_ROOT
      - MYSQL_DATABASE=bookstack
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=PW_OF_MYSQL_DB
    volumes:
      - ./mariadb:/config
    restart: unless-stopped

  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    depends_on:
      - mariadb
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin

      - APP_URL=https://wiki.fabula.vision
      # Wo wird BookStack aufrufbar sein? (Deine URL)
      - APP_KEY=base64:...
      # Zum Generieren das ausführen: docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey
      - APP_THEME=custom
      #'custom' ermöglich es Hacks zu nutzen; mehr dazu hier: https://www.bookstackapp.com/hacks/applying/

      - DB_HOST=mariadb
      - DB_PORT=3306
      - DB_DATABASE=bookstack
      - DB_USERNAME=bookstack
      - DB_PASSWORD=PW_OF_MYSQL_DB
      # (Wie oben!)

      - APP_DEFAULT_DARK_MODE=true
      # (Geschmackssache)

    volumes:
      - ./bookstack:/config
    restart: unless-stopped

  caddy:
    image: caddy:latest
    container_name: caddy
    depends_on:
      - bookstack
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy/data:/data
      - ./caddy/config:/config
    restart: unless-stopped

Schritt 3: Caddy konfigurieren (Caddyfile) 🛡️

Füge Folgendes ein und ersetze die Domain:

wiki.fabula.vision {
	# Deine URL natürlich...
	encode zstd gzip

	# Reverse Proxy zu BookStack (Container heißt "bookstack", interner Port 80)
	reverse_proxy bookstack:80

	# sinnvolle Header (optional)
	header {
		# HSTS (nur setzen, wenn du sicher bist, dass HTTPS dauerhaft aktiv sein soll)
		Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		Referrer-Policy "strict-origin-when-cross-origin"
	}
}

Schritt 4: Container starten ▶️

  1. Ins Verzeichnis wechseln:

    • cd /opt/bookstack/
  2. Stack starten:

    • docker compose up -d

    Aktualisieren geht später so:

    • docker compose pull
    • docker compose up -d
  3. Fertig ✅
    Jetzt schnell die URL aufrufen und die Standard-Zugangsdaten ändern!

    • Standard-Login: admin@admin.com
    • Standard-Passwort: password

Schritt 5: Cron-Job für BookStack ⏱️

Einen Cron-Job anlegen:

  1. Crontab öffnen:
    • crontab -e
  2. Folgende Zeile eintragen (Cron jede Minute):
    • * * * * * docker exec -i bookstack php /app/www/artisan schedule:run >/dev/null 2>&1

Beschränkungen & Module/Hacks 🧩

Es gibt drei Einschränkungen, die bisher aufgefallen sind:

  1. E-Mail-Versand

  2. Erweiterung über „Hacks“

    Wichtiger Hinweis zum Export 📄

    • Mermaid (und auch Formeln) funktionieren bei mir nicht sauber im Export (z. B. PDF): statt gerendertem Inhalt erscheinen Code-Blöcke.

    Wie installiert man Hacks als Module?

    • Den ersten Schritt haben wir bereits gemacht: In der YML steht
      APP_THEME=custom
      Dadurch werden Module aus folgendem Pfad geladen:
      • /opt/bookstack/bookstack/www/themes/custom/modules
    • Dann per SSH:
      1. In den Container wechseln:
        • docker exec -it bookstack /bin/bash
      2. Ins Web-Verzeichnis:
        • cd /app/www/
      3. Dort das Kommando ausführen, das im jeweiligen Hack steht (Beispiel Mermaid):
  3. Shift+Enter – Zeilenumbruch (CommonMark)

    • Durch die Entscheidung für den CommonMark-Standard wird ein einfacher Zeilenumbruch standardmäßig nicht gerendert.
    • Stattdessen braucht man „zwei Spaces am Zeilenende + Enter“ – das hat mich wahnsinnig gemacht, weil viele Markdown-Editoren Shift+Enter gewohnt sind.
    • Mein Fix besteht aus zwei Teilen:
    1. In den BookStack-Einstellungen unter
      https://example.com/settings/customization
      bei „Custom HTML Head Content“ folgenden Code eintragen:

       <script>
         window.addEventListener('editor-markdown::setup', event => {
           event.detail.markdownIt.set({breaks: true});
         });
       </script>
      
    2. Eine functions.php anlegen unter:

      • /opt/bookstack/bookstack/www/themes/custom/

      Mit folgendem Inhalt:

      <?php
      
      use BookStack\Theming\ThemeEvents;
      use BookStack\Facades\Theme;
      
      Theme::listen(ThemeEvents::COMMONMARK_ENVIRONMENT_CONFIGURE, function ($environment) {
        $environment->mergeConfig([
          'renderer' => [
            'soft_break' => "<br>",
          ]
        ]);
      
        return $environment;
      });
      

Weitere QoL-Fixes (unter „Customization“) 🛠️

Einstellen hier:

Einfach jeweils unter „Custom HTML Head Content“ eintragen:

  1. Blockquotes: kein dicker Rand unten / saubere Abstände

    • Ursache: CSS (u. a. <p> mit margin-bottom)
    • Fix (gleicher Abstand oben/unten + keine Scrollbalken):
     <style>
       /* 1) Letztes & erstes direktes Kindelement im Blockquote: Margin */
       .content-wrap blockquote > :last-child {
         margin-bottom: .3em;
       }
    
       .content-wrap blockquote > :first-child {
         margin-top: .3em;
       }
    
       /* 2) Blockquote: keine Scrollbalken */
       .content-wrap blockquote {
         overflow: visible;     /* Standard „ohne Scrollen“ */
         overflow-x: visible;
         overflow-y: visible;
       }
     </style>
    
  2. Codeblöcke: Soft-Wraps (kein horizontales Scrollen nötig)

     <script>
     window.addEventListener('library-cm6::pre-init', event => {
         const detail = event.detail;
         const config = detail.editorViewConfig;
         const EditorView = detail.libEditorView;
    
         if (detail.usage === 'content-code-block') {
             config.extensions.push(EditorView.lineWrapping);
         }
     });
     </script>
    
  3. Dark Mode: Text heller (Überschriften 70%, Text 90%)

     <style>
     html.dark-mode .page-content h1, html.dark-mode .page-content h2, html.dark-mode .page-content h3, html.dark-mode .page-content h4, html.dark-mode .page-content h5, html.dark-mode .page-content h6 {
         color: hsl(0 0% 70%);
       }
       html.dark-mode body {
         color: hsl(0 0% 90%);
       }
     </style>
    
  4. Textgröße: Hauptinhalt 110%, Überschriften 90%

     <style>
     .page-content {
         zoom:1.1;
       }
    
       .page-content h1, .page-content h2, .page-content h3, .page-content h4, .page-content h5, .page-content h6 {
         zoom:.9;
       }
     </style>
    

Wenn du willst, kann ich dir als nächsten Schritt noch eine „Checkliste vor dem Start“ (DNS, Ports 80/443, Firewall, APP_KEY-Generierung etc.) ergänzen – inhaltlich gleich, nur als schnell abhakbare Sektion.