User Tools

Site Tools


dokuwiki:pikvm:setup_on_pikvm

Setup DokuWiki on a PiKVM

PiKVM is a specialized RaspberryPi 4 appliance for remote controlling one or more computers over the internet.

It makes sense to leave a RaspberryPi 4 running 24×7 but shutdown a much more power hungry computer for example a TrueNAS.

It is possible to extend the PiKVM main menu with more services. It is also not very hard to add PHP to the Arch Linux ARM that powers PiKVM.

PiKVM uses nginx as the web server that acts as a switch in front of the different services that make up PiKVMs remote control capability.

Readonly root and DokuWiki settings

Usually the root filesystem and with that the /etc folder is read only. The way DokuWiki is installed by defualt on Arch Linux this means that the configuration settings including the users for the wiki are can not be changed without executing some additional commands:

rw
# This alone is not enough, the php interpreter still thinks the conf directory is read only
systemctl restart php-legacy-fpm kvmd-nginx
# Change settings or add user
ro

Install php-legacy-fpm

dokuwiki uses php, not the very latest version, together with nginx this is php-legacy-fpm.

rw
pacman -S php-legacy-fpm dokuwiki
systemctl enable php-legacy-fpm
# Created symlink /etc/systemd/system/multi-user.target.wants/php-fpm-legacy.service -> /usr/lib/systemd/system/php-fpm-legacy.service.
systemctl start php-legacy-fpm

Configuration

cd /etc/php-legacy/

total 88
drwxr-xr-x 2 root root  4096 Jan 16 22:58 conf.d
drwxr-xr-x 2 root root  4096 Apr 11 15:38 php-fpm.d
-rw-r--r-- 1 root root  5331 Apr 11 16:09 php-fpm.conf
-rw-r--r-- 1 root root 72933 Apr  3 06:02 php.ini

We want to prepare php-fpm for larger file uploads than configured by default: nano /etc/php-legacy/php.ini

[...]
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
[...]
; Maximum allowed size for uploaded files.
; https://php.net/upload-max-filesize
upload_max_filesize = 50M
[...]
;;;;;;;;;;;;;;;;;
; Data Handling ;
;;;;;;;;;;;;;;;;;
[...]
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; https://php.net/post-max-size
post_max_size = 50M

nano /etc/php-legacy/php-fpm.d/www.conf

Check the users at the top of the file: The user for every file php has to work with is http, the user for the socket is different: kvmd-nginx You need to change

listen.owner = kvmd-nginx
listen.group = kvmd-nginx
; Start a new pool named 'www'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
[www]

; Per pool prefix
; It only applies on the following directives:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of the child processes. This can be used only if the master
; process running user is root. It is set after the child process is created.
; The user and group can be specified either by their name or by their numeric
; IDs.
; Note: If the user is root, the executable needs to be started with
;       --allow-to-run-as-root option to work.
; Default Values: The user is set to master process running user by default.
;                 If the group is not set, the user's group is used.
user = http
group = http

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm-legacy/php-fpm.sock

; Set listen(2) backlog.
; Default Value: 511 (-1 on FreeBSD and OpenBSD)
;listen.backlog = 511

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. The owner
; and group can be specified either by name or by their numeric IDs.
; Default Values: Owner is set to the master process running user. If the group
;                 is not set, the owner's group is used. Mode is set to 0660.
listen.owner = kvmd-nginx
listen.group = kvmd-nginx
;listen.mode = 0660

Also we need to relax a security mechanism in sysetmd that php-legacy-fpm uses:

export EDITOR=/usr/bin/nano
# else the editor will be vim. Use i to enter insert mode, make the changes, ESC, :x
systemctl edit php-legacy-fpm.service
### Editing /etc/systemd/system/php-fpm-legacy.service.d/override.conf
### Anything between here and the comment below will become the contents of the drop-in file
 
[Service]
ProtectSystem=true
 
### Edits below this comment will be discarded
 
### /usr/lib/systemd/system/php-fpm-legacy.service
# # It's not recommended to modify this file in-place, because it
# # will be overwritten during upgrades.  If you want to customize,
# # the best way is to use the "systemctl edit" command.
#
# [Unit]
# Description=The PHP FastCGI Process Manager
[...]
# # Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit.
# ProtectSystem=full

Successfully installed edited file '/etc/systemd/system/php-fpm-legacy.service.d/override.conf'.

Storing the data on some other device than the SD card

You can format and mount any device Linux and the Raspberry Pi can talk to (USB keys, external USB drives, network filesystems). DokuWiki is set up on ArchLinux to use /var/lib/dokuwiki to store any data that is not part of its core code like data and plugins for add ons and tpl for different looks.

So for example we can attach an USB key and format it using ext4. Then we mount it at a temporary location and move the contents of /var/lib/dokuwiki there. When we have moved everything we then can mount the USB key to /var/lib/dokuwiki and making this permanent in /etc/fstab

fdisk /dev/sda

Welcome to fdisk (util-linux 2.38.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.


Command (m for help): p

Disk /dev/sda: 7.5 GiB, 8053063680 bytes, 15728640 sectors
Disk model: USB DISK        
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: AAE09444-894D-4F1F-AD63-B413B8D6B5F2

Device     Start      End  Sectors  Size Type
/dev/sda1   2048 15728606 15726559  7.5G Microsoft basic data

Command (m for help): q
mkfs.ext4 /dev/sda1
# in the next steps replace a5c127c4-439a-4ab4-97c2-27c4910036c5 with the UUID value of the output of mkfs.ext4
lsblk -o NAME,SIZE,RO,TYPE,LABEL,UUID,MOUNTPOINTS
NAME         SIZE RO TYPE LABEL  UUID                                 MOUNTPOINTS
sda          7.5G  0 disk                                             
`-sda1       7.5G  0 part        a5c127c4-439a-4ab4-97c2-27c4910036c5 
mmcblk0     14.8G  0 disk                                             
|-mmcblk0p1  256M  0 part PIBOOT BE9C-7C3A                            /boot
|-mmcblk0p2  256M  0 part PIPST  8ac2bdd9-4be5-4ed2-a352-9d6a6458248d /var/lib/kvmd/pst
|-mmcblk0p3    6G  0 part PIROOT e9d84664-4af4-49e2-b4eb-926a6679afcf /
`-mmcblk0p4  8.3G  0 part PIMSD  0edfeabf-57a0-4f74-9160-bdc4234a4246 /var/lib/kvmd/msd
mount UUID=a5c127c4-439a-4ab4-97c2-27c4910036c5 /mnt
mv /var/lib/dokuwiki/* /mnt
umount /mnt
nano /etc/fstab
[...]
LABEL=PIPST /var/lib/kvmd/pst  ext4  nodev,nosuid,noexec,ro,errors=remount-ro,data=journal,X-kvmd.pst-user=kvmd-pst  0 0
LABEL=PIMSD /var/lib/kvmd/msd  ext4  nodev,nosuid,noexec,ro,errors=remount-ro,data=journal,X-kvmd.otgmsd-user=kvmd  0 0
# add the following line here
UUID=a5c127c4-439a-4ab4-97c2-27c4910036c5 /var/lib/dokuwiki ext4  nodev,nosuid,noexec,rw,errors=remount-ro,data=journal 0 0
systemctl daemon-reload
mount /var/lib/dokuwiki

Integrate with the pikvm UI

mkdir -p /usr/share/kvmd/extras/dokuwiki (or cd)

Two files: nano /usr/share/kvmd/extras/dokuwiki/manifest.yaml

name: DokuWiki
description: A DokuWiki instance
icon: dokuwiki/lib/tpl/dokuwiki/images/logo.png
path: dokuwiki
daemon: kvmd-webterm
place: 10

nano /usr/share/kvmd/extras/dokuwiki/nginx.ctx-server.conf

        #Remember to comment the below out when you are installing DokuWiki, and uncomment it when you are done.
        location ~ (data/|conf/|bin/|inc/|install.php) {          
          deny all; 
        } # secure Dokuwiki
 
#        location ~ \.ht { deny all; } # also secure the Apache .htaccess files
 
#        location @dokuwiki {
#            root /usr/share/webapps;
#            #rewrites "doku.php/" out of the URLs if you set the userewrite setting to .htaccess in dokuwiki config page
#            rewrite ^/dokuwiki/_media/(.*) /dokuwiki/lib/exe/fetch.php?media=$1 last;
#            rewrite ^/dokuwiki/_detail/(.*) /dokuwiki/lib/exe/detail.php?media=$1 last;
#           rewrite ^/dokuwiki/_export/([^/]+)/(.*) /dokuwiki/doku.php?do=export_$1&id=$2 last;
#            rewrite ^/dokuwiki/(.*) /dokuwiki/doku.php?id=$1&$args last;
#        }
 
        location = /dokuwiki {
           return 301 /dokuwiki/;
        }
 
        location /dokuwiki/ {
          root /usr/share/webapps;
          index doku.php;
#          try_files $uri $uri/ @dokuwiki;
        }
 
        # Allow larger uploads (e.g. 50 MB)
        client_max_body_size 50m;
 
        location ~ \.php$ {
            root /usr/share/webapps;
            try_files $uri =404;
 
            # default fastcgi_params
            include /etc/nginx/fastcgi_params;
 
            # fastcgi settings
            fastcgi_pass unix:/run/php-fpm-legacy/php-fpm.sock;
            fastcgi_index                       index.php;
            fastcgi_buffers                     8 16k;
            fastcgi_buffer_size         32k;
 
            # fastcgi params
            fastcgi_param DOCUMENT_ROOT         $realpath_root;
            fastcgi_param SCRIPT_FILENAME       $realpath_root$fastcgi_script_name;
            include /etc/nginx/fastcgi.conf;
        }

For using install.php to setup dokuwiki change the deny all location ~  to

        #Remember to comment the below out when you are installing DokuWiki, and uncomment it when you are done.
        location ~ (data/|conf/|bin/|inc/) {
        #|install.php) {          
          deny all; 
        } # secure Dokuwiki
systemctl restart php-legacy-fpm kvmd-nginx

Now you can open https://pikvm/dokuwiki/install.php

dokuwiki/pikvm/setup_on_pikvm.txt · Last modified: by 127.0.0.1