BookStack - Personal wiki
Bookstack is a "simple, self-hosted, easy-to-use platform for organising and storing information." In other words, it's a personal wiki. The documentation for kasad.com (what you're reading now) is hosted using BookStack.
BookStack requires two containers, the BookStack server and a database.
mysql images are used for those.
The BookStack web app is reverse-proxied behind the Secure Web Application Gateway (SWAG) container. It is not protected by Cloudflare Access policies in order to allow public read-only access to the content. A login is required to edit content.
Docker Compose stack
We deploy the BookStack instance using the following Docker Compose file:
version: "2" services: bookstack: image: lscr.io/linuxserver/bookstack:22.09.20220908 container_name: bookstack environment: - PUID=1003 # bookstack - PGID=941 # servlets - UMASK=007 env_file: stack.env volumes: - /srv/bookstack/config:/config networks: - default - swag restart: unless-stopped depends_on: - bookstack_db bookstack_db: image: mysql container_name: bookstack_db environment: - PUID=1003 # bookstack - PGID=941 # servlets - UMASK=007 - TZ=America/Los_Angeles - MYSQL_ROOT_PASSWORD=[redacted] - MYSQL_DATABASE=bookstackapp - MYSQL_USER=bookstack - MYSQL_PASSWORD=[redacted] volumes: - /srv/bookstack/db_data:/var/lib/mysql restart: unless-stopped networks: swag: external: true name: swag_default
Since our BookStack instance is reverse-proxied by the Secure Web Application Gateway, the SWAG container needs network access to the Bookstack container. This has been done in the Compose stack above. See this explanation for details.
Persistent file volumes
BookStack stores most of its data in the MySQL database.
However, some of BookStack's configuration data is stored in files in the
/config directory and file uploads are stored in the
So we mount a storage volume on
/config within the
bookstack container in order to persist this data between service restarts:
volumes: - /srv/bookstack/config:/config
The configuration for BookStack's server is done using environment variables. There is a settings interface within the BookStack web frontend which controls settings that pertain to using BookStack.
For example, configuring the SMTP server is done using environment variables whereas configuring user roles is done from the settings interface.
All of BookStack's configuration can be done using environment variables.
By default, BookStack is designed to read configuration by parsing
/config/www/.env for environment variables.
Variables defined in the container's environment are also applied.
A value defined in the container environment will override a different value for the same variable in the file.
To improve container repeatability, we define these variables in a
stack.env file adjacent to the
This file is loaded into the container's environment by setting
env_file: stack.env for the
bookstack service in the Compose file.
The contents of the
stack.env file are listed below.
The comments in the file explain the settings well, so they will not be explained again on this page.
More settings are available, and are documented in the Configuration section of BookStack's documentation.
# Application URL # This must be the root URL that you want to host BookStack on. # All URLs in BookStack will be generated using this value # to ensure URLs generated are consistent and secure. # If you change this in the future you may need to run a command # to update stored URLs in the database. Command example: # php artisan bookstack:update-url https://old.example.com https://new.example.com APP_URL=https://books.kasad.com/ # Database connection parameters DB_HOST=bookstack_db DB_DATABASE=bookstackapp DB_USERNAME=bookstack DB_PASSWORD=[redacted] # Mail system to use # Can be 'smtp' or 'sendmail' MAIL_DRIVER=smtp # Mail sender details MAIL_FROM_NAME="Kasad BookStack" MAIL_FROMfirstname.lastname@example.org # SMTP mail options # These settings can be checked using the "Send a Test Email" # feature found in the "Settings > Maintenance" area of the system. MAIL_HOST=mail.kasad.com MAIL_PORT=587 MAIL_ENCRYPTION=tls MAIL_USERNAME=bookstack MAIL_PASSWORD=[redacted] # OpenID Connect authentication AUTH_METHOD=oidc # Control if BookStack automatically initiates login via your OIDC system # if it's the only authentication method. Prevents the need for the # user to click the "Login with x" button on the login page. # Setting this to true enables auto-initiation. AUTH_AUTO_INITIATE=true # Set the display name to be shown on the login button. # (Login with <name>) OIDC_NAME="Kasad Auth Portal" # Name of the claims(s) to use for the user's display name. # Can have multiple attributes listed, separated with a '|' in which # case those values will be joined with a space. # Example: OIDC_DISPLAY_NAME_CLAIMS=given_name|family_name OIDC_DISPLAY_NAME_CLAIMS=name # OpenID Connect server parameters OIDC_CLIENT_ID=[redacted] OIDC_CLIENT_SECRET=[redacted] OIDC_ISSUER=https://auth2.kasad.com/application/o/bookstack/ OIDC_ISSUER_DISCOVER=true # Within BookStack there are a few different options for storing files: # local (Default) - Files are stored on the server running BookStack. Images are publically accessible, served by your websever, but attachments are secured behind BookStack’s authentication. # local_secure - Same as local option but images are served by BookStack, enabling authentication on image requests. Provides higher security but is more system resource intensive and could induce performance issues. # s3 - Store files externally on Amazon S3. Images are made publically accessible on upload. STORAGE_TYPE=local_secure # Only send cookies over a HTTPS connection. # Ensure you have BookStack served over HTTPS before enabling. # Defaults to 'false' SESSION_SECURE_COOKIE=true # Store user session data in the database instead of in files. # This will hopefully persist user sessions across service restarts. SESSION_DRIVER=database
Authentik OpenID provider settings
Within Authentik, we need to create an Application and an OpenID Provider for BookStack.
- In the newly-created provider, set the Redirect URI to
- Under Advanced protocol settings, ensure that Issuer mode is set to
Each provider has a different issuer, based on the application slug..
All other settings should be fine if left with their default values.
Configuration within BookStack
There are actually some settings that are controlled from BookStack's user interface when logged in as a user with administrator permissions. These settings don't pertain to the BookStack server's configuration, but instead to the user-facing options, e.g. custom theming and allowing public access sans authentication.
Users and roles
In BookStack, users have Roles which define what permissions they are given. Many roles can be created. Roles are not nested, though, so they don't inherit permissions from each other.
Roles are configured within the settings interface in BookStack. Default permissions for each role on a specific book/chapter/page can be overridden by setting custom permissions on said book/chapter/page. See Book/page permissions below for details.
OpenID group sync
Roles can be automatically assigned according to groups which a user belongs to in the SSO provider. See the Group Sync section of BookStack's OpenID documentation for details.
Configuring this requires defining two environment variables:
OIDC_USER_TO_GROUPS=true- Enable OpenID group sync
OIDC_GROUPS_CLAIM=groups- The OpenID resource claim which contains the list of groups a user belongs to. For Authentik, this is the
Books and pages can have custom permissions.
Since the instance is publicly accessible, unauthenticated users can access the content according to the permissions assigned to the
Create/modify/delete permissions should not be granted to the
Public role, otherwise unauthenticated users will be able to modify content.
By default, books/pages will not be publicly visible.
To make a book/page publicly visible, add custom permissions for that page and select the
View permission for the
Pages and chapters will inherit permissions from the book they belong to unless they are given custom permissions. More specific permissions (e.g. page level) override less specific (e.g. book level) ones.