Block Password Recovery Attacks

Been annoyed by the recent barrage of brute force password recovery attacks. In WordPress you can block these kind of attacks by turning off password recovery. Now this is obviously not for everyone as you will not be able to reset your password if you ever lose it. And that would mean adjusting the code to reactivate this or do some cool database tweaks with knowledge of password hashing and or other stuff like salts and whatnot. But I can manage. So I added

// Block Password Recovery
function disable_reset_lost_password()
return false;
add_filter( 'allow_password_reset', 'disable_reset_lost_password');

to functions.php

WordPress Setup Digital Ocean

Digital Ocean Account Setup

To work with Digital Ocean you need an account. It can be one run by developer, but preferably one client runs and to which he invites you as a developer and or DevOps. So you need the following for starters

  • Setup of account by client with DO
  • Team Setup with access for developer

Droplet Setup

Droplet’s setup is relatively easy using the Digital Ocean’s interface. You need to choose the proper droplet, your preferred region, Droplet size and Droplet base OS.

  • Droplet Size – At least 1 GB
  • Region Choice
  • Ubuntu 18.0.4 Setup with SSH keys attached
  • FQDN domain name connected to ip Droplet
  • Domain name must be directed to Digital Ocean DNS Server from Domain Service Provider
  • Domain at Digital Ocean must be directed with A Record to Droplet’s IP
  • Digital Ocean LEMP with WordPress

WordPress Setup Digital Ocean

Once you have taken care of the Droplet and Domain setup we move onto the actual guide for setting up a WordPress LEMP. This guide will be your base. It explains all and refers to requirements needed like:

  • initial Ubuntu 18.0.4 Server Setup
  • LEMP Setup
  • Let’s Encrypt SSL Setup

before moving onto setting things up like the

  • actual database installation,
  • PHP extensions,
  • WordPress Download
  • WordPress Config Tweaks
  • WordPress GUI Installation

Digital Ocean Initial Server Setup

Digital Ocean has a great guide mentioning where need be all extra steps to take to setup a basic Ubuntu Server to get going

It will guide you through setting up a server with

  • Sudo User,
  • basic firewall,
  • external access

Digital Ocean LEMP Setup

For the LEMP setup there is another great guide. It will go through all the necessary steps to set up a LEMP with:

  • Nginx webserver,
  • MySQL Database server,
  • PHP-FPM PHP Parser

on your Ubuntu Linux Droplet.

SSL Setup

Let’s Encrypt SSL Setup to get a free SSL certificate is not hard anymore these days and DO also gots your back here with this guide. It explains the DNS needs to set you up with LE SSL using Certbot.

Database Setup

MySQL Database installation on MYSQL Server is explained in the base tutorial. It basically tells you how to add the database from the command line with needed privileges and such.

PHP Extensions

Installing the necessary PHP Extensions is also explained in the base guide just like the database setup. Just follow it, install the necessary extensions with apt:

  • sudo apt update
  • sudo apt install php-curl php-gd php-intl php-mbstring php-soap php-xml php-xmlrpc php-zip

See guide for all the details

WordPress Installation

Downloading of the needed WordPress files to run the WordPress CMS is what you need to do here. Also explained in base guide as well as on WordPress. We can use curl for this step as you will see in the guide.

WordPress Configuration

Configuring the WordPress configuration file to work with the set up database, necessary constants for security like the AUTH_KEY.

Installation via Interface

Installation of WordPress following the instructions in the browser. Explained in base guide as well as on WordPress and actually pretty self explanatory.


New WordPress Admin User w/ PHP

To add a New WordPress Admin User w/ PHP you can tweak the database, but you can also simply do it with PHP code. I prefer the latter as I am better at PHP than MySQL and as messing with the database once a site is up is always tricky.

PHP Snippet

Here is a snippet from WP Scholar to achieve this as a WordPress Must Use Plugin:


add_action( 'init', function () {
	$username = 'admin';
	$password = 'password';
	$email_address = '';

	if ( ! username_exists( $username ) ) {
		$user_id = wp_create_user( $username, $password, $email_address );
		$user = new WP_User( $user_id );
		$user->set_role( 'administrator' );
} );

As you can see it adds three variables:

  • user name
  • password
  • email address

It also makes sure to only add it when it exists and assigns it the role of administrator which is what we were aiming for.


Just add it to the following directory:


If the mu plugins folder is missing add it. This setup loads it as a must use plugin that wil be loaded on the fly by WordPress. Once that is done you should be able to log in with your new details. Once you checked it worked do not forget to remove this file!

And there you have it. A new admin level user with a new password without touching existing users nor the database.

Laravel Valet Nginx 502 errors

Sometimes your WordPress website won’t load properly in Laravel Valet. You keep on getting Laravel Valet Nginx 502 errors. What can be done about it?

Telltale Signs

In your .valet/Log/nginx-error.log  you will see something like:

HTTP/2.0", upstream
2018/07/24 09:18:54 [error] 15573#0: *328 upstream sent too big header while reading response header from upstream, client:, server:

That means that your Nginx defaults are not good enough to handle the needs of the local setup.

Nginx Configuration Tweaks

To deal with this you can change your Nginx confix under .valet/Nginx/site.test and add the following to the php block:

# 24 july 2018 parameters to avoid Nginx 502 errors
  fastcgi_temp_file_write_size 10m;
  fastcgi_busy_buffers_size 512k;
  fastcgi_buffer_size 512k;
  fastcgi_buffers 16 512k;
  fastcgi_connect_timeout 300;
  fastcgi_send_timeout 300;
  fastcgi_read_timeout 300;
  fastcgi_intercept_errors on;
  fastcgi_next_upstream error invalid_header timeout http_500;

source SO pacofelc

Restart Brew Nginx Services

You will then also need to restart Nginx for Valet and you can do this like so:

brew services restart nginx

Digital Ocean Volume for WordPress Media

Adding Digital Ocean Volume for WordPress Media can be very useful. Especially if you have a lot of images and or other media and need a cheap way to store them. Block Storage at Digital Ocean is fast and easy to work with. It allows you to get a cheap Droplet and add cheap storage.

We already wrote about Setting up Trellis on Digital Ocean. Now you can expand upon this with a volume for your media!

Format the Volume

To format the volume I followed Digital Ocean’s instructions. These you will get once a volume has been setup. In a popup you will get the line needed for your volume in your region. Idid a

sudo mkfs.ext4 -F /dev/disk/by-id/scsi-0DO_Volume_volume-lon1-01

Add directory to store media

If you have this WordPress setup from scratch and just start a website you can skip this as the media directory is yours to use

If you do not already have the media directory where you store the media you can create one. Most likely you do. We however moved the old sites one inside the wp-content/uploads for our multisite media to a backup location and then recreated it using:

sudo mkdir -p sites

This as we would later sync all that data from the production server.

Mounting the Volume

Next we had to mount that directory so that it would load all the data from the volume instead of the actual Droplet. We did that using:

sudo mount -o discard,defaults /dev/disk/by-id/scsi-0DO_Volume_volume-lon1-01 /srv/www/;

And to make the mount permanent do a:

echo /dev/disk/by-id/scsi-0DO_Volume_volume-lon1-01 /srv/www/ ext4 defaults,nofail,discard 0 0 | sudo tee -a /etc/fstab

Then we checked if the mounting was successful:

cat /proc/mounts |grep staging
/dev/sda /srv/www/ ext4 rw,relatime,discard,data=ordered 0 0

As you see it was. And this means for most of you that you are done. You will have a Digital Ocean Volume for WordPress Media. We however needed to get the media copied over still.

Rsync Data

If you have this setup from scratch and just start a website you can skip this

Normally if you have a media volume already and need one for staging or another clone of the server you can just clone the volume and set up a new one and attach it. We only had an issue as the production server and volume were in a different region than staging so we had to set up a volume from scratch at both locations and sync the data between them:

ssh -o ForwardAgent=yes "rsync -aze 'ssh -o StrictHostKeyChecking=no' --progress /srv/www/"

Responsive Images with Width Based on Actual Image Width

WordPress has responsive images built in these days. Since 4.4 as a matter of fact. But what if we want to have WordPress Responsive images with width based on actual image width?

Current State and Needs

Can we generate something like WordPress responsive image (comments added to html):

<img width="1024" height="445" 
src="" // old browser support using src
class="d-block w-100" alt="" 
srcset=" 1024w, // 1024 width image 300w, // 300px width image 768w" / /768px width image
sizes="(max-width: 1024px) 100vw, 1024px">

where the 1024px can be based on the actual width of the image? That was the question we had and so we started looking around.

Additional Width

Somehow we had quite a few images that were smaller than 1024px on our site and these now got stretched as they are not 1024px wide.
As WordPress sees that the full image is 1024px by 445px that is what is uses to generate the images and though this works well it does not work for all. Looking for solution as suggested by Mark Root-Wiley like:

 srcset="example.gif 200w"
 sizes="(min-width: 400px) 400px, 100vw"
 width="200" /* <=== TA-DA! */

This would be a possible solution if the width was not static and the $attr variable would not overwrite the image attributes. Still we looked further.

Custom Sizes

Well, WordPress did suggest a solution for custom sizes:

$img_src = wp_get_attachment_image_url( $attachment_id, 'medium' );
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, 'medium' );
<img src="<?php echo esc_url( $img_src ); ?>"
     srcset="<?php echo esc_attr( $img_srcset ); ?>"
     sizes="(max-width: 50em) 87vw, 680px" alt="A rad wolf">

But that still did not load a width based on actual image width. And that set the srcset image to a another image size which we didn’t really need. Full width was fine for us.

WordPress Image Width

We could use

$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), "thumbnail" ); ?>

to grab the image meta data and then the width using:

$image_width = $image_data[1];

NB Great Explanation by Jonathan here

Custom Responsive Image with Actual Width

So something like:

$alt_text = get_post_meta($post->ID, '_wp_attachment_image_alt', true);
$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), "thumbnail" );
$image_width = $image_data[1];
$img_src = wp_get_attachment_image_url( $attachment_id, 'full' ); 
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, 'full' ); ?> 
<img src="<?php echo esc_url( $img_src ); ?>" srcset="<?php echo esc_attr( $img_srcset ); ?>" sizes="(max-width:<?php $echo image_width;?>) 100vw,<?php$ echo image_width;?>" alt="<?php echo $alt_text;?>">

NB Not tested yet!

should do the trick. This would allow a fully customized loading of the image with the actual width loaded instead of the full image width as set in the theme.

To be continued…

Quick Local WordPress Setup with Valet

Often you just want to do a quick WordPress setup locally on your Mac for trying something out. I always do a quick local WordPress setup with Valet. Laravel Valet is an application that is created by the developers behind Laravel. It can be used to run all sorts of apps and WordPress is one of them. Thanks to the Evan Mattson’s CLI Valet Command package you can use Valet to create WordPress sites with a single command.


So what do you need? You need to setup Laravel Valet and for that you need Homebrew (MacOs package manager) including PHP and MariaDB. You also need Composer to install the Laravel Valet package itself.. Let’s go through settings all these up.


So what do you need? You need to setup Laravel Valet and for that you need Homebrew (MacOs package manager). So install Homebrew using:

/usr/bin/ruby -e "$(curl -fsSL"

Homebrew Packages

Then you need to install PHP 7.2 (currently).

brew install homebrew/php/php72

And you also need to install MariaDB

brew install mariadb

Composer & Laravel Valet

Then you can install Laravel Valet with composer. Most of you using Laravel should have it already, but just in case. To install Composer do the following in a directory of your choice

php -r "copy('', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

Next step is to install the composer package for Laravel Valet

composer global require laravel/valet


You should have WordPress Command Line Interface installed too. You can read about it here. But on top of that you need to install the WP Valet package. This package does all the magic of using the coolness of Laravel Valet and WP CLI. You can do the installation using this wp command:

wp package install

That will get you going.

WordPress Website Installation

Once that is done you can install WordPress using Valet and Bedrock as a setup using:

wp valet new my-project --project=bedrock

Bonus: Local Site Copy

So what if you quickly want to set up an existing website? This so you can make changes for your client? There are many options. You could do a general WordPress Valet setup, replace the database and add the wp-content directory. That would do the trick. You could also do a general Valet WordPress setup and than do a BackupBuddy restore.

To start a new project as a base you simply run:

wp valet new my-project --project=wp

Then inside the newly created directory my-project run

valet link new-project

Using valet links you can check if it was created, but of course also by surfing to https:/my-project.test. You can then login at https://my-project.test/wp-login.php with username admin and password admin.

Local Restore

Now let’s say I want to go the BackupBuddy restore way. How do I proceed? I install the BackupBuddy plugin and import the backup using the backup file and the import file. Issue is that BackupBuddy refuses to run backups or restores due to errors with wp-cron and others.

Error: Error #9038: Loopback test error: cURL error 6: Could not resolve: site.test (Domain name not found). URL: https://site.test/wp-admin/admin-ajax.php?action=itbub_http_loop_back_test&serial=96ytxigaj612suq. If you need to contact your web host, tell them that when PHP tries to connect back to the site at the URL https://site.test/wp-admin/admin-ajax.php?action=itbub_http_loop_back_test&serial=96ytxigaj612suq via curl (or other fallback connection method built into WordPress) that it gets the error cURL error 6: Could not resolve: site.test (Domain name not found). This means that WordPress' built-in simulated cron system cannot function properly, breaking some WordPress features & subsequently some plugins. There may be a problem with the server configuration (eg local DNS problems, mod_security, etc) preventing connections from working properly.

We do have 1024MB as a memory limit already at /usr/local/etc/php/7.3/conf.d/php-memory-limits.ini and we also made execution time 120 instead of 30 at /usr/local/etc/php/7.3/php.ini

But with or without SSL we still got stuck updating via BackupBuddy’s interface. So what you can better do is replace wp-content and import the database as a whole. We imported with WP Database Backup.

WP Database Backup

We did however had to re-create the database and using utf8mb4. Basic WP Valet database setup caused the import to fail and even using different import settings than Greek Windows did not help. Still got stuck at

[ERROR in query 1] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PK   ' at line 1 [ERROR in query 2] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '??4?A?? ??G?ж??O ?????? ? fW??n?,?m??e?x? ? ?

With new database under the same name we could import. Warning shots were fired and a database update was needed by WordPress but things did work in the end. That and with home url and site url changed to work with .test . Of course image would still load remote site images, but for local code tweaks that did not matter.

NextGen Gallery Custom Field Rotating Images

NextGen Gallery Custom Field Rotating Images was created by us about 5 years ago for Ultimate Fiji Vacations. Since then the NextGen gallery has gone through some major changes. It has been taken over by Imagely and it has had some major upgrades.

Shortcode Changes

Some of these NextGen Gallery plugin changes were also shortcode changes. And these caused a not loading or not loading of some galleries (old post on setup) of a client of ours. We had to dig deep into the code changes to figure out what to do. We realized templates were loaded differently and that also the shortcode to load a gallery had changed. It now calles source and container_ids to load a gallery with images properly. The code

$gal = apply_filters('the_content', '[nggallery id='.$gal.' ' . $nggtemplate. ']' );
is therefore no longer applicable.

Full Code

Here is the full code to now load the gallery based on custom post type ID:
/* NG Gallery Custom Field Rotating Images */ 
$gallery = get_post_meta($post-&gt;ID, 'Gallery ID Number', true); 
$gal = $gallery; 
if( !empty($gal) ) { 
$gal = apply_filters('the_content', '[ngg_images source="galleries" container_ids=' .$gal.' display_type="photocrati-nextgen_basic_imagebrowser"]');
echo $gal;

As you can see the source=”” has been added and we removed the old fashioned way loading of the template as it no longer worked.

Template Loading

As the template is no longer loaded the old fashioned way and as this code allowed it to be loaded right away we decided do ditch loading a template by absolute path like so:


Instead we added the necessary JavaScript for the styling in the code where the slider was generated. This saved us the loading of another file and worked just as well! MainWP Issues

Been having MainWP Issues lately. The MainWP Dashboard cannot connect to the child theme. Never been happy with hostnet really as they throttle RAM all the time. This causes issues doing BackupBuddy backups and even issues with Wordfence.

MainWP – Hostnet Connection Severed

But now for two months I have not been able to connect the dashboard to the child theme. I tried:

  • deactivating and activating the MainWP Child theme,
  • reconnecting multiple times, no joy

HTTP Error

I keep on getting

ERROR: HTTP error - Connection timed out after 10001 milliseconds

errors. Funnily the error nor access logs in the control panel showed me little:

[Wed Feb 21 03:50:08 2018] [error] [client] cgid daemon is gone; is Apache terminating?: /usr/bin/php-cgi
[Wed Feb 21 05:20:37 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort

The app_pass_bridge can be fixed by raising the PHP_FCGI_MAX_REQUESTS limit or limiting the FcgidMaxRequestsPerProcess to 500 – SO url. And frankly I am not sure if that is related to MainWP knocking on the server’s door.

SSL Errors

Then we checked the SSL error logs and found:

[Wed Feb 21 17:33:15 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort, referer:
[Wed Feb 21 17:33:17 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort, referer:
[Wed Feb 21 17:33:18 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort, referer:
[Wed Feb 21 17:33:19 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort, referer:
[Wed Feb 21 18:28:13 2018] [error] [client] Premature end of script headers: php-cgi, referer:
[Wed Feb 21 19:08:42 2018] [error] [client] cgid daemon is gone; is Apache terminating?: /usr/bin/php-cgi
[Wed Feb 21 22:41:30 2018] [error] [client] cgid daemon is gone; is Apache terminating?: /usr/bin/php-cgi
[Thu Feb 22 01:07:16 2018] [error] [client] ap_pass_brigade failed with error 103: Software caused connection abort, referer:

More errors there, but nothing again on the immediate connectivity issues, but a strong indicator on server errors as ap_pass_brigade errors popup a lot.


What I mainly read upon it is that it is either an issue I can solve by raising RAM or by increasing PHP FCGI MAX REQUESTS. I opened a ticket with on it.

WP CLI Installation of WordPress

To do a WP CLI Installation of WordPress on a server where WordPress Command Line Interface is installed is quite easy. Let me explain here how you can get WordPress installed with it in no time.

WP CLI Installation

To install WP CLI itself do a

curl -O
chmod +x wp-cli.phar 
sudo mv wp-cli.phar /usr/local/bin/wp

then do a wp –info to see that it works.

WP Core Installation Parameters

You just need to log into the server via shell using ssh Then you go to the web root or directory where your site should reside. There you run the command wp core with the following parameters:

wp core install --title=Staging --admin_user=uberlord --admin_password=toughpassword

This will make wp-cli install WordPress for you with:

  • url – domain where the site will be served from
  • title – site’s Title
  • admin_user – admin’s username
  • admin_password – the administrator’s password
  • admin_email – the email address of the administrator

WP CLI Automation

Once you have started the command it will download the latest WordPress version, install it using the parameters you fed it.


I also wrote about installing WordPress from the command line before without any tool. This works just fine too. But these days I prefer Laravel Valet or WP CLI. These tools are just too nice to live without.