How to deploy BookStack 0.29.3 in docker swarm behind Traefik v2.0

How to deploy BookStack 0.29.3 in docker swarm behind Traefik v2.0

BookStack is a simple, self-hosted, platform for organizing; storing information, and books can contain chapters and pages.

This post is to show you how to deploy BookStack 0.29.3 to our Docker Swarm Cluster using the Docker Compose tool.

BookStack is a simple, self-hosted, easy-to-use platform for organizing and storing information.

learn more about using the official BookStack website and GitHub.

Let’s start with actual deployment…

Prerequisites

Please make sure you should fulfill the below requirements before proceeding to the actual deployment.

  1. Docker Swarm Cluster with GlusterFS as persistent tool.
  2. Traefik as reverse proxy to expose micro-services to external.
  3. Database stack to host application databases.

Introduction

If you are looking to self-host your product documents to reduce the footprint of ticket management or want to manage project documentation for internal teams or want to have a private repository, BookStack is the best solution to consider.

BookStack is an opinionated wiki system that provides a pleasant and simple out of the box experience.

Why is BookStack

BookStack is a simple, easy-to-use platform for storing and organizing information and documentation.

New users only require basic word-processing skills to get involved in creating content on BookStack.

BookStack is not designed as an extensible platform to be used for purposes that differ to the statement above.

In regards to development philosophy, BookStack has a relaxed, open & positive approach. At the end of the day, this is free software developed and maintained by people donating their own free time.

The principles of storing information within BookStack is based on the ideas of a normal stack of books. Just like normal books, BookStack books can contain chapters and pages. You start off by creating a book that acts as the highest level of categorization. Ideally, you’d have separate books for separate topics.

Within a book, you can directly create pages or you can first create chapters. Chapters provide an additional level of page grouping to keep pages organized but are optional.

Once you start to stack up books you can start to use Bookshelves to organize your Books. Bookshelves can contain multiple books and a single book could be placed on multiple Bookshelves.

BookStack Features

BookStack should provide advanced power features to those that desire it but they should not interfere with the core simple user experience.

Here are some of the features that you’ll love

  1. BookStack is fully free and open, MIT licensed. There is no cost to downloading and installing your own instance.

  2. Simplicity has been the top priority. It has a simple WYSIWYG interface & content is broken into Books, Chapters, and Pages.

  3. The content is fully searchable. Search at book level or across all books, chapters & pages. You can link directly to any paragraph to keep documentation connected.

  4. BookStack is built using PHP, on top of the Laravel framework and it uses MySQL to store data. It can run happily on a $5 Digital Ocean VPS.

  5. You can set up BookStack to suit your use case, change the name, Logo, and registration options. You can also change whether the whole system is publicly viewable or not.

  6. Along with the default email/password login, social providers such as GitHub, Google, Slack, AzureAD, and more can be used. Okta and LDAP options are available for enterprise environments.

Some other features include below as well apart from the above list

  • Multi-lingual
  • Powerful Features
  • Optional Markdown Editor

Persist BookStack Data

Containers are fast to deploy and make efficient use of system resources. Developers get application portability and programmable image management and the operations team gets standard run time units of deployment and management.

With all the known benefits of containers, there is one common misperception that the containers are ephemeral, which means if we restart the container or in case of any issues with it, we lose all the data for that particular container. They are only good for stateless micro-service applications and that it’s not possible to containerize stateful applications.

I am going to use GlusterFS to overcome the ephemeral behavior of Containers.

I already set up a replicated GlusterFS volume to have data replicated throughout the cluster if I would like to have some persistent data.

The below diagram explains how the replicated volume works.

GlusterFS Replicated Volume

Volume will be mounted on all the nodes, and when a file is written to the /mnt partition, data will be replicated to all the nodes in the Cluster

Note

In case of any one of the nodes fails, the application automatically starts on other node without loosing any data and that’s the beauty of the replicated volume.

Persistent application state or data needs to survive application restarts and outages. We are storing the data or state in GlusterFS and had periodic backups performed on it.

We will use a backup of the volume to spin a new application container anywhere else in case of unexpected issues occur in the current environment.

I am going to persist /var/www/bookstack/public/uploads and /var/www/bookstack/storage/uploads directories of BookStack for disaster recovery.

Create folders in /mnt directory to persistent BookStack data folders.

cd /mnt
sudo mkdir -p buploads
sudo mkdir -p bsuploads

Tip

Please watch the below video for the GlusterFS Replicated Volume Setup.

Prepare BookStack Environment

Create a folder in /opt directory to place configuration file, i.e, .yml file for BookStack.

Use the below commands to create the folder.

cd /opt
sudo mkdir -p bookstack
cd bookstack
sudo touch bookstack.yml

BookStack Docker Compose

Open bookstack.yml created earlier with nano editor using sudo nano bookstack.yml

Copy and paste the below code in bookstack.yml

Here is the docker compose file for bookstack.

version: "3.7"
 
services:
  bookstack:
    image: solidnerd/bookstack
    ports:
      - '8081:8080'
    volumes:
      - /mnt/buploads:/var/www/bookstack/public/uploads
      - /mnt/bsuploads:/var/www/bookstack/storage/uploads
    secrets:
      - mysql_root_password
    environment:
      - DB_HOST=db:3306
      - DB_DATABASE=bookstack
      - DB_USERNAME=root
      - DB_PASSWORD_FILE=/run/secrets/mysql_root_password
      - APP_URL=https://bookstack.example.com
      - STORAGE_TYPE=local_secure
      - AUTH_METHOD=standard
      - APP_AUTO_LANG_PUBLIC=true
      - APP_VIEWS_BOOKS=grid
      - CACHE_DRIVER=file
      - SESSION_DRIVER=file
      - SESSION_LIFETIME=120
      - SESSION_COOKIE_NAME=book_session
      - SESSION_SECURE_COOKIE=false
      - CACHE_PREFIX=bookstack
    networks:
      - proxy
    deploy:
      placement:
        constraints: [node.role == worker]
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=proxy"
        - "traefik.http.routers.bookstack.rule=Host(`bookstack.example.com`)"
        - "traefik.http.routers.bookstack.tls=true"
        - "traefik.http.routers.bookstack.tls.certresolver=default"
        - "traefik.http.routers.bookstack.entrypoints=websecure"
        - "traefik.http.services.bookstack.loadbalancer.server.port=8080"
secrets:
  mysql_root_password:
    external: true
volumes:
  buploads:
    driver: "local"
  bsuploads:
    driver: "local"
networks:
  proxy:
    external: true

As I mentioned in the prerequisites, I used MariaDB as a back-end storage system for BookStack which was deployed earlier to our Docker Swarm environment.

There are some configurations we can use while composing BookStack. Please go through this link for the full set of configuration options.

Community docker setups are available for those that would prefer to use a containerized version of BookStack:

LinuxServer.io

Solidnerd

Deploy BookStack using Docker Compose

Please make sure we have created a wiki database before deploying BookStack using the MariaDB stack deployed earlier.

Now it’s time to deploy our docker-compose file above, bookstack.yml using the below command

docker stack deploy --compose-file bookstack.yml bookstack

You can give it any name for the stack. I just named it as bookstack

Check the status of the stack by using docker stack ps bookstack

Now open any browser and type bookstack.example.com (whatever host URL used in the BookStack configuration in the docker-compose file) to access the instance.

Make sure that you have DNS entry for your application (bookstack.example.com) in your DNS Management Application.

You will be greeted with the below screen to the login screen of BookStack. Use default credentials (admin@admin.com / password) to login.

Bookstack Login Screen

Change Admin email address and password in Edit Profile settings.

Edit Admin Profile

Shelves View

Books view

Bookstack Settings

Hope you enjoyed this tutorial, please give your input/thought on it by commenting below. It would help me to bring more articles that focus on Open Source to self-host.

Stay tuned for other deployments in coming posts…🙄