How to install your own Image Optimizer on your Cloudways VPS

Last updated: 14 September 2019 (see update)

If you’re looking for a free alternative to Imagify or ShortPixel, and you don’t want to use a bloated WordPress plugin such as EWWW Image Optimizer, then you’re in luck because you can piggyback on WP CLI.

On Cloudways servers, WP CLI comes pre-installed, so all you need to do is install the image-optimize-command package, which is a wrapper for spatie/image-optimizer (a quite powerful PHP package that runs images through a chain of various optimization tools).

Then, you can use Cron to automatically run the image optimizer at a specified schedule. I would recommend to run it at night or at a time when you don’t have a lot of traffic.

The optimization process is a CPU-intensive task. If you have your own VPS (which you do with Cloudways) and your site is not too large (your users don’t upload a ton of images every day), then your server should be able to handle the load.

Alright, let’s go over step-by-step.

Steps

Follow the steps below to install and configure the image optimizer on your Cloudways server.

Install the WP CLI Package

Log into your Cloudways account and head over to your server’s control panel.

Launch the SSH terminal.

Screenshot of the server's control panel
Screenshot of the server’s control panel

Log in with your master SSH username and password (found on the server’s control panel).

To be able to copy/paste inside the SSH terminal, right-click and select “Paste from browser”.

Once you’re logged in, copy and paste the following command:

wp package install typisttech/image-optimize-command:@stable

This should install all the needed components on your server. At the end, you will receive a message:

Success: Package installed.

That’s it for the installation!

Configure Cron

The package is installed, but now we need to schedule the image optimizer to run at specified times every day.

To be able to do this, you need to create a Cron job.

This time, navigate to your application’s control panel, head over to the Cron Job Management panel and click on “Add new cron job”.

Screenshot of the Cron Job Management panel
Screenshot of the Cron Job Management panel

We will create a placeholder Cron job just to get the right path of your application.

Select the “Once a day” common settings and some dummy command, e.g. “test.php”.

Video of the Cron job creation step

Submit. Then, go to the Advanced tab and you should see the following code.

0  0  *  *  *       cd /home/xxxxxx.cloudwaysapps.com/xxxxxxxxxx/public_html && php /home/xxxxxx.cloudwaysapps.com/xxxxxxxxxx/public_html/test.php  #CloudwaysApps

Take note of the path to your application’s public_html folder. In the above example, it would be /home/xxxxxx.cloudwaysapps.com/xxxxxxxxxx/public_html.

Copy it somewhere in your notes and delete everything that’s inside the Advanced Cron’s text zone. Then, paste the following:

*/5 2-4 * * *       cd /home/xxxxxx.cloudwaysapps.com/xxxxxxxxxx/public_html && export WP_CLI_PACKAGES_DIR=/home/master/.wp-cli/packages/ && /usr/local/bin/wp image-optimize batch --limit=3  #ImageOptimizer

Replace the path to the public_html folder with the path that you saved earlier.

Basically, */5 2-4 * * * means that the Cron job will run at every 5th minute past every hour from 2am to 4am.

If you want to customize the frequency, I would recommend you to use crontab.guru. It’s a handy tool that will make sure you have the right Cron syntax.

Then, cd /home/xxxxxx.cloudwaysapps.com/xxxxxxxxxx/public_html is a command to change the working directory to your application’s pubic_html folder (make sure to replace it with your own path).

To share the WP CLI packages that were installed by the master user, we need to set an environment variable, which is done by export WP_CLI_PACKAGES_DIR=/home/master/.wp-cli/packages/.

The final part /usr/local/bin/wp image-optimize batch --limit=3 is the command that runs the image optimizer. There is a limit of 3 attachments per run, so if you want to optimize more images each run, you could increase this number.

With the Cron job running every 5 minutes for 2 hours, it will be able to optimize 72 images each day. If you think your users will upload more than 72 photos every day, then you should tweak the numbers.

Apply the fix (IMPORTANT)

As of today (14 September 2019), there is a known issue that you need to fix in order for the image optimizer to work on Cloudways. If not, you might get the following error when you run wp image-optimize.

PHP Fatal error:  Uncaught Error: Call to undefined method Symfony\Component\Process\Process::fromShellCommandline()

The issue and the fix is described here: https://github.com/TypistTech/image-optimize-command/issues/37

Open the SSH terminal and type:

nano +97 /home/master/.wp-cli/packages/vendor/spatie/image-optimizer/src/OptimizerChain.php

This should open the PHP file at line 97 in the nano editor.

Modify the line from:

$process = Process::fromShellCommandline($command);

to

$process = new Process($command);

You’re all set now!

UPDATE: Install more libraries

I realized that there are some binaries that are not installed by default on Cloudways servers. These binaries are needed to optimize particular images.

Since you don’t have root access in Cloudways, you will need to talk with their support team.

Open a chat session or ticket and ask the agent to run the following commands on your server.

sudo apt-get install jpegoptim
sudo apt-get install optipng
sudo apt-get install pngquant
sudo npm install -g svgo
sudo apt-get install gifsicle
sudo apt-get install webp

Some of these libraries might already be installed, but ask them anyway, just to be sure.

After the Cloudways’ agent finishes the installation, you can log into your SSH terminal and run the following commands to check if everything is good.

jpegoptim --version
optipng --version
pngquant --version
svgo --version
gifsicle --version

Each command should output the proper version number of the library.

For webp, you should instead run this command:

apt list --installed | grep webp

You should see the webp library part of the output.

That’ll do the job!