You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
6.6 KiB
Markdown
247 lines
6.6 KiB
Markdown
4 years ago
|
# Bookstack in docker
|
||
|
|
||
|
###### guide by example
|
||
|
|
||
|
![logo](https://i.imgur.com/qDXwqaU.png)
|
||
|
|
||
|
### Purpose
|
||
|
|
||
|
Documentation and notes.
|
||
|
|
||
|
* [Official site](https://www.bookstackapp.com/)
|
||
|
* [Github](https://github.com/BookStackApp/BookStack)
|
||
|
* [DockerHub image used](https://hub.docker.com/r/linuxserver/bookstack)
|
||
|
|
||
|
### Files and directory structure
|
||
|
|
||
|
```
|
||
|
/home
|
||
|
└── ~
|
||
|
└── docker
|
||
|
└── bookstack
|
||
|
├── 🗁 bookstack-data
|
||
|
├── 🗁 bookstack-data-db
|
||
|
├── 🗁 bookstack-backup
|
||
|
├── 🗋 .env
|
||
|
├── 🗋 docker-compose.yml
|
||
|
└── 🗋 bookstack-backup-script.sh
|
||
|
```
|
||
|
|
||
|
### docker-compose
|
||
|
|
||
|
Dockerhub linuxserver/bookstack [example compose.](https://hub.docker.com/r/linuxserver/bookstack)
|
||
|
|
||
|
`docker-compose.yml`
|
||
|
|
||
|
```
|
||
|
version: "2"
|
||
|
services:
|
||
|
|
||
|
bookstack:
|
||
|
image: linuxserver/bookstack
|
||
|
container_name: bookstack
|
||
|
hostname: bookstack
|
||
|
environment:
|
||
|
- PUID
|
||
|
- PGID
|
||
|
- DB_HOST
|
||
|
- DB_USER
|
||
|
- DB_PASS
|
||
|
- DB_DATABASE
|
||
|
- APP_URL
|
||
|
volumes:
|
||
|
- ./bookstack-data:/config
|
||
|
restart: unless-stopped
|
||
|
depends_on:
|
||
|
- bookstack_db
|
||
|
|
||
|
bookstack_db:
|
||
|
image: linuxserver/mariadb
|
||
|
container_name: bookstack_db
|
||
|
hostname: bookstack_db
|
||
|
environment:
|
||
|
- PUID
|
||
|
- PGID
|
||
|
- MYSQL_ROOT_PASSWORD
|
||
|
- TZ
|
||
|
- MYSQL_DATABASE
|
||
|
- MYSQL_USER
|
||
|
- MYSQL_PASSWORD
|
||
|
volumes:
|
||
|
- ./bookstack-data-db:/config
|
||
|
restart: unless-stopped
|
||
|
|
||
|
networks:
|
||
|
default:
|
||
|
external:
|
||
|
name: $DEFAULT_NETWORK
|
||
|
```
|
||
|
|
||
|
`.env`
|
||
|
|
||
|
```
|
||
|
# GENERAL
|
||
|
MY_DOMAIN=blabla.org
|
||
|
DEFAULT_NETWORK=caddy_net
|
||
|
TZ=Europe/Prague
|
||
|
|
||
|
# BOOKSTACK
|
||
|
PUID=1000
|
||
|
PGID=1000
|
||
|
DB_HOST=bookstack_db
|
||
|
DB_USER=bookstack
|
||
|
DB_PASS=bookstack
|
||
|
DB_DATABASE=bookstackapp
|
||
|
APP_URL=https://book.blabla.org
|
||
|
|
||
|
# BOOKSTACK-MARIADB
|
||
|
PUID=1000
|
||
|
PGID=1000
|
||
|
MYSQL_ROOT_PASSWORD=bookstack
|
||
|
MYSQL_DATABASE=bookstackapp
|
||
|
MYSQL_USER=bookstack
|
||
|
MYSQL_PASSWORD=bookstack
|
||
|
```
|
||
|
|
||
|
### reverse proxy
|
||
|
|
||
|
caddy v2 is used,
|
||
|
details [here](https://github.com/DoTheEvo/Caddy-v2-examples)
|
||
|
|
||
|
`Caddyfile`
|
||
|
```
|
||
|
{
|
||
|
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
||
|
}
|
||
|
|
||
|
book.{$MY_DOMAIN} {
|
||
|
reverse_proxy {
|
||
|
to bookstack:80
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### update
|
||
|
|
||
|
* [watchguard]() updates the image automaticly
|
||
|
|
||
|
* manual image update</br>
|
||
|
`docker-compose pull`</br>
|
||
|
`docker-compose up -d`</br>
|
||
|
`docker image prune`
|
||
|
|
||
|
### backup and restore
|
||
|
|
||
|
* **backup** using [borgbackup setup](https://github.com/DoTheEvo/docker-selfhosted-projects/tree/master/borg_backup)
|
||
|
that makes daily backup of the entire directory
|
||
|
|
||
|
* **restore**</br>
|
||
|
down the bookstack containers `docker-compose down`</br>
|
||
|
delete the entire bookstack directory</br>
|
||
|
from the backup copy back the bookstack directortory</br>
|
||
|
start the container `docker-compose up -d`
|
||
|
|
||
|
### Backup of just user data
|
||
|
|
||
|
For additional peace of mind.
|
||
|
Having user-data daily exported using the [official procedure.](https://www.bookstackapp.com/docs/admin/backup-restore/)</br>
|
||
|
For bookstack it means database dump and the content of several directories
|
||
|
containing user uploaded files.
|
||
|
The backup files are overwriten on every run of the script,
|
||
|
but borg backup is backing entire directory in to snapshots, so no need for some keeping-last-X consideration.
|
||
|
|
||
|
* **database backup**</br>
|
||
|
script `make_backup.sh` placed in to `bookstack_db` container,
|
||
|
in to `/config` directory that is bind mounted to the host machine.</br>
|
||
|
made executable `chmod +x make_backup.sh` inside the container
|
||
|
|
||
|
- This script creates path `/config/backups-db`</br>
|
||
|
- deletes all files in the backup path except 30 newest</br>
|
||
|
- creates new mysqldump using env variables passed from `.env` file</br>
|
||
|
|
||
|
`make_backup.sh`
|
||
|
```
|
||
|
#!/bin/bash
|
||
|
|
||
|
# -----------------------------------------------
|
||
|
NUMB_BACKUPS_TO_KEEP=30
|
||
|
BACKUP_PATH=/config/backups-db
|
||
|
BACKUP_NAME=$(date +"%s").bookstack.database.backup.sql
|
||
|
# -----------------------------------------------
|
||
|
|
||
|
mkdir -p $BACKUP_PATH
|
||
|
|
||
|
cd $BACKUP_PATH
|
||
|
ls -tr | head -n -$NUMB_BACKUPS_TO_KEEP | xargs --no-run-if-empty rm
|
||
|
|
||
|
mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE > $BACKUP_PATH/$BACKUP_NAME
|
||
|
```
|
||
|
|
||
|
* **files backup**</br>
|
||
|
script `make_backup.sh` placed in to `bookstack` container,
|
||
|
in to `/config` directory that is bind mounted to the host machine.</br>
|
||
|
made executable `chmod +x make_backup.sh` inside the container
|
||
|
|
||
|
- This script creates path `/config/backups-files`</br>
|
||
|
- deletes all files in the backup path except 30 newest</br>
|
||
|
- creates new archive containing uploaded files</br>
|
||
|
|
||
|
`make_backup.sh`
|
||
|
```
|
||
|
#!/bin/bash
|
||
|
|
||
|
# -----------------------------------------------
|
||
|
NUMB_BACKUPS_TO_KEEP=30
|
||
|
BACKUP_PATH=/config/backups-files
|
||
|
BACKUP_NAME=$(date +"%s").bookstack.files.backup.tar.gz
|
||
|
# -----------------------------------------------
|
||
|
|
||
|
mkdir -p $BACKUP_PATH
|
||
|
|
||
|
cd $BACKUP_PATH
|
||
|
ls -tr | head -n -$NUMB_BACKUPS_TO_KEEP | xargs --no-run-if-empty rm
|
||
|
|
||
|
cd /config/www
|
||
|
tar -czvf $BACKUP_PATH/$BACKUP_NAME .env uploads files images
|
||
|
```
|
||
|
|
||
|
* **automatic periodic execution of the backup scripts**
|
||
|
|
||
|
Using cron running on the host machine that will execute scripts inside containers.
|
||
|
|
||
|
script `cron_job_do_backups.sh` inside `~/docker/bookstack`
|
||
|
|
||
|
`cron_job_do_backups.sh`
|
||
|
```
|
||
|
#!/bin/bash
|
||
|
|
||
|
docker exec bookstack /config/make_backup.sh
|
||
|
docker exec bookstack_db /config/make_backup.sh
|
||
|
```
|
||
|
|
||
|
`chmod +x cron_job_do_backups.sh` on the host machine
|
||
|
|
||
|
`crontab -e`
|
||
|
|
||
|
`0 2 * * * /home/bastard/docker/bookstack/cron_job_do_backups.sh`
|
||
|
|
||
|
### restore official way
|
||
|
|
||
|
* restore of the database
|
||
|
|
||
|
copy the backup sql dump file in to the bind mount `bookstack-data-db` directory
|
||
|
|
||
|
exec in to the container and tell mariadb to restore data from the copied file
|
||
|
|
||
|
`docker exec -it bookstack_db /bin/bash`</br>
|
||
|
`cd /config`</br>
|
||
|
`mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE < 1584566634.bookstack.database.backup.sql`
|
||
|
|
||
|
* restore of the files
|
||
|
|
||
|
copy the backup gz.tar archive in to bind mount `bookstack-data/www/` directory</br>
|
||
|
|
||
|
`docker exec -it bookstack /bin/bash`</br>
|
||
|
`cd /config/www`</br>
|
||
|
`tar -xvzf 1584566633.bookstack.files.backup.tar.gz`
|