Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 51 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
# ns8-bookstack

This is a NS8 App for [Bookstack](https://www.bookstackapp.com/).
# NS8 Bookstack

This is an NS8 application for [Bookstack](https://www.bookstackapp.com/), a free and open source Wiki designed for teams.

## Install

Instantiate the module with:

add-module ghcr.io/compgeniuses/bookstack:latest 1
add-module ghcr.io/geniusdynamics/bookstack:latest 1

The output of the command will return the instance name.
Output example:

{"module_id": "bookstack1", "image_name": "bookstack", "image_url": "ghcr.io/compgeniuses/bookstack:latest"}
{"module_id": "bookstack1", "image_name": "bookstack", "image_url": "ghcr.io/geniusdynamics/bookstack:latest"}

## Default Credentials
Initial Login Credetials for boockstack
- `USername`: admin@admin.com

Initial Login Credentials for Bookstack

- `Username`: admin@admin.com
- `Password`: password

## Configure

Let's assume that the mattermost instance is named `bookstack1`.
Let's assume that the bookstack instance is named `bookstack1`.

Launch `configure-module`, by setting the following parameters:

- `host`: a fully qualified domain name for the application
- `http2https`: enable or disable HTTP to HTTPS redirection (true/false)
- `lets_encrypt`: enable or disable Let's Encrypt certificate (true/false)


Example:

```
Expand All @@ -41,27 +43,40 @@ EOF
```

The above command will:

- start and configure the bookstack instance
- configure a virtual host for trafik to access the instance
- configure a virtual host for Traefik to access the instance

## Get the configuration

You can retrieve the configuration with

```
api-cli run get-configuration --agent module/bookstack1
```

## Update Module

```bash
api-cli run update-module --data '{
"module_url": "ghcr.io/geniusdynamics/bookstack:latest",
"instances": ["bookstack1"],
"force": true
}'

```

## Uninstall

To uninstall the instance:

remove-module --no-preserve bookstack1

## Smarthost setting discovery
## Smarthost Setting Discovery

Some configuration settings, like the smarthost setup, are not part of the
`configure-module` action input: they are discovered by looking at some
Redis keys. To ensure the module is always up-to-date with the
Redis keys. To ensure the module is always up-to-date with the
centralized [smarthost
setup](https://nethserver.github.io/ns8-core/core/smarthost/) every time
bookstack starts, the command `bin/discover-smarthost` runs and refreshes
Expand All @@ -78,36 +93,41 @@ expected to work: it can be rewritten or discarded completely.

## Debug

some CLI are needed to debug
Some CLI commands are needed to debug the module:

- The module runs under an agent that initiates a lot of environment variables (in `/home/bookstack1/.config/state`), it could be useful to verify them on the root terminal:

`runagent -m bookstack1 env`

- The module runs under an agent that initiate a lot of environment variables (in /home/bookstack1/.config/state), it could be nice to verify them
on the root terminal
- You can become runagent for testing scripts and initiate all environment variables:

`runagent -m bookstack1 env`
`runagent -m bookstack1`

- you can become runagent for testing scripts and initiate all environment variables

`runagent -m bookstack1`
The path becomes:

the path become :
```
echo $PATH
/home/bookstack1/.config/bin:/usr/local/agent/pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/
```

- if you want to debug a container or see environment inside
`runagent -m bookstack1`
```
- If you want to debug a container or see environment inside:

`runagent -m bookstack1`

Then you can run:

```
podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d292c6ff28e9 localhost/podman-pause:4.6.1-1702418000 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp 80b8de25945f-infra
d8df02bf6f4a docker.io/library/mariadb:10.11.5 --character-set-s... 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp mariadb-app
9e58e5bd676f docker.io/library/nginx:stable-alpine3.17 nginx -g daemon o... 9 minutes ago Up 9 minutes 127.0.0.1:20015->80/tcp bookstack-app
```

you can see what environment variable is inside the container
You can see what environment variables are inside the container:

```
podman exec bookstack-app env
podman exec bookstack-app env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TERM=xterm
PKG_RELEASE=1
Expand All @@ -124,18 +144,18 @@ MARIADB_DB_PORT=3306
HOME=/root
```

you can run a shell inside the container
You can run a shell inside the container:

```
podman exec -ti bookstack-app sh
/ #
podman exec -ti bookstack-app sh
/ #
```

## Testing

Test the module using the `test-module.sh` script:


./test-module.sh <NODE_ADDR> ghcr.io/compgeniuses/bookstack:latest
./test-module.sh <NODE_ADDR> ghcr.io/geniusdynamics/bookstack:latest

The tests are made using [Robot Framework](https://robotframework.org/)

Expand All @@ -146,4 +166,4 @@ Translated with [Weblate](https://hosted.weblate.org/projects/ns8/).
To setup the translation process:

- add [GitHub Weblate app](https://docs.weblate.org/en/latest/admin/continuous.html#github-setup) to your repository
- add your repository to [hosted.weblate.org]((https://hosted.weblate.org) or ask a compgeniuses developer to add it to ns8 Weblate project
- add your repository to [hosted.weblate.org](https://hosted.weblate.org) or ask a NethServer developer to add it to the ns8 Weblate project
2 changes: 1 addition & 1 deletion build-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ images=()
repobase="${REPOBASE:-ghcr.io/geniusdynamics}"
# Configure the image name
reponame="bookstack"
BOOKSTACK_TAG="25.07.1"
BOOKSTACK_TAG="25.12.8"
# Create a new empty container image
container=$(buildah from scratch)

Expand Down
30 changes: 13 additions & 17 deletions imageroot/actions/configure-module/10configure_environment_vars
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,30 @@
#

import json
import os
import sys
import agent
import base64

# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
data = json.load(sys.stdin)

host = data.get("host", "")
port = data.get("TCP_PORT", "")
url = host + ":" + port

APP_URL = "https://" + host
agent.write_envfile("app.env", {"APP_URL": APP_URL})
# This is specific to you module, so you need to change it accordingly.
# we read a json stdin {"vars1":true, "var2":"foo", "vars3": 3} and we writ it to .config/state/environment
# Upper case to set environment variable and minor case to read from stdin

# this values must exists in the json stdin
# agent.set_env("MAIL_SERVER", data["mail_server"])
# agent.set_env("LDAP_DOMAIN", data["ldap_domain"])
def generate_laravel_app_key():
key = os.urandom(32) # 32 bytes for AES-256
return "base64:" + base64.b64encode(key).decode("utf-8")


# you can add default values for the following variables
# agent.set_env("MAIL_DOMAIN",data.get("mail_domain",""))
# agent.set_env("WOWORKERSCOUNT",data.get("workers_count",3))
# agent.set_env("AUXILIARYACCOUNT",data.get("auxiliary_account",True))
# agent.set_env("ACTIVESYNC",data.get("activesync",False))
if os.path.exists("app-db.env"):
dt = agent.read_envfile("app-db.env")
APP_KEY = dt.get("APP_KEY", generate_laravel_app_key())
else:
APP_KEY = generate_laravel_app_key()

APP_URL = "https://" + host
agent.write_envfile("app.env", {"APP_URL": APP_URL, "APP_KEY": APP_KEY})

# Make sure everything is saved inside the environment file
# just before starting systemd unit
# agent.dump_env()
13 changes: 11 additions & 2 deletions imageroot/actions/create-module/10configure_vars
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import json
import sys
import agent
import os
import base64

# Try to parse the stdin as JSON.
# If parsing fails, output everything to stderr
Expand All @@ -23,6 +24,13 @@ def generate_random_password(length):
return password[:length]


def generate_laravel_app_key():
key = os.urandom(32) # 32 bytes for AES-256
return "base64:" + base64.b64encode(key).decode("utf-8")


APP_KEY = generate_laravel_app_key()

MARIADB_ROOT_PASSWORD = generate_random_password(16)
MARIADB_DATABASE = data.get("MARIADB_DATABASE", "bookstack")
MARIADB_USER = data.get("MARIADB_USER", "bookstack")
Expand All @@ -39,9 +47,10 @@ maria_db = {
app = {
"DB_HOST": "mariadb-app",
"DB_PORT": "3306",
"DB_USER": MARIADB_USER,
"DB_PASS": MARIADB_PASSWORD,
"DB_USERNAME": MARIADB_USER,
"DB_PASSWORD": MARIADB_PASSWORD,
"DB_DATABASE": MARIADB_DATABASE,
"APP_KEY": generate_random_password(64),
}

agent.write_envfile("database.env", maria_db)
Expand Down
2 changes: 1 addition & 1 deletion imageroot/systemd/user/mariadb-app.service
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ExecStart=/usr/bin/podman run --conmon-pidfile %t/mariadb-app.pid \
--pod-id-file %t/bookstack.pod-id --replace -d --name mariadb-app \
--env-file=%S/state/database.env \
--volume mysql-data:/var/lib/mysql/:Z \
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
${MARIADB_IMAGE}
ExecStartPost=/usr/bin/podman exec mariadb-app /bin/bash -c 'printf "[client] \npassword=${MARIADB_ROOT_PASSWORD}" > /root/.my.cnf'
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/mariadb-app.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/mariadb-app.ctr-id
Expand Down
17 changes: 17 additions & 0 deletions imageroot/update-module.d/migrate_vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env python3

#
# Copyright (C) 2022 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import os
import agent

if os.path.exists("app-db.env"):
dt = agent.read_envfile("app-db.env")
if "DB_USERNAME" not in dt and "DB_USER" in dt:
dt["DB_USERNAME"] = dt.pop("DB_USER")
if "DB_PASSWORD" not in dt and "DB_PASS" in dt:
dt["DB_PASSWORD"] = dt.pop("DB_PASS")
agent.write_envfile("app-db.env", dt)
Loading