WP-cli run command over each subsite

If you use WP-cli command on a multisite it be default will only run on the mainsite.
But often you want to change a setting for all the sites.
In my case I wanted to set the timezone to Amsterdam for the whole network. That’s not hard:

wp option set timezone_string 'Europe/Amsterdam'

On a multisite this is a bit more difficult. But the script below will do the same for each site in a multisite.

wp site list --field=url | xargs -I % sh -c 'printf "SITE: %\n"; wp option set timezone_string 'Europe/Amsterdam' --url=%'

It consists of 3 parts.
First create a list of all site url’s

wp site list --field=url

Secondly we pass that on to xargs.
xargs is a very powerfull tool. One that I hardly understand and should go into deeper one day.
This is the best tutorial I found if you want to start with xargs.

The only thing important now is the -I %. This sets the variable to %.
But the most important thing here is that inside the '***' You can run any command. like normal.

xargs -I % sh -c '***'

Which brings us to the final part.
First print the site url on a line, then do the actual command we want to do on each sub site. As you can see we pass on the --url=% where we set the variable given in xargs.

printf "SITE: %\n"; wp option set timezone_string 'Europe/Amsterdam' --url=%

VVV disable backups

Update VVV 3.0

As of the release of VVV 3.0 this can all be done by adding the following in the vvv-custom.yml

general:
  # Backup the databases to the database/backups subfolder on halt/suspend/destroy, set to false to disable
  db_backup: false
  # Import the databases if they're missing from backups
  db_restore: false
list of vvv custom action files

Pre VVV 3.0

VVV is great but if you have 20+ sites in it most of which are quite big doing a reload or halt can be quite slow.
Disabling it isn’t the easiest. In vagrant-root/config/homebin/ create these 3 files:

  • vagrant_destroy_custom
  • vagrant_halt_custom
  • vagrant_suspend_custom

I wish there was a way to easily disable these. The vvv-custom.yml would be great for this.
Also adding a way to exclude specific databases.

source

php array; insert new item at specific index

The php function array_splice can be used to insert new items. At specific places.

<?php
$breadcrumbs = [
    'home',
    'year',
    'month',
    'day',
];
$new_crumb = [
    'category'
];
array_splice($breadcrumbs, 1, 0, $new_crumb);

The result is that category is inserted at the second place.

<?php
array (
    0 => 'home',
    1 => 'category',
    2 => 'year',
    3 => 'month',
    4 => 'day',
);

Running php from command line

This is one of those “I know this is possible, but don’t know how”.

php -r '$parts = [ "hello", "world" ]; echo implode( " ", $parts ) . PHP_EOL;' # hello world

Only useful for simple onelines. You’re very likely to be better of putting code in a php file and run that script like:

php ./helloworld.php

Run PHP with WordPress loaded.

Of course your good old friend wp-cli can help.
It can run code with wp fully loaded. So if you add things in the init action or even after the wp_loaded, those plugin/theme functions, posttypes and such are all available.

First off the plain php code execution, with wp eval

wp eval 'var_dump(did_action( "wp_loaded" ));'  # int(1)

Secondly we execute a file with WordPress fully loaded using wp eval-file

wp eval-file ./helloworld.php

Installing PHP7.4 on a Rapsberry Pi

Note: this post call also be used to install php7.0, php7.1, php7.2 or php7.3, just change every reference to 7.x. And skip right to “Actual install php

Default Rasbian still ships with php7.3, not that weird as at time of writing 7.4 is only released for about a month.
We will install the latest php7.4. But because this is not the default we will need to do a few extra tweaks.

Add newer source

We are going to create a new source for php. We do this with the following 3 commands

sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ buster main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update

Actual install php

Now we are ready to install php7.4 with all modules we need:

sudo apt install -y php7.4-common php7.4-fpm php7.4-cli php7.4-curl php7.4-json php7.4-mysql php7.4-opcache php7.4-gd php7.4-sqlite3 php7.4-mbstring php7.4-zip php7.4-readline php-pear

When done check it with php -v it should show a php 7.4.0 or higher.
Now we need to add a few fpm things for nginx to work properly.
Create a extra config file sudo nano /etc/php/7.4/fpm/conf.d/90-pi-custom.ini.
And add:

cgi.fix_pathinfo=0

upload_max_filesize=64m
post_max_size=64m
max_execution_time=600

Finally reload php

sudo service php7.4-fpm reload

Now PHP is ready to use

Extra’s

You might want to follow these instructions to install. wp-cli, composer, image compression support in php

Installing Nginx on a Rapsberry Pi

In this step we are going to install a webserver (nginx). For those who are bit familiar with webservers you might wonder why we are not using apache? I myself are far more familiar with Apache but Nginx just has better performance. And on the not so powerful pi that is important.

Install Nxing

To start we just plainly install nginx.

sudo apt install -y nginx

Check the version nginx -v it should be version nginx/1.14.2 or higher

To test if it works enter the IP address in the browser. You should see this page.

If you see an error most likely IPv6 isn’t supported. Open the nginx config file sudo nano /etc/nginx/sites-enabled/default.
At the top you should see these lines

    listen 80 default_server;
    listen [::]:80 default_server;

Change them to:

    listen 80 default_server;
    #listen [::]:80 default_server;

Save then restart nginx.

sudo nginx -t && sudo service nginx reload

Then test the page again in the browser.

Setting up a site with php and url

First we will do some global settings open: sudo nano /etc/nginx/conf.d/90-pi-custom..conf
Add the following line, we increase the allowed upload sizes.

client_max_body_size 64M;

Note: for the example I use example.local replace that with the url you want to use. If you don’t have the url setup yet you can add it to you own host file. Or instead of the url use the IP-address of the Pi.

We will create our own vhost files. PS I’ll be using example.local but use whatever you intend to use. Create the vhost file: sudo nano /etc/nginx/sites-enabled/example.local.conf

server {
    listen 80;

    server_name example.local;
    root /var/www/example.local/public_html;

    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }
}

Next create the folders needed. Set the rights of those files and add a test page.

sudo mkdir -p /var/www/example.local/public_html
sudo touch /var/www/example.local/public_html/index.php
sudo chown www-data:www-data /var/www/example.local -R
sudo nginx -t && sudo service nginx reload

In the main file add sudo nano /var/www/example.local/public_html/index.php

<?php
phpinfo();

To test the url example.local you need to add it to your host file. Depending if you’re on Windows, Mac or Linux the instructions are different. See this guide: How to edit your hostfile

Now go the the url and you should see this:

phpinfo dump on a working example.local

Now we have a basic and functioning webserver with php.
For security sake delete the index.php file

sudo rm /var/www/example.local/public_html/index.php

Permissions and Nginx

So far we use sudo for pretty much everything. This is fine.
After the initial setup most of the work has to be done in /var/www/*. These files are owned by the www-data user. This also is normal and fine.
We can change Nginx to use the pi user.

That way you can avoid the sudo for every small change.
This is a security risk of course.
The big upside is no more sudo and changing owners of files.
The downside is that every file pi can access Nginx also can access.

Tips when using the default Nginx user.

  1. Files created by Nginx will have owner and group www-data
  2. The default pi user can’t edit these. When editing use sudo
    If you are changing a lot you want want too temporarily change the entire folder to the pi user.

    Change user to PI
    sudo chown pi:pi -R /var/www/PATH

    Change user back to the Nginx default.
    sudo chown www-data:www-data -R /var/www/PATH

There is a separate user for changing the user Nginx so it won’t use www-data.
This is a security risk, so I don’t recommend it, The rest of the guide(s) acts as if you didn’t do this.

Curl output format

A lot of usefull informatoin can be caught using curl. Formating the output can be done with the -w --write-out argument

curl -w 'Home loadtime: %{time_total}\nResponse code: %{http_code}\n' -o /dev/null -s 'https://www.janw.me/'
Bash output of curl request

Output example:

This example will show the load time and response code. These 2 values are duable. But If you want more it’s more readable to pass a file.

In file: nano curlformat.txt

    time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
   time_pretransfer:  %{time_pretransfer}\n
      time_redirect:  %{time_redirect}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ----------\n
         time_total:  %{time_total}\n

Then pass the file to curl:

curl -w "@curl-format.txt" -o /dev/null -s "https://janw.me/"
Bash output of curl format file

A list of all avialable variables are in the man pages

Sources:

Extra programs on a Raspberry Pi

In this series the pi itself is installed using Raspbian Stretch Lite to keep it light. Some extra’s will come in handy.

Installing git on a Raspberry Pi

sudo apt install git -y

After installing git, set your credentials

git config --global user.name "John Doe"
git config --global user.email "johndoe@example.com"

Git documentation

Installing wp-cli on a Raspberry pi

wp-cli will not work without php installed

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

WP-cli documentation

Installing composer on a Raspberry pi

composer will not work without php and git

curl -O https://getcomposer.org/composer.phar
chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer
sudo composer self-update
composer --version

Composer documentation

Installing optipng gifsicle libjpeg-progs on a Raspberry Pi

You might want image optimization & compression. In the main php article php-gp was installed. But that is not enough.

sudo apt install -y optipng gifsicle libjpeg-progs

Installing send mail on a Raspberry Pi

sudo apt install -y sendmail

Installing PHP on a Raspberry Pi

PHP is covered in it’s own article.

Installing mariaDB/mysql on a Raspberry Pi

MariaDB or Mysql is covered in it’s own article.

Installing NginX on a Raspbery Pi

NginX is covered in it’s own article

RaspberryPi, Only allow ssh key login

This is the followup of Opening a Raspberry Pi to the outside world On the internet bots constantly try to hack servers. The Raspberry Pi is popular target. That’s why by default ssh is disabled nowadays.
To make this more secure we will only allow login by ssh key instead of a password. Ssh keys are a lot safer and you also won’t need to type/paste the password on login.

Open file: sudo nano /etc/ssh/sshd_config

Look for PasswordAuthentication
remove the # at the front and change the value to no.

PasswordAuthentication no

As a fall-back we will allow login in from the home network. So at the bottom of the file add. (the 4 spaces in front of the line matter)

Match address 192.168.*.*
    PasswordAuthentication yes

Restart the ssh service. sudo service ssh restart

ssh keys

Generate keys on the raspberry pi: ssh-keygen -t rsa -b 4096 -C "pi-webserver"
Just press enter for both the location and password.
Add your local key. Form your own machine mac/linux/windows.

Open File: sudo nano .ssh/authorized_keys

Paste your public key in this file.
For linux/mac you can find your public key with: cat ~/.ssh/id_rsa.pub

In a new terminal tab/window, try to login again. This way you can change things in the current tab. If something went wrong. You should login without needing to type the password. To check if the password is disabled you should try login in from a different computer and a different ip.

RaspberryPi up and running

This guide will help you set up a Raspberry Pi with Rasbian. Ready to do pretty much whatever you want.

What hardware do you need?

a Raspberry Pi, a case, a network cable, power supply and an SD-card
The Required Hardware
  • First off a Raspberry Pi of course, this tutorial uses a 4B 4GB. And should also work on a Model 2B and 3B.
  • Second I have a network cable. Wifi is available on since the 3B but wire always has a more stable connection.
  • A USB-C power source. This can get a bit tricky. Recommended is at least 2A with 5V. A normal smartphone adapter won’t give that. Using less will slow down your Raspberry. If you’re using a 2B or 3B you need micro USB instead of USB-c
  • A micro SD card, at least class 10 for speed and with 8GB or more. The SD card will serve as the main harddrive for the pi. An micro SD adapter is also needed to install the image on the SD card.
  • A Case, simply a case to better protect your Raspberry.

Installing Rasbian

First off download Raspbian Buster Lite from the Raspberry pi website. When It’s done flash the image on the SD card. There is an official guide that explains it better then what I could do.

Flashing the image can take a while. You could set up all the wires and put things in place.

After the SD card is done

When the writing of the SD card is done. Put a file with the name (of empty folder) named ssh in the root of the boot partition.

Also in the boot partition is a file called cmdline.txt. Open that, and at the end of the line add the IP you want to give the Pi

 EXTSTING_FILE=SETTINGS ip=192.168.x.x

If you need wifi place a file named wpa_supplicant.conf also in the boot partition. And add the following:

network={
    ssid="YOUR_SSID_WIFI_NAME"
    psk="YOUR_PASSWORD"
    key_mgmt=WPA-PSK
}

I haven’t tried this myself so more information here

Then plug in the SD card and powerup. Do wait 2~5minutes before actually trying. The Raspberry has to setup stuff for the first time. If after 20max you still can’t find an IP. The flashing of the SD card has gone wrong and you’ll have to restart.

Go to your own computer and open the terminal (or Putty for the windows users) Login with the command ssh pi@192.168.*.* Use the IP address you noted before. If it asks if you want to continue choose yes. and use the default password: raspberry Putty again will work a bit different.

Login in on a Raspberry Pi by a terminal
Logging in for the first time.

Now you are logged-in remote on the raspberry pi. Time to configure some stuff with the command sudo raspi-config.
On this menu we can configure some basic settings. Let’s change some settings.

the start screen of raspi-config tool
Start screen of the raspi-config screen.
  1. Change User Password CHANGE THE PASSWORD. Longer is better and safer
  2. Network options
    N1 Hostname the name of your Raspberry in your network. I named mine pi-webserver. Not required. It’s just a label. But useful if you got multiple Raspberry’s running.
  3. Boot options
    B1 Desktop / CLI Chose the ‘Console Autologin’ or ‘Console’ option. Don’t choose auto login if someone else might have physical access to the pi. Desktop will just waste power.
    B2 Wait for Network at Boot Just turn this off to be safe.
  4. Localisation Options Here you can change the timezone to your current one. You could change the language of the PI and the keyboard layout if you need to. Keep in mind I will be using English.
  5. Interfacing Options we don’t need this
  6. Overclock Only for the Pi 2B, Set this to the highest setting. It won’t hurt and will make the Pi a faster.
  7. Advanced Options This will be a bit more.
    A1 Expend Filesystem Run this. No need to reboot immediately.
    A3 Memory Split Set this to 16. Because we don’t have a interface we won’t need memory for that.
  8. Update Run this is should not hurt. It’s only to update the raspi-config tool.

When this is finished the pi might download some language packs. It it doesn’t reboot. you have to do it yourself. sudo reboot now.

Wait about a minute and login in again like before. But with the new password

Updates

This might take a while but first we are going to update.

sudo apt update && sudo apt upgrade -y

Now we update all default installed software. If the image is old or hasn’t been updated in a while it might take a long time. The date of the image is in the file name of the downloaded image.
At times It might appear to hang. It Unless it’s stuck on one thing 15 minutes it’s probably fine. Give it an 15 to 30 minutes. Else pull the plug.

When it’s done reboot again just to be sure.

You now have a Raspberry Pi ready for use.