Skip to main content

Install your own BookStack instance

'>

ℹ️ DieseThis Anleitungguide startetstarts abfrom demthe Punktpoint, anwhere demyou dualready bereitshave einena Linux-ServerLinux server hast undand Docker installiertis ist.installed. DieThe „Schritte“steps davor“before folgenthat” späterwill follow eslater ist wirklichit’s nichtreally schwernot hard (besondersespecially mitwith KI-Hilfe)AI help).


Überblick:Overview: WasWhat’s wirdbeing hierset eingerichtet?up here?

DuIn bekommstthe amend Ende:you’ll have:

  • BookStack (Wiki/Docs-System)wiki/docs system)
  • MariaDB alsas Datenbankthe database
  • Caddy alsas Reversea Proxyreverse mitproxy with automatischemautomatic HTTPS (Let’s Encrypt) 🌐

Hintergrund:Background: WasWhat istis Caddy? 🌐

Caddy istis eina modernermodern Webserverweb server (ähnlichsimilar to Nginx/Apache), geschriebenwritten in Go, derthat embraces “Security-security-by-default lebtand, undabove dirall, vor allemmakes HTTPS extremextremely bequem macht.convenient.

Kernidee:Core idea: „Webserver,“A derweb einfachserver funktioniert“that just works”

WichtigeKey Merkmalefeatures

  1. AutomatischesAutomatic HTTPS (TLS)
    • ZertifikateCertificates werdenare automatischobtained bezogenand undrenewed erneuertautomatically (typischtypically via Let’s Encrypt).
  2. EinfacheSimple Konfigurationconfiguration
    • ÜberVia einan gut lesbareseasy-to-read Caddyfile.
  3. Reverse Proxyproxy & Loadload Balancingbalancing
    • Ideal,Ideal umfor Anfragenforwarding anrequests Servicesto services (z.e.g., B.Docker Docker-Container) weiterzuleiten.containers).
  4. GuteGood Defaultsdefaults
    • VieleMany sinnvollesensible Security-Standardssecurity sindstandards direktare aktiv.enabled by default.
  5. Modular erweiterbarextensibility
    • BeiIf speziellenyou Anforderungenhave lässtspecial sichrequirements, Caddy ausbauen.can be extended.

TypischeTypical Einsatzfälleuse cases 🧩

  • WebsitesHosting hostenwebsites (statisch/dynamisch)static/dynamic)
  • Reverse Proxyproxy vorin einerfront Appof an app (z. B.e.g., /apiBackend)backend)
  • TLS-TerminationTLS termination
  • LokaleLocal Dev-Setupsdev mitsetups with HTTPS

SchrittStep 1: VerzeichnisPrepare directory & Dateien vorbereitenfiles 🧱

ErstelleCreate dasthe Verzeichnis:directory:

  • /opt/bookstack

Lege darinCreate zweitwo Dateienfiles an:inside it:

  • docker-compose.yml
  • Caddyfile

✍️ Wichtig:Important: DuYou’ll musstneed gleichto einadjust paara Wertefew anpassenvalues in dua siehstmoment im YAMLyou sehrcan deutlich,clearly see wowhere. in the YAML.


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

FügePaste folgendenthe Inhaltfollowing eincontent (undand passeadjust ihnit an,where wo nötig)necessary):

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
      # WoWhere wirdwill BookStack aufrufbarbe sein?accessible? (DeineYour URL)
      - APP_KEY=base64:...
      # ZumTo Generierengenerate dasit, ausführen:run: docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey
      - APP_THEME=custom
      #'custom' ermöglichmakes esit Hackspossible zuto nutzen;use mehrhacks; dazumore hier:on that here: https://www.bookstackapp.com/hacks/applying/

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

      - APP_DEFAULT_DARK_MODE=true
      # (Geschmackssache)Personal preference)

    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 ▶️

    Ins Verzeichnis wechseln:

      cd /opt/bookstack/

      Stack starten:

        docker compose up -d

        Aktualisieren geht später so:

          docker compose pull docker compose up -d

          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:

              Crontab öffnen:
                crontab -e 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:

                    E-Mail-Versand

                      (z. B. „Passwort vergessen“) funktioniert bei mir nicht bzw. meine Experimente haben noch keine Lösung hervorgebracht. Ich brauche es nicht zwingend – aber z. B. für Kommentare (Benachrichtigungen) kommt man daran nicht vorbei. Mehr dazu:
                      https://www.bookstackapp.com/docs/admin/email-webhooks/#email-configuration

                      Erweiterung über „Hacks“

                        BookStack kann über sogenannte „Hacks“ erweitert werden. Zwei Empfehlungen:
                          MathJax/TeX (Mathe-Formeln):
                            https://www.bookstackapp.com/hacks/mathjax-tex/ Mermaid Viewer (Diagramme):
                              https://www.bookstackapp.com/hacks/mermaid-viewer/

                              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:
                                      In den Container wechseln:
                                        docker exec -it bookstack /bin/bash Ins Web-Verzeichnis:
                                          cd /app/www/ Dort das Kommando ausführen, das im jeweiligen Hack steht (Beispiel Mermaid):
                                            Auf der Hack-Seite im Abschnitt „Install as Module“
                                            https://www.bookstackapp.com/hacks/mermaid-viewer/

                                            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:

                                                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>
                                                

                                                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:

                                                    https://deineurl.com/settings/customization

                                                    Einfach jeweils unter „Custom HTML Head Content“ eintragen:

                                                      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>
                                                        

                                                        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>
                                                        

                                                        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>
                                                        

                                                        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>