Install and Configure Wiki.js on Kubernetes Cluster

Posted on 237 views

Normally, when the term Wiki is mentioned, the first thing that comes in the mind is wikipedia.org. There is a difference between the two, Wikipedia is just a website that adheres to the Wiki format while a wiki is defined as software built to help ease collaborative writing and editing for teams. It also offers a productive writing environment with a set of management tools for managers and moderators. Wiki has been in existence for a long time with popular wiki engines such as MediaWiki, PmWiki, TiddlyWiki, Wikkawiki, and DokuWiki.

Amongst the many wiki engines, exists an open-source wiki engine with NodeJS technologies known as Wiki.js. This is a fully customizable wiki engine written in JavaScript. This open-source wiki engine is released under the Affero GNU General Public License.

Wiki.js is an amazingly fast web application with support for many databases interface with primary support for PostgreSQL. Wiki.js is preferred due to the following amazing features:

  • Full version and revision control.
  • Fairly easy to use.
  • Seamless Media Assets Management.
  • Multi-lingual content support with full support for RTL languages like: Arabic, Hebrew and Persian.
  • It has a search functionality as a built-in feature.
  • Supports comments.
  • Git-backed storage.
  • It offers full support for content backup and synchronization for multi-vendors like Google Drive, AWS S3, Box.net,Dropbox, Microsoft OneDrive and DigitalOcean Spaces.
  • Integrated access control.
  • Assets management – media content can be inserted into content.

By the end of this guide, you should be able to install and configure Wiki.js on Kubernetes Cluster.

Getting Started

For this guide, you will need a Kubernetes cluster set up. We have dedicated guides on how to set up a Kubernetes cluster.

With your Kubernetes cluster set up, proceed as below.

Install and Configure Wiki.js on Kubernetes Cluster

Install and configure Wiki.js on Kubernetes Cluster on your system with the aid of the below steps.

Step 1 – Create the Wiki.js Namespace

Normally, a namespace is used to partition a single Kubernetes cluster into many virtual clusters. Begin by creating the namespace for wiki.js as below.

kubectl create namespace wikijs

Verify the namespace exists.

$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   98s
kube-node-lease   Active   99s
kube-public       Active   99s
kube-system       Active   99s
wikijs            Active   11s

Step 2 – Create the Secrets file

The secret file contains the username and passwords to be created for the below database.

Generate your own credentials for theROOT, ROOT_PASSWORD, DATABASE, USER variables. See below examples

# MySQL root user
$ echo -n 'root' | base64
cm9vdA==

# MySQL root user password
$ echo -n 'StrongRootPassword' | base64
U3Ryb25nUm9vdFBhc3N3b3Jk

# Wiki.js MySQL database name
$ echo -n 'wikijs' | base64
d2lraWpz

# Wiki.js MySQL user
$ echo -n 'wikijs' | base64
d2lraWpz

# Wiki.js MySQL user Password
$ echo -n 'WikijsUserPassw0rd' | base64
V2lraWpzVXNlclBhc3N3MHJk

Now create a secret file as below.

vim wikijs-secret.yaml

In the file, add the below lines replacing appropriately.

apiVersion: v1
kind: Secret
metadata:
  name: mariadb-secret
  namespace: wikijs
type: Opaque
data:
  ROOT: cm9vdA==
  ROOT_PASSWORD: U3Ryb25nUm9vdFBhc3N3b3Jk
  DATABASE: d2lraWpz
  USER: d2lraWpz
  PASSWORD: V2lraWpzVXNlclBhc3N3MHJk

Apply the made changes.

kubectl apply -f wikijs-secret.yaml

Verify if your change is made.

$ kubectl get secret -n wikijs
NAME                  TYPE                                  DATA   AGE
default-token-pb9fx   kubernetes.io/service-account-token   3      7m9s
mariadb-secret        Opaque                                5      6s

Step 3 – Create the Database Pod for wiki.js

This config file contains the database details for wiki.js. In this guide, we will use the MariaDB database which can be configured as below.

Option 1: Using Persistent Volume with StorageClass (Recommended)

For configuration of Kubernetes PV Storage solution refer to guides in the following links:

List available Storage Classes configured in your Kubernetes

$ kubectl get storageclasses
NAME              PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com      Delete          Immediate           true                   211d
rook-cephfs       rook-ceph.cephfs.csi.ceph.com   Delete          Immediate           true                   211d

Let’s create PV Claim for Wiki.js Database

$ vim wikijs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: wikijs-pv-claim
  namespace: wikijs
spec:
  storageClassName: rook-cephfs 
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

# Apply manifest
$ kubectl apply -f wikijs-pvc.yaml

Confirm PVC is created and available

$ kubectl get pvc -n wikijs
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wikijs-pv-claim   Bound    pvc-fdee5351-7a84-4823-9e6c-9cf9a6aabccc   10Gi       RWO            rook-cephfs    23s

Create the wikijs-config.yaml file as below.

vim wikijs-config.yaml 

Paste contents below into the file:

---
apiVersion: v1
kind: Service
metadata:
  name: mariadb
  namespace: wikijs
spec:
  selector:
    app: mariadb
  ports:
  - name: mariadb
    protocol: TCP
    port: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb
  namespace: wikijs
  labels:
    app: mariadb
spec:
  selector:
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
      - name: mariadb
        image: mariadb:latest
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: DATABASE
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: USER
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: PASSWORD
        - name: MARIADB_ROOT_HOST
          value: "%"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: wikijs-db
          mountPath: /var/lib/mysql
      volumes:
      - name: wikijs-db
        persistentVolumeClaim:
          claimName: wikijs-pv-claim

Apply configuration file using the commands below

$ kubectl apply -f wikijs-config.yaml -n wikijs
service/mariadb created
deployment.apps/mariadb created

Confirm Pod is running:

$ kubectl get deployment -n wikijs
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
mariadb   1/1     1            1           5m20s

$ kubectl get pods -n wikijs
NAME                      READY   STATUS    RESTARTS   AGE
mariadb-75cc6d696-tw4ld   1/1     Running   0          5m27s

Option 2: Using hostPath for data persistence (Note recommended)

You will require to create a storage volume for MariaDB

sudo mkdir /var/wikijs

Create the wikijs-config.yaml file as below.

vim wikijs-config.yaml 

In the file, add the below lines. Here do not alter anything.

---
apiVersion: v1
kind: Service
metadata:
  name: mariadb
  namespace: wikijs
spec:
  selector:
    app: mariadb
  ports:
  - name: mariadb
    protocol: TCP
    port: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb
  namespace: wikijs
  labels:
    app: mariadb
spec:
  selector:
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
      - name: mariadb
        image: mariadb:latest
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: DATABASE
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: USER
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: PASSWORD
        - name: MARIADB_ROOT_HOST
          value: "%"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mariadb-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mariadb-storage
        hostPath:
          path: /var/wikijs
          type: DirectoryOrCreate

Remember under DB_TYPE, you can set the type of database you want to use i.e. Postgres, MySQL, MariaDB, MsSQL, SQLite e.t.c

Apply the settings made.

kubectl apply -f wikijs-config.yaml

Verify if the MariaDB pod has been created.

$ kubectl get pod -n wikijs
NAME                      READY   STATUS    RESTARTS   AGE
mariadb-6f9ddfd55c-55rzq   1/1     Running            0             15s

Step 4 – Deploy the Wiki.js Service and application

Here, we can deploy the service as a NodePort, ClusterIP, or load balancer. First, create the file

vim wikijs-service.yaml

For Nodeport add the below lines.

apiVersion: v1
kind: Service
metadata:
  name: "wikijs"
  namespace: wikijs
spec:
  type: NodePort
  ports:
    - name: http
      port: 3000
  selector:
    app: "wikijs"

For this guide, we will deploy the service as NodePort for the cluster to be accessed from outside.

kubectl apply -f wikijs-service.yaml

Verify this.

$ kubectl get svc -n wikijs
NAME     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
mariadb   ClusterIP   10.96.123.37             3306/TCP         29s
wikijs   NodePort   10.100.116.117           3000:31694/TCP   5s

Printing Node Port value only

$ kubectl get service wikijs -o jsonpath='.spec.ports[0].nodePort'; echo
31665

Now proceed to the wiki.js deployment.

vim wikijs-deployment.yaml

In the file, add the below lines, here don’t replace anything, we are simply mapping the above configs.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wikijs
  namespace: wikijs
  labels:
    app: wikijs
spec:
  selector:
    matchLabels:
      app: wikijs
  template:
    metadata:
      labels:
        app: wikijs
    spec:
      containers:
      - name: wikijs
        image: requarks/wiki:latest
        imagePullPolicy: Always
        env:
        - name: DB_TYPE
          value: "mariadb"
        - name: DB_HOST
          value: "mariadb"
        - name: DB_PORT
          value: "3306"
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: DATABASE
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: USER
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: PASSWORD
        ports:
        - containerPort: 3000
          name: http

We have mapped the ConfigMap and secret variables to the deployment and also pulled the official wiki.js docker image.

Now apply the made changes.

kubectl apply -f wikijs-deployment.yaml

Get the deployment.

$ kubectl get deploy -n wikijs
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
mariadb   1/1     1            1           115s
wikijs    1/1     1            1           14m

Get the wiki.js pod.

$ kubectl get pods -n wikijs
NAME                       READY   STATUS    RESTARTS     AGE
mariadb-6f9ddfd55c-55rzq   1/1     Running   0            2m39s
wikijs-548dcdd86c-tzp4f    1/1     Running   1 (5s ago)   93s

As seen we have two pods running successfully. One for the database and the other for the wiki.js service. We can check logs to ensure Database connection is okay

$ kubectl logs deploy/wikijs
Loading configuration from /wiki/config.yml... OK
2022-05-17T16:41:59.475Z [MASTER] info: =======================================
2022-05-17T16:41:59.479Z [MASTER] info: = Wiki.js 2.5.282 =====================
2022-05-17T16:41:59.479Z [MASTER] info: =======================================
2022-05-17T16:41:59.479Z [MASTER] info: Initializing...
2022-05-17T16:42:01.704Z [MASTER] info: Using database driver mysql2 for mariadb [ OK ]
2022-05-17T16:42:01.748Z [MASTER] info: Connecting to database...
2022-05-17T16:42:02.075Z [MASTER] info: Database Connection Successful [ OK ]

Obtain the port to which the NodePort service has been exposed.

$ kubectl get svc -n wikijs
mariadb   ClusterIP   10.96.123.37             3306/TCP         67s
wikijs    NodePort    10.104.156.51           3000:31694/TCP   22s

Manually granting permissions on MySQL CLI

In case of any database access issues like below:

2022-05-17T16:33:04.998Z [MASTER] error: Database Connection Error: ER_ACCESS_DENIED_ERROR undefined:undefined
2022-05-17T16:33:04.999Z [MASTER] warn: Will retry in 3 seconds... [Attempt 1 of 10]

You can access MariaDB pod shell and grant permissions

$ kubectl exec -ti deploy/mariadb -- bash
[email protected]:/# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 56
Server version: 10.6.7-MariaDB-1:10.6.7+maria~focal mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Create user and grant permissions:

CREATE USER 'wikijs'@'%' IDENTIFIED BY 'WikijsUserPassw0rd';
GRANT ALL PRIVILEGES ON *.* TO 'wikijs'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;

Validate user grants on the database:

MariaDB [(none)]> SELECT host, user FROM mysql.user;
+-------------------------+-------------+
| Host                    | User        |
+-------------------------+-------------+
| %                       | wikijs      |
| 127.0.0.1               | root        |
| ::1                     | root        |
| localhost               | mariadb.sys |
| localhost               | root        |
| mariadb-bc4b6f568-xsb92 | root        |
+-------------------------+-------------+
7 rows in set (0.002 sec)
MariaDB [(none)]> EXIT
Bye

Validate connectivity works

[email protected]:/# mysql -u wikijs -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 31
Server version: 10.6.7-MariaDB-1:10.6.7+maria~focal mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.025 sec)

MariaDB [(none)]> EXIT
Bye

Step 5 – Access the wiki.js Web UI.

At this point, we can access the wiki.js service from the browser with the URL http://IP_Address:31694. Remember to replace the port with your own NodePort.

You should be able to see this page:

1

Fill in the required details for account creation and proceed with wiki.js installation.

a7022b90e7dbafdc63023da4cbc9a1ec94a01804_2_545x500

When complete, you will be redirected to the login window.

On successful login, you will see this wiki.js welcome notification.

Proceed and create your wiki.js content.

How-To-Install-and-Configure-Wiki.js-on-Kubernetes-Cluster-4-1024x514

That was enough learning! I hope you too benefitted from this guide on how to install and Configure Wiki.js on Kubernetes Cluster.

coffee

Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.