Running sites on different versions of PHP on the same server

Thsi quick guide explains the steps needed to be able to run different versions of PHP on the same server (different virtual hosts or even different folders within the same site).


If the ‘add-apt-repository’ command is missing, you need to install the package “software-properties-common” first:

apt install -y software-properties-common

Add the ondrej/php repository to your system:

add-apt-repository ppa:ondrej/php

apt update:

apt update

Install Apache fastCGI module:

apt install -y libapache2-mod-fcgid

For each version of PHP

As of 1 Jan 2021, PHP versions 7.4 (php7.4) and 8.0 (php8.0) are those with active support and updates. PHP version 7.3 (php7.3) will continue to receive critical updates until 1 Jan 2022. See Supported PHP Versions.

Install required packages

apt install -y php7.4 php7.4-fpm php7.4-mysql libapache2-mod-php7.4

Install other wanted modules for the same PHP version, for example these commonly used:

apt-install -y php7.4-curl, php7.4-gd, php7.4-intl, php7.4-json, php7.4-mbstring, php7.4-readline

Start the php-fpm service:

systemctl start php7.4-fpm

Check that the service is running:

systemctl status php7.4-fpm

Configuring PHP version for virtual host or subfolder

Activate necessary Apache modules and restart Apache:

a2enmod actions fcgid alias proxy_fcgi
systemctl restart apache2

Use FilesMatch directive to set the PHP version:
FilesMatch is valid in both the virtualhost configuration and inside a Directory section.
To set PHP version globally for a virtual host, use it outside a Directory section.
The default PHP version can be set using ‘a2enmod php8.0’ (or any other version)

<FilesMatch \.php$>
  SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"

Check the configuration for errors:

apachectl configtest

If result is “Syntax OK”, restart Apache:

systemctl restart apache2


Create a file named ‘i.php’ in the locations with the different PHP versions (can be different virtualhosts or folders)


Access these locations on the virtualhosts or their directory locations to verify that they are using different PHP versions.


Most useful resource for this guide
How To Run Multiple PHP Versions on One Server Using Apache and PHP-FPM on Ubuntu 18.04 (DigitalOcean Community)

Linux: how to run commands by keypress on the local console

This is probably not the only way to do this, and just something I had to dig up to be able to control the piStorm from the console keyboard without being logged in.

After trying to find some built-in way of doing it, I ended up using ‘lirc’ (‘inputlircd’) to fetch the keystrokes and execute appropriate commands in the background. The guide is not intended to be complete, and it’s not even re-tested because of the trial-and-error attempt on getting this working the first time, and not taking any notes.

The most useful resource for the success was:
How to run script on keypress? (

Required steps to getting started with lirc

Become root

sudo su -

Install required packages:

apt -y install lirc inputlirc input-utils socat

Find the input device you wish to capture keypresses from:


The not really necessary step
Examine the inputlirc start/stop script “/etc/init.d/inputlirc” to see where it looks for configuration:


test -x $DAEMON || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME

The marked lines in the partial content of “/etc/init.d/inputlirc” reveals that a file “/etc/default/inputlirc” is sourced.

Change startup parameters for inputlircd
“/etc/default/inputlirc” contains parameters for running inputlircd, including the input device to capture events from and the parameters to the service looking for keystrokes.

Read the inputlircd manpage (man 8 inputlircd) to find out which parameters you need/want to use. The below is what I had to put in the file:

# Options to be passed to inputlirc.
OPTIONS=-m 0 -c

-m 0 = -m sets the lowest keycode to pass to the daemon
I also use -c to allow to capture the modifier keys (CTRL, SHIFT, ALT) so they will be part of a keystroke instead of generating their own events. This will make it possible to use combinations like SHIFT + F1 for command execution.

After editing and saving the file, enable and (re)start the inputlirc service:

systemctl enable inputlirc
systemctl restart inputlirc

Then check that it’s running:

systemctl status inputlirc

Snooping for keypress events
Unless you know all the keycodes you are going to use for running commands, now is a good time to check what lircd receives on specific keypresses. Run the command to snoop for keypresses in the shell, and press keys on the keyboard connected to the computer (this could be connected through USB, PS/2, Bluetooth, IR, whatever)

socat UNIX-CONNECT:/var/run/lirc/lircd STDOUT

Sample output (F12 and modifier keys)

root@raspberrypi:~# socat UNIX-CONNECT:/var/run/lirc/lircd STDOUT
58 0 SHIFT_KEY_F12 /dev/input/event0
58 0 CTRL_SHIFT_KEY_F12 /dev/input/event0

The irexec service
To make the irexec service restart when inputlirc is restarted (due to a key configuration change), the service startup file has to be slightly modified:


Description=Handle events from IR remotes decoded by lircd(8)

Add the lines marked above, then rebuild the systemd service configuration file and enable and start the irexec service:

systemctl daemon-reload
systemctl enable irexec
systemctl start irexec

Check that the irexec.service is running:

systemctl status irexec

Configuring what to run on keypresses
The file “/etc/lirc/irexec.lircrc” contains the configuration for what commands to run when selected key(combinations) are used. Wipe out all the defaults in there and add something useful. Below is the updated, more generic configuration I use on my PiOS for the piStorm now, just mapping some keys to a script with a similar name:

    prog   = irexec
    button = SHIFT_KEY_F1
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F2
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F3
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F4
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F5
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F6
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F7
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F8
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F9
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F10
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F11
    config = /home/pi/irexec/

    prog   = irexec
    button = SHIFT_KEY_F12
    config = /home/pi/irexec/

    prog   = irexec
    button = CTRL_SHIFT_KEY_F12
    config = /home/pi/irexec/

Whenever you have made a change to /etc/lirc/irexec.lircrc, you need to restart inputlirc (which automatically restarts liexec):

systemctl restart inputlirc

Action scripts in /home/pi/irexec
These scripts can be updated without having to restart inputlirc. Be sure to set the execute flag on them (chmod 755 /home/pi/irexec/*.sh)
For the piOS installation for the piStorm, the content of my configuration-switching scripts are as follows:

/home/pi/irexec/ (the F-keys 1-10 with the SHIFT key held down):

cp /home/pi/cfg/a1200_4068_os31.cfg /home/pi/default.cfg
sudo systemctl restart pistorm

In a similar way, I have set up the other shift-f-key combinations as shown in the video.

I have used SHIFT+F12 for a safe reboot, and CTRL+SHIFT+F12 for a shutdown of the pi. If running piStorm in RTG mode there can be a delay of about 1 minute before something happens.


sudo systemctl stop pistorm
sudo reboot


sudo systemctl stop pistorm
sudo halt -p

You can check the status of the piStorm service to see that it received the shutdown command:

root@raspberrypi:~# systemctl status pistorm
● pistorm.service - Start piStorm 68k emulator
   Loaded: loaded (/lib/systemd/system/pistorm.service; disabled; vendor preset: enabled)
   Active: deactivating (final-sigterm) since Sat 2021-04-24 23:48:43 BST; 1min 6s ago
  Process: 1023 ExecStart=/home/pi/ (code=killed, signal=TERM)
 Main PID: 1023 (code=killed, signal=TERM)
    Tasks: 10 (limit: 873)
   CGroup: /system.slice/pistorm.service
           ├─1024 sudo ./emulator --config /home/pi/default.cfg
           └─1025 ./emulator --config /home/pi/default.cfg

Apr 24 13:23:53 raspberrypi[1023]: [MUSASHI] Mapped read range 4: 40000000-48000000
Apr 24 13:23:53 raspberrypi[1023]: [MUSASHI] Mapped write range 3: 40000000-4800000
Apr 24 13:23:53 raspberrypi[1023]: Platform custom range: 00E90000-80010000
Apr 24 13:23:53 raspberrypi[1023]: Platform mapped range: 00200000-48000000
Apr 24 13:23:53 raspberrypi[1023]: RTG display disabled.
Apr 24 13:23:53 raspberrypi[1023]: Pitch: 800 (800 bytes)
Apr 24 13:23:53 raspberrypi[1023]: RTG thread running
Apr 24 13:23:53 raspberrypi[1023]: error: XDG_RUNTIME_DIR not set in the environmen
Apr 24 23:48:43 raspberrypi systemd[1]: Stopping Start piStorm 68k emulator...
Apr 24 23:48:43 raspberrypi systemd[1]: pistorm.service: Main process exited, code=killed, status=15/

Revised script
Because I want to run the wip-crap version of the emulator at some points, I have added a check for the mentioning of “wip-crap” in the configuration file that is going to be used, then depending on its existance or not, launching the emulator from the correct directory:

if grep -q wip-crap "/home/pi/default.cfg"; then
  echo "wip-crap"
  cd /home/pi/pistorm-bnu/
  echo "main"
  cd /home/pi/pistorm/
sudo ./emulator --config /home/pi/default.cfg
exit 0

To enable the wip-crap version, just add a comment in the beginning of the configuration such as:

# using wip-crap functions

Inner secrets of Synology Hybrid RAID (SHR) – Part 1

Inner workings of Synology Hybrid RAID

Maybe a too much promising title for this post, but this is my guesswork on how SHR works when replacing drives. If anyone have a spare DS1517 (or later device, with at least 4 slots) to donate, I will investigate this further, cannot afford to do it on my primary NAS because of risk of loosing data – and now even not possible without upgrading the disks again to larger ones).

I will also post here my case (more or less in full) sent to Synology when the NAS got unresponsive (crashed) during the rebuild/reshaping process.

What is Synology Hyrbrid RAID ?

This is in fact the only thing Synology themselves have briefly explained in their documentation:
What is Synology Hybrid RAID (SHR)

My short explanation is that it is a software RAID that is able to maximize the utilization of mixed sized hard drives. For simplicity, Synology illustrates this with drives varying of 500GB to 2TB (in 500GB increments), possibly fooling some people to think that the disks are always split into 500GB partitions.

My findings while expanding my DS1517 (from 3TB, 3TB, 3TB, 8TB, 8TB to all 14TB) is that the remaining space of the drives are splitted in as few parts as possible to obtain the maximum available space (after setting aside about 2.5GB for the DSM (operating system) and 2GB for swap).

Replacing disks and rebuilding the RAID

Before I replaced the first disk, I actually forgot to view and save down the info about the partitions, mdraid volumes and logical volumes (I might have that somewhere else, but I will not look for it now). Based on how it looked after the first disk had been replaced, and the rebuild was done (in the process of reshaping) it should have been something like this:

# sfdisk -l
/dev/sda1                  2048         4982527         4980480  83
/dev/sda2               4982528         9176831         4194304  82
/dev/sda5               9453280      5860326239      5850872960  fd

/dev/sdb1                  2048         4982527         4980480  83
/dev/sdb2               4982528         9176831         4194304  82
/dev/sdb5               9453280      5860326239      5850872960  fd

/dev/sdc1                  2048         4982527         4980480  83
/dev/sdc2               4982528         9176831         4194304  82
/dev/sdc5               9453280      5860326239      5850872960  fd

/dev/sdd1                  2048         4982527         4980480  fd
/dev/sdd2               4982528         9176831         4194304  fd
/dev/sdd5               9453280      5860326239      5850872960  fd
/dev/sdd6            5860342336     15627846239      9767503904  fd

/dev/sde1                  2048         4982527         4980480  fd
/dev/sde2               4982528         9176831         4194304  fd
/dev/sde5               9453280      5860326239      5850872960  fd
/dev/sde6            5860342336     15627846239      9767503904  fd

Note: The partition types for sd[a-c][1-2] seems incorrect as these where changed to “fd” later on during the process, or it might have been something changed by Synology on later DSM versions (but not at the point of updating DSM).

Partitions 1-2 are the system and swap partitions on all the drives, sized 2.5GB respectively 2GB.
Partition 5 is a part of the storage space available in the volume on the NAS. In this case it is about 2.9TB in size (the maximum available on the smallest disks).
Partition 6 is the second part of the total storage space. At this time those partitions are about 4.8TB in size.

mdraid volumes

Out of the partitions above, the Synology creates these mdraid volumes:
md0: RAID 1 of sda1, sdb1, sdc1, sdd1, sde1: total size 2.5GB used for DSM
md1: RAID 1 of sda1, sdb2, sdc2, sdd2, sde2: total size 2GB used for swap
md2: RAID 5 of sda5, sdb5, sdc5, sdd5, sde5: total size about 11.7TB
md3: RAID 1 of sdd6, sde6: total size of about 4.8TB

LVM logical disk

md2 and md3 are joined together into a logical disk using LVM, which gives about 16.5TB space in total for the storage volume on the NAS (Synology DSM says 15.5TB, but the difference is only because of how I estimate the space and how Synology does – I just take the block count, divide by two, then use a one decimal precision – which is adequate enough for this description).

DSM Storage Manager before replacing the first disk

… to be continued in part 2 …

Synology NAS – PHP

Enabling extensions in PHP CLI

Become root
Find out which configuration file is used:
php --ini

I get:
Configuration File (php.ini) Path: /usr/local/etc/php70
Loaded Configuration File: /usr/local/etc/php70/php.ini

Edit the php.ini file, check/change extensions dir to where it is located. If PHP was installed through DSM it should be something like ‘/volume1/\@appstore/PHP7.0’
extension_dir = "/volume1/@appstore/PHP7.0/usr/local/lib/php70/modules/"

Enable the extensions you wish to use:
extension =
extension =
extension =
extension =
extension =

Installing Composer

Composer documentation

Become root
Enable the extensions as above (phar, openssl and zip are needed for Composer).

Get and install Composer:
cd /usr/local/bin
curl -s | php70

Create shortcut script ‘composer’ in /usr/local/bin:
php70 /usr/local/bin/composer.phar $*

Set permissions:
chmod --reference=composer.phar composer

composer --version

PC games


Humble Bundle
Abandonware DOS


SPORE™ Collection on GoG
Google Search (videos) “Spore GDC 2005”

Spore 35min Demonstration from the GDCe (2005)

The making of spore (FULL)

Will Wright: Spore, birth of a game (TED Talk)

Will Wright and Spore

G4TV’s Icons – Will Wright

Cannon Fodder

(some free levels + uses data from full Amiga/PC versions)


Available from Steam and Humble Bundle


X-Plane 11

Captain Joe

Fly with Captain Joe

Synology NAS – Add disk and include in md0+md1

Adding new disks, including in mirroring of system partitions (md0 and md1)

GNU parted documentation

  1. Add the new disks as hot spare, then remove them (will create the disklabel, otherwise just do this using parted)
  2. Check the partition table of a disk already used for system and swap. Find it by checking mdstat (cat /proc/mdstat)
    # cat /proc/mdstat
    Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]
    md1 : active raid1 sdd2[3] sdb2[1] sdc2[2] sda2[0]
    2097088 blocks [5/4] [UUUU_]
    md0 : active raid1 sdd1[3] sdb1[1] sda1[0] sdc1[2]
    2490176 blocks [5/4] [UUUU_]
    unused devices:
    # parted /dev/sda
    (parted) unit s
    (parted) p
    Model: ATA ST3000DM001-1CH1 (scsi)
    Disk /dev/sda: 5860533168s
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:
    Number Start End Size File system Name Flags
    1 2048s 4982527s 4980480s ext4 raid
    2 4982528s 9176831s 4194304s linux-swap(v1) raid
    (parted) q
  3. Run parted on the new disk
    # parted /dev/sde
    (parted) unit s
    (parted) p
    Model: ATA ST3000DM001-1CH1 (scsi)
    Disk /dev/sda: 5860533168s
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:
    Number Start End Size File system Name Flags
    (parted) mkpart system ext4 2048 4982527
    (parted) mkpart swap linux-swap 4982528 9176831
    (parted) p
    Number Start End Size File system Name Flags
    1 2048s 4982527s 4980480s ext4 system
    2 4982528s 9176831s 4194304s linux-swap(v1) swap
    (parted) q
  4. Add partitions to system and swap
    # mdadm --add /dev/md0 /dev/sde1
    # mdadm --add /dev/md1 /dev/sde2
  5. Check rebuild status using ‘cat /proc/mdstat’
  6. Final result should be something like:
    # cat /proc/mdstat
    Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]
    md1 : active raid1 sde2[4] sdd2[3] sdb2[1] sdc2[2] sda2[0]
    2097088 blocks [5/5] [UUUUU]
    md0 : active raid1 sde1[4] sdd1[3] sdb1[1] sda1[0] sdc1[2]
    2490176 blocks [5/5] [UUUUU]
    unused devices:

Buffalo LS220 – BAMP – Buffalo Apache MySQL PHP

Apache (med PHP-stöd) och MySQL på Buffalo (LS220)

Fullt möjligt, men inte så snabbt.
Jag har på en av mina Buffalos även testat köra WordPress på LS220n, funkar fram till 5.1.1 med förinstallerad version av PHP. Från version 5.2 krävs PHP version 5.6 (jag kommer undersöka om det går att uppdatera php-cgi på Buffalon)

En förutsättning för att få det att fungera är att den är patchad för att tillåta root-inloggning via SSH:
Buffalo LS220 – root access och andra modifieringar

Nästa steg är att få igång en egen virtualhost på den förinstallerade (och tok-felkonfigurerade) Apache 2.2.14 som finns där:
Buffalo LS220 – apache web server
Apache får sitt PHP-stöd genom php-cgi, PHP versionen som är tillgänglig är 5.3.23

Sedan MySQL:
Buffalo LS220 – MySQL server

Övrig Buffalo information

Buffalo forum

Firmware uppdatering

Nyaste firmwaren finns här. Version 1.70 kom i slutet på januari 2018. I början på december 2019 varnade mina LS220s att det finns en ny firmware. 1.73 hade släppts, och timestamp på innehållet i arkivet är 2019-11-19. Mina NASar (och NASNavigator) har slutat att indikera att det finns ny firmware att installera, och jag kör 2020-01-01 fortfarande på 1.70.

Senaste firmware för LS220
Installationen är enkel. Ladda ner senaste versionen, packa upp och starta LSUpdater.exe
Programmet hittar själv de Buffalosar på ditt nät som behöver uppdateras.
Var beredd på att innehåll i /root kommer gå förlorat, likaså allt som är modifierat i filer som följer med systemet (många av modifieringarna nedan).

TFTP-återställning av LS220D

Ifall något går helt snett, eller om båda diskarna byts. Med tanke på hur kasst BuffaloOS är, så kanske det inte ens går byta en disk utan att återställa den.
Completely revocering from a bricked Buffalo Linkstation LS200


Den flersidiga tråden med de av andras och mina inlägg är källan till alla mina Buffalo-artiklar
Hacka Buffalo Linkstation LS220D (LS200, LS400)

Buffalo LS220 – MySQL server

MySQL server på Buffalo LS220

Testad upp till firmware 1.70 (14 sepember 2018)

En del av Buffalo LS220 – BAMP – Buffalo Apache MySQL PHP

Första gången (efter root-patchning)

MySQL 5.1.63 är förinstallerat med firmware 1.67 (säkert samma på äldre) men används inte till något (vad jag känner till).
För att databaserna inte ska gå förlorade är det en bra idé att lägga dom under ‘/mnt/array1’.

Börja med att kopiera konfigurationsfilen för MySQL från /usr/share/mysql:

cp /usr/share/mysql/my-small.cnf /etc/my.cnf

Lägg till ‘datadir’ och ‘pid-file’ under [mysqld] i /etc/my.cnf:

port           = 3306
socket         = /tmp/mysql.sock
pid-file       = /tmp/
datadir        = /var/lib/mysql

Skapa uppdateringssäker lagringsplats för databaserna och länka

mkdir /mnt/array1/mysql
ln -s /mnt/array1/mysql /var/lib

Skapa grupp och användare för MySQL

addgroup -S mysql
adduser -S -s /bin/false  -G mysql -g "MySQL Server" -h /var/lib/mysql mysql

Skapa systemdatabas i /mnt/array1/mysql och sätt rootlösenord

mysql_install_db --user=mysql --datadir=/mnt/array1/mysql
/usr/share/mysql/mysql.server start
/usr/bin/mysqladmin -u root password 'new-password'

Kolla att det fungerar, och länka sen in start/stoppscripten

ln -s /usr/share/mysql/mysql.server /etc/rc.d/extensions.d/S70_mysql.server
ln -s /usr/share/mysql/mysql.server /etc/rc.d/extensions.d/K70_mysql.server

Efter uppdatering av firmware

/etc/passwd och /etc/group oförstörda (alltid nåt, det innebär att mysql-användaren finns kvar)

Kopiera /usr/share/mysql/my-small.cnf till /etc

cp /usr/share/mysql/my-small.cnf /etc/my.cnf

Lägg in ‘datadir’ och ‘pid-file’ i /etc/my.cnf

port           = 3306
socket         = /tmp/mysql.sock
pid-file       = /tmp/
datadir        = /var/lib/mysql

Länka till /var/lib/mysql

ln -s /mnt/array1/mysql /var/lib


/usr/share/mysql/mysql.server start

Länka in start/stoppscripten:

ln -s /usr/share/mysql/mysql.server /etc/rc.d/extensions.d/S70_mysql.server
ln -s /usr/share/mysql/mysql.server /etc/rc.d/extensions.d/K70_mysql.server