Skip to main content

BookStack - Instalace, Konfigurace, Údržba

Návod pro instalaci, konfiguraci a údržbu BookStack wiki pro Debian GNU/Linux s využitím Apache web serveru. Instalace je založená dle návodu k manuální instalaci na bookstackapp.com/docs/admin/installation/#manual. Veškeré proměnné, hesla apod jsou zde uvedeny jako příklad.. rozhodně si nastavte vlastní, jiné hesla.

Příprava instalace

Systém

  • Prvně je potřeba opatřit si balíčky bez kterých se neobejdeme.
    apt -yq update
    apt install \
     sudo \
     curl \
     git \
     openssl \
     composer \
     mariadb-server \
     apache2 libapache2-mod-php \
     php php-common \
     php-ldap php-apcu php-fpm php-curl php-gd php-dompdf php-iconv php-mbstring php-mysql php-pdo-mysql php-tokenizer php-xml php-tidy php-zip
    

PHP

  • Nastavíme si v /etc/php/< verze php >/apache2/php.ini pro Apache větší paměťový limit a časové pásmo.
    date.timezone = Europe/Amsterdam
    memory_limit = 512M
    
  • V souboru /etc/php/< verze php >/fpm/php.ini si zvětšíme limit pro možnost uploadování větších souborů než 2MB. V mém případě beze strachu na 5GB
    upload_max_filesize = 5000M
    post_max_size = 5000M
    memory_limit = 2048M
    

Apache

  • Aktivujeme Apache moduly:
    a2enmod proxy_fcgi setenvif rewrite
    
  • Aktivujeme Apache konfigurační soubor pro naši verzi php, třeba 8.2:
    a2enconf php8.2-fpm
    

Instalace

MariaDB

  • Za předpokladu že máme balíček mariadb-server, můžeme spustit příkaz mariadb-secure-installation který nás interaktivně provede instalací. V mém případě jsem odpovídal takto:
    • Switch to unix_socket authentication [Y/n] n
    • Change the root password? [Y/n] n
    • Remove anonymous users? [Y/n] Y
    • Disallow root login remotely? [Y/n] Y
    • Remove test database and access to it? [Y/n] Y
    • Reload privilege tables now? [Y/n] Y

Databázový server máme připravený, jdeme si jej nakonfigurovat.

  • Spustit příkaz: mariadb
    • Vytvoříme si databázi pro naši wiki, v mém případě baliwki:
      CREATE DATABASE baliwiki;
      
    • Teď budeme potřebovat uživatele, který se k databázi bude připojovat. Vytvoříme si uživatele baliwiki s heslem abrakadabra a udělíme mu plné oprávnění na databázi baliwki:
      CREATE USER baliwiki@localhost IDENTIFIED BY 'abrakadabra';
      GRANT ALL ON baliwiki.* TO baliwiki@localhost WITH GRANT OPTION;
      

      🗒️ Nemělo by být potřeba, ale pokud se oprávnění neaplikují, odeslat příkaz: FLUSH PRIVILEGES;

    • Zobrazíme si oprávnění uživatele (pro kontrolu):
      SHOW GRANTS FOR baliwiki@localhost;
      
    • Tady jsme hotovi, ukončíme pomocí: quit

BookStack

V mém případě jej umisťuji do /srv/http/bookstack, kde bude vystaven na portu 80 (http). Do internetu je aplikace přístupná přes webovou proxy (ukážeme si později).

  • Vytvořit adresáře a přejít do "webrootu":
    mkdir -p /srv/http/{.config,.cache}
    cd /srv/http
    

    🗒️ Adresáře .config a .cache slouží pro composer, lze je umístit jinde..

  • Stáhnout BookStack z GitHubu, z větve release.
    git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch bookstack
    
  • Předat rekurzivně vlastnictví uživateli www-data, skupině www-data:
    chown -R www-data:www-data {bookstack,config,cache}
    
  • Přejít do složky bookstack a zkopírovat si příklad(/základ) souboru .env:
    cd bookstack
    cp .env.example .env
    
  • Oeditovat si soubor .env svým oblíbeným texťákem, kde
    • APP_URL odkazuje na koncový bod. V mém případě schovávám server za reverzní proxy a musím uvést adresu té proxy, NE serveru.
      APP_URL=https://baliwiki.balonkluk.cz
      

      ⚠️ Po každé změně této proměnné je nutné spustit příkaz k migraci URI v databázi.
      Například když migruji z interní adresy na http na reverzní proxy s https:
      php artisan bookstack:update-url http://baliwiki.in.balonkluk.cz https://baliwiki.balonkluk.cz.

      Nakonec ještě vyčistím cache: php artisan cache:clear

    • DB_HOST => localhost (pokud mám MariaDB na stejném serveru).
    • DB_DATABASE => baliwiki.
    • DB_USERNAME => baliwiki. Tohoto uživatele jsem si vytvářel při instalaci MariaDB.
    • DB_PASSWORD => abrakadabra. Toto heslo jsem nastavoval při instalaci MariaDB.
    • MAIL_DRIVER => smtp
    • MAIL_FROM_NAME => "BaliWiKi"
    • MAIL_FROM => baliwiki@balonkluk.cz (Z této emailové adresy budou chodit notifikace).
    • MAIL_HOST => mail.balonkluk.cz (Tento server bude použit jako SMTP relay pro odesílání e-mailů).
    • MAIL_PORT => 25. Server definovaný v MAIL_HOST bude kontaktován přes port 25.
    • FILE_UPLOAD_SIZE_LIMIT => 5000. Chtěl bych uploadovat až 5GB/5000MB velké soubory.
  • Nastavit jako uživatel www-data proměnnou COMPOSER_HOME do /srv/http a spustit update.

    ⚠️ Pokud jste adresáře .config a .cache vytvářeli jinde, změňte si adekvátně hodnotu proměnné.

    sudo -u www-data COMPOSER_HOME=/srv/http composer update
    
  • Spustit instalaci composera:
    sudo -u www-data composer install --no-dev --no-plugins
    
  • Vygenerovat klíč aplikace. Tento klíč bude uložen v souboru .env v proměnné APP_KEY:
    php artisan key:generate --no-interaction --force
    
  • Zmigrovat databázi do MariaDB (prvotně vytvořit):
    php artisan migrate --no-interaction --force
    
  • Nastavit oprávnění tak, aby bylo vše jak má být:
    chown www-data:www-data -R bootstrap/cache public/uploads storage 
    chmod u+rw bootstrap/cache public/uploads storage
    chmod -R 640 .env
    

Apache

  • Přepsat výchozí konfigurační soubor Apache:
    cat > /etc/apache2/sites-available/000-default.conf << EOL
    ServerName baliwiki.balonluk.cz
    ServerAdmin balonluk@balonluk.cz
    
    <VirtualHost *:80>
      DocumentRoot /srv/http/bookstack/public/
      <Directory /srv/http/bookstack/public/>
          Options Indexes FollowSymLinks
          AllowOverride None
          Require all granted
          <IfModule mod_rewrite.c>
              <IfModule mod_negotiation.c>
                  Options -MultiViews -Indexes
              </IfModule>
              RewriteEngine On
              # Handle Authorization Header
              RewriteCond %{HTTP:Authorization} .
              RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
              # Redirect Trailing Slashes If Not A Folder...
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteCond %{REQUEST_URI} (.+)/$
              RewriteRule ^ %1 [L,R=301]
              # Handle Front Controller...
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteCond %{REQUEST_FILENAME} !-f
              RewriteRule ^ index.php [L]
          </IfModule>
      </Directory>
    
      SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
      LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded
    
      ErrorLog ${APACHE_LOG_DIR}/baliwiki-error.log
      CustomLog ${APACHE_LOG_DIR}/baliwiki-access.log combined env=!forwarded
      CustomLog ${APACHE_LOG_DIR}/baliwiki-access.log forwarded env=forwarded
    
    </VirtualHost>
    EOL
    
  • Otestovat, že je konfigurace v pořádku:
    apachectl configtest
    
  • Restartovat webserver:
    systemctl restart apache2
    
  • Otevřít si v prohlížeči URI definovanou v proměnné APP_URL, v souboru .env. Např.: http://baliwiki.balonluk.cz
  • Přihlásit se jako admin@admin.local s heslem admin.
  • Změnit si heslo a mail na něco co vám dává smysl.

Hotovo 😁

Konfigurace

Poskytovatel identit

LDAP

LDAP nám umožňuje ověření a synchronizaci uživatelských skupin v něm a rolí v BookStacku.

🗒️ Konfigurace je popsána na oficiálních stránkách projektu.

💡 Pro řešení problémů s LDAP skupinami lze nastavit LDAP_DUMP_USER_GROUPS na true. Uživatel při přihlášení uvidí .json ve kterém budou informace o uživateli.

V základu je potřeba nastavit v souboru .env:

  • AUTH_METHOD=ldap místo AUTH_METHOD=standart (lokální přihlášení přes e-mail a heslo).
  • LDAP_SERVER => ldap://ldap.balonkluk.cz (389) nebo ldaps://ldap.balonkluk.cz (636)
  • LDAP_BASE_DN => ou=Users,dc=balonkluk,dc=cz
  • LDAP_DN => cn=baliwiki,ou=Users,dc=balonkluk,dc=cz
  • LDAP_PASS => myultimateldaplmaopassword
  • LDAP_ID_ATTRIBUTE =>
    • Výchozí je uid.
    • Při použití Active Directory je lepší zvolit sAMAccountName.
  • LDAP_EMAIL_ATTRIBUTE => mail
  • LDAP_DISPLAY_NAME_ATTRIBUTE => cn
  • (volitelné) LDAP_THUMBNAIL_ATTRIBUTE => thumbnailPhoto

    ⚠️ Atribut musí obsahovat binární JPEG data !

  • LDAP_USER_TO_GROUPS => true (Zapne synchronizaci LDAP skupin x BookStack rolí => člen LDAP skupiny Admini bude člen BookStack role pojmenované Admini).
  • LDAP_GROUP_ATTRIBUTE => "memberOf" (Atribut ve kterém má uživatel uložené členství ve skupinách. Ve výchozím stavu je nastaveno na memberOf a není potřeba explicitně definovat, pro jistotu je to určitě lepší.
  • (volitelné) LDAP_REMOVE_FROM_GROUPS => false (Pokud např.: chceme aby nám LDAP neodebral uživateli roli Admin pokud není v LDAP skupině se stejným jménem. Zkrátka pokud bude mít uživatel role které nemá v LDAPu, budou mu odebrány).

Azure AD

🗒️ Konfigurace je popsána na oficiálních stránkách projektu.

S tímto druhem přihlášení se nedají synchronizovat role/skupiny a je lepší použít OIDC nebo SAML SSO.
Co je ale dobré, je možnost alternativního přihlášení kromě standart/ldap protože Azure účet musí být s uživatelským účtem v BookStacku prolinkován a máme na výběr dvě možnosti přihlášení do jednoho stejného účtu (např.: ldap+azure nebo standart+azure).

Je potřeba pouze nastavit tři proměnné:

  • AZURE_APP_ID: Často reprezentováno jako client_id. Entra tento atribut nabízí jako Application ID.
  • AZURE_APP_SECRET: V Certificates & secrets vytvořit nový Client secret. HODNOTU (Value), nikoliv Secret ID a zkopírujeme zde.
  • AZURE_TENANT: ID tenantu. V základní/domovské obrazovce (Overview) aplikace lze najít názvem Directory (tenant) ID.

OpenID Connect

OpenID Connect nám v BookStacku umožňuje synchronizovat i skupiny uživatele a je tak lepší alternativou Azure AD navíc s podporou SSO což znamená, že máme jednotné přihlášení napříč weby kde požíváme stejného poskytovatele identit. Nevýhodou může být, že si v nastavení musíme vybrat v AUTH_METHOD oidc a na přihlašovací obrazovce budeme mít jako možnost přihlášení POUZE tuto metodu.

🗒️ Konfigurace je popsána na oficiálních stránkách projektu.

💡Pro debugování tokenu lze nastavit OIDC_DUMP_USER_DETAILS=true v souboru .env a po přihlášení na nás vyskočí .json plný informací.

Entra ID

Jak nastavíme OIDC pomocí vlastní Entra ID ?

  • EntraID
    • Vytvořit App registration.
    • Authentication => [ + Add a platform ] => Web => Nastavit Redirect URI na < obsah proměnné APP_URL v konfiguračním souboru .env + /oidc/callback' >. Například: https://baliwiki.balonluk.cz/oidc/callback>
    • Certificates & secrets => [ + New client secret ] => < Pojmenovat si klíč a nastavit platnost (volil bych nejdelší - 24 měsíců) > => [Add]. Zkopírovat HODNOTU (Value), nikoliv Secret ID a uložit si jej někam (později jej budeme potřebovat) NEBO rovnou vyplnit v .env do proměnné OIDC_CLIENT_SECRET.
    • Token configuration => [ + Add groups claim ] => Customize token properties by type =>
      • [X] Security groups
      • [X] Directory roles
      • [X] All groups (includes 3 group types: security groups, directory roles, and distribution lists)
      • [X] Groups assigned to the application (recommended for large enterprise companies to avoid exceeding the limit on the number of groups a token can emit)
      • Customize token properties by type:
        • ID:
          • sAMAccountName
    • API permissions
      • [ + Add a permission ] => Microsoft Graph => Delegated permissions => Nyní máme dvě možnosti jak nastavit oprávnění ke čtení uživatelského profilu. Buď pomocí vybrání jednotlivých oprávnění nebo obecného User.Read (Sign in and read user profile).
        • OpenId permissions

          🗒️ User.Read => Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users.
          GroupMember.Read.All => Allows the app to list groups, read basic group properties and read membership of all groups the signed-in user has access to.

          • email (Může být použito User.Read)
          • openid (Může být použito User.Read)
          • profile (Může být použito User.Read)
          • GroupMember.Read.All
        • => [ Add permissions ]
        • Kliknout na [ Grand admin consent for <jméno tvého tenantu> ]. Toto je nutné pro scope GroupMember.Read.All, u ostatních jde vybrat Revoke admin consent.

          🗒️ Tato akce udělí všem uživatelům oprávnění používat tento scope v této aplikaci.

  • BookStack
    • AUTH_METHOD => oidc
    • (Volitelné) AUTH_AUTO_INITIATE => false (Pokud je nastaveno na true, uživatel je automaticky přesměrován na přihlašovací bránu SSO).
    • OIDC_NAME => BalonKluk MS (Label který bude vidět na tlačítku k přihlášení).
    • OIDC_DISPLAY_NAME_CLAIMS => name (Jméno claimu který obsahuje <Zobrazované jméno>)
    • OIDC_CLIENT_ID => <Application (client) ID>
    • OIDC_CLIENT_SECRET => Token který jsme si dříve vygenerovali v Certificates & secrets.
    • OIDC_ISSUER => https://login.microsoftonline.com/< Directory (tenant) ID >/v2.0
    • OIDC_ISSUER_DISCOVER => true (Zapíná auto-discovery tokenů a klíčů. Standartně se předpokládá endpoint <issuer>/.well-known/openid-configuration)
    • OIDC_USER_TO_GROUPS => true (Zapíná synchronizaci skupin. POZOR! Pro toto je nutné nezapomenout na GroupMember.Read.All a Admin consent !)
    • OIDC_GROUPS_CLAIM => groups (Atribut v tokenu, ve kterém jsou skupiny získárny.)
    • (Volitelné) OIDC_ADDITIONAL_SCOPES => Zde lze nastavit scope který bychom chtěli při přihlášení získat "navíc".
    • OIDC_REMOVE_FROM_GROUPS => false (Stejně jako v LDAPu toto znamená, odebrat z rolí které nadále uživatel nemá.)

Údržba

Záloha a Obnovení

Jak zálohovat a obnovit BookStack je pěkně popsáno na oficiálních stránkách.

V mém případě provedu zálohu takto:

mysqldump -u root baliwiki > baliwiki_db-backup.sql
tar -czvpf baliwiki-backup.tar.gz /srv/http/bookstack/{.env,public/uploads,storage/uploads,themes}

Obnovení zase takto:

mysql -u root -p baliwiki < baliwiki_db-backup.sql
tar -C /srv/http/bookstack -xvzpf baliwiki-backup.tar.gz

Aktualizace

Před aktualizací radši proveď zálohu !

  • Aktualizaci provedeme tak, že nejprve uvnitř kořenového adresáře aktualizujeme git repozitář.

    cd /srv/http/bookstack
    sudo git pull origin release
    
  • Pokračovat v instalaci pomocí:

    sudo composer install --no-dev
    sudo php artisan migrate
    
  • Nakonec promazat cache:

    sudo php artisan cache:clear
    sudo php artisan config:clear
    sudo php artisan view:clear