V
V
Vadim Timoshenko2019-04-17 10:53:55
Nginx
Vadim Timoshenko, 2019-04-17 10:53:55

How to setup Webp Express Plugin for Wordpress on NGINX?

Need to improve the performance of the site on wordpress in Google Page Speed. I want to replace all jpeg, jpg, png images with .webp. Installed the Webp Express plugin . He converted all the images on my site to .webp format. Pictures in the proper folders are in the right format.
But the problem. My site is on a VPS (Ubuntu 18/04). The web server is not Apache2, but NGINX.
In the FAQ for the plugin, I found the settings for NGINX. Here is what the creator writes:

It is possible to make WebP Express work on NGINX, but it requires manually inserting redirection rules in the NGINX configuration file (nginx.conf or the configuration file for the site, found in /etc/nginx/sites-available).
There are two different approaches to achieve the redirections. One based on rewrite and one based on try_files. As try_files performs best, I shall recommend that.
For multisite on NGINX, read here
method 1 (try_files)
Lets take this step by step.
The first step is to redirect images to the script. The second step is redirecting directly to existing webp images. Finally, as an optional third step, you can add extra rules for enabling the Convert non-existing webp-files upon request functionality
Step 1: Redirecting images to the script
The following will redirect all images under wp-content to the script, but only for webp-enabled browsers.
Insert the following in the server context of your configuration file (usually found in /etc/nginx/sites-available). "The server context" refers to the part of the configuration that starts with "server {" and ends with the matching "}".
location ~* ^/?wp-content/.*\.(png|jpe?g)$ {
  add_header Vary Accept;
  if ($http_accept !~* "webp"){
    break;
  }
  try_files
    /nonexisting-because-try-files-needs-fallback
    /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content
    ;
}

Beware when copy/pasting: You might get html-encoded characters. Verify that the ampersand before "wp-content" isn't encoded
If you have moved wp-content to a non-standard place, you must change accordingly. Especially note that you must also change the wp-content parameter to the script. It expects a relative path to wp-content (from document root) and is needed so the script can find the configuration file.
The xsource parameter helps the script finding the source file. It is only needed on some setups. You can try deleting it and see if it still works.
Beware that if you haven't enabled png conversion, you should replace "(png|jpe?g)" with "jpe?g", so the first line becomes:
location ~* ^/?wp-content/.*\.jpe?g$ {
If you cannot get this to work then perhaps you need to add the following to your mime.types configuration file:
image/webp webp;
If you still cannot get it to work, you can instead try method 2
Step 2: Redirecting directly to existing webp images.
Once you got this working, lets improve performance by redirecting directly to existing webp images. This step isn't necessary, as the script also does that - but invoking the php script takes more resources that the direct redirect. Also, a direct redirect will produce an ETag response header, which is increases caching performance.
The rules looks for existing webp files by appending ".webp" to the URL. So for this to work, you must configure WebP Express to store the converted files like that:
1. Set Destination folder to mingled
2. Set File extension to Append ".webp"
Now, place the following in the server context (replacing what you inserted in step 1):
location ~* ^/?wp-content/.*\.(png|jpe?g)$ {
  add_header Vary Accept;
  expires 365d;
  if ($http_accept !~* "webp"){
    break;
  }
  try_files
    $uri.webp
    /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content
    ;
}

Beware when copy/pasting: You might get html-encoded characters. Verify that the ampersand before "wp-content" isn't encoded
Again, beware that if you haven't enabled png conversion, you should replace "(png|jpe?g)" with "jpe?g".
Credits: This second step builds on Eugene Lazutkins solution.
Step 3:: Caching
In most cases you can and should allow images to be cached for a long period. If you do not want to do that, simply remove the "expires 365d;" line.
Step 4:: Routing requests for non-existing webps to the converter
Simply add the following rules below the ones you added in step 2:
location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ {
    try_files
      $uri
      /wp-content/plugins/webp-express/wod/webp-realizer.php?wp-content=wp-content
      ;
}

Again, beware that if you haven't enabled png conversion, you should replace "(png|jpe?g)" with "jpe?g".

I'm not strong in NGINX settings at all and I don't understand regular expressions yet. My NGINX config now looks like this (added the last two locations):
server {

  ...

  error_page 598 = @backend;

  ##########

  location @backend {
    try_files $uri $uri/ /$2$3 /$3 /index.php  =404;
    #   Путь к сокету PHP-FPM
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    #
    fastcgi_index index.php;
    fastcgi_read_timeout 360;
    #   Добавляем содержимое fastcgi_params.conf
    ################################################################################
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  REDIRECT_STATUS    200;
    ################################################################################
  }

  ############################################################################

  location  / {
    index  index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
  }

  ############################################################################

  location ~* /(\w+/)?(\w+/)?(.+\.(jpe?g|jpg|ico|gif|png|webp|css|js|pdf|txt|tar|woff|svg|ttf|eot|csv|zip|xml|yml))$ {
    access_log off;
    try_files $uri $uri/ /$2$3 /$3 /index.php?$args;
    expires max;
    add_header Access-Control-Allow-Origin *;
    add_header Cache-Control public;
  }

  ############################################################################

  location ~ ^/(\w+/)?(\w+/)?init.php {
    return 404;
  }

  location ~* \.(tpl.?)$ {
    return 404;
  }

  location ~ /\.(ht|git) {
    return 404;
  }

  location ~* \.php$ {
    return 598 ;
  }

  ################################################################################
  
  location ~* ^/?wp-content/.*\.(png|jpe?g)$ {
    add_header Vary Accept;
    if ($http_accept !~* "webp"){
    break;
    }
    try_files
    /nonexisting-because-try-files-needs-fallback
    /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content
    ;
  }

}

NGINX reloaded. But on the site, even after updating the cache, the address of the picture is not changed. Maybe I forgot something? Or is some NGINX config parameter interfering? Tell me please.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Skibin, 2019-04-17
@PbI6A_KuT

You work out the first location for statics, not reaching the second. Put it before the first static, or rewrite the expression so that jpg and png are not captured into it

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question