bookstack

BookStack

BookStack is a well-maintained documentation platform and web application that allows for organizing notes with a basic book, chapter, page structure. Books can then be ‘Shelved’ with similar books, and further organized with images / permissions. Check out the Official BookStack Website for more information and documentation on some of the other features BookStack offers.

When looking for a central place to store notes on various projects, there were many possible solutions that didn’t require the use of Docker, NGINX, Git, Markdown, or Linux. The benefit of hosting a personal notes / documentation application for me is seen in my ability to manually backup my documentation or migrate my service to another platform if needed. This may seem like two very simple requests, but when migrating between services issues can surface due to the service’s need for a specific file structure, syntax, or other dependency. This is where BookStack’s use of Markdown language within its post editor is helpful. Since we can create posts with Markdown and count on BookStack to translate the content as needed on the back-end, our content remains independent from the specifics of the BookStack platform itself, allowing us to simply copy over our content to another platform, should we ever want to make a move.

BookStack Markdown

The following table is a quoted from the Markdown Documentation hosted on the BookStack website.

Shortcut Description
Ctrl+S Save Draft
Ctrl+Enter Save Page
Ctrl+1 Header Large
Ctrl+2 Header Medium
Ctrl+3 Header Small
Ctrl+4 Header Tiny
Ctrl+5 Normal Paragraph
Ctrl+6 Blockquote
Ctrl+7 Code Block
Ctrl+8 Inline Code
Ctrl+9 Callout (info)
Ctrl+k Insert Link

When using Ctrl-9 to insert a callout within your post, you will notice some HTML is input within your Markdown editor. BookStack offers info, warning, and danger callouts. Simply change the info callout snippet inserted when using Ctrl+9 to any of the below to use them.

1
2
3
<p class="callout info"></p>
<p class="callout warning"></p>
<p class="callout danger"></p>

Knoats Documentation

Knoats is my personal project in linux administation and documentation – it is open for signup, and the only reason for doing so is to see and comment on less polished content. There are a few books and pages that can be edited (text only) if you are logged in, but for the most part this is public only to share the information I’ve learned along the way and isn’t intended to be a service to anyone other than myself. That being said, I hope some of the information hosted there can serve anyone who may be passing through, as that’s the sole reason I’ve decided to make it public.

Public Contribution

I’m open to collaboration where appropriate – it is possible for me to on-board others as I see fit to edit the documentation hosted on Knoats. Chances are, I’ll be willing to set up your account to have the appropriate permissions. I hope to one day be able to use this project to collaborate on well built documentation for projects controlled via Git or otherwise worked remote.

BookStackApp/BookStack

Docker

LinuxServer provides a Docker image which is well maintained and updated as the main BookStack Repository is versioned. They also host a good bit of information on other images and current / upcoming projects at LinuxServer.io, which is a good central location to begin exploring if you are looking to learn about Docker images. Their images are not only well-maintained, but they have an active community which can be easily found by reading through their blog or joining their Discord server which is linked on all of their repositories. These are volunteers and enthusiasts, so please approach them appropriately if you are requesting support on an image or repository they are hosting.

Container Setup

For running a containerized version of BookStack, I ran into some discrepancies from the general BookStack documentation vs actual implementation of the LinuxServer image, especially when dealing with networking and the termination of SSL. There are many solutions and sources to these problems if you have never hosted an application with Docker, and I found realizing these differences to be a positive and well documented learning experience. There may be a full end-to-end tutorial out there somewhere for this specific image, but I simply pulled the image via docker compose and reconfigured as needed to resolve the issues I faced. This gave me an opportunity to learn a bit about Networking, Docker, Compose, and Linux in general.

LinuxServer’s Docker BookStack repository

Snippets

Below are some snippets related to the changes I had to make to get the BookStack container running. Feel free to reference them as needed for any projects you might be working on.

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
---
version: "2"
services:
bookstack:
image: linuxserver/bookstack
container_name: bookstack
environment:
- PUID=1000
- PGID=1000
- DB_HOST=bookstack_db
- DB_USER=bookstack
- DB_PASS=<yourdbpass>
- DB_DATABASE=bookstackapp
volumes:
- <path to local data>:/config
ports:
- 6875:80
restart: unless-stopped
depends_on:
- bookstack_db
bookstack_db:
image: linuxserver/mariadb
container_name: bookstack_db
environment:
- PUID=1000
- PGID=1000
- MYSQL_ROOT_PASSWORD=<yourdbpass>
- TZ=Europe/London
- MYSQL_DATABASE=bookstackapp
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=<yourdbpass>
volumes:
- <path to local data>:/config
restart: unless-stopped

I’ll reiterate here what I went over on the WordPress Docker explanation -

Its important to note above that the volumes we define carry the syntax local:container when defining the path to be mounted, and we don’t need to initialize any directories / configurations in general. When the container starts the first time, directories and files will be created and any volumes defined in the docker-compose.yml used to create the service will be mounted so that the files on the container are available locally on the host. This is a useful tool to help ease the task of automating or scheduling backups and also makes the configurations on the container easier to modify using our local settings and packages.

This docker-compose.yml was taken directly from the default provided by LinuxServer

nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# A simple nginx.conf showing how to pass traffic to a docker container
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events { }

http {
include mime.types;

# Redirect root domains
server {
listen 80;
server_name domain.com www.domain.com;
return 301 https://www.domain.com$request_uri;

}


# SSL - domain.com
server {
server_name domain.com www.domain.com;
server_tokens off;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

# Pass to container
location / {
include proxy_params;
proxy_pass http://localhost:1234/;
}

}

}