Настраиваем отдачу webp в nginx

На одном из сайтов, возникла необходимость внедрить формат изображений webp. Но так как не все браузеры поддерживают данный формат, нужно сделать так, чтобы пользователям, браузеры которых поддерживают этот формат выдавались .webp изображения, а всем остальным jpg/png. Всё это необходимо было сделать на связке nginx+php-fpm. Так как я не системный администратор, то обратился на фриланс, чтобы помогли мне в этом. А готовым решением, решил здесь поделится (вдруг кому-то понадобится).

Для того, чтобы всё заработало, нам нужно немного отредактировать только 2 файла NGINX:

  1. Глобальный конфигурационный файл: /etc/nginx/nginx.conf
  2. Конфигурационный файл самого домена: /etc/nginx/vhosts/login/site.com.ua.conf

В первый файл добавляем:

 map $http_accept $image {
	default 0;
	"~*image/webp,*/*" "1";
    }

Во второй:

if ($image) {
    rewrite ^(.*)\.(jpg|jpeg) $1.webp last;
}

В итоге, глобальный конфигурационный файл, у меня выглядит так:

user  apache;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
worker_connections  1024;
# Метод выбора соединений (для FreeBSD будет kqueue)
use                             epoll;
# Принимать максимально возможное количество соединений
multi_accept                    on;
}
http {
include       /etc/nginx/mime.types;
default_type  application/octet-stream;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Отключить вывод версии nginx в ответе
server_tokens off;
access_log  /var/log/nginx/access.log  main;
sendfile        on;
# Ограничивает объём данных, который может передан за один вызов sendfile(). Нужно для исключения ситуации когда одно соединение может целиком захватить воркер
sendfile_max_chunk  128k;
# Отправлять заголовки и и начало файла в одном пакете
tcp_nopush                      on;
tcp_nodelay                     on;
# Сбрасывать соединение если клиент перестал читать ответ
reset_timedout_connection       on;
# Разрывать соединение по истечению таймаута при получении заголовка и тела запроса
client_header_timeout           3;
client_body_timeout             5;
# Разрывать соединение, если клиент не отвечает в течение 3 секунд
send_timeout                    3;
# Задание буфера для заголовка и тела запроса
client_header_buffer_size       2k;
client_body_buffer_size         256k;
# Ограничение на размер тела запроса
client_max_body_size            128m;
#tcp_nopush     on;
#gzip  on;
map $http_accept $image {
default 0;
"~*image/webp,*/*" "1";
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/vhosts/*/*.conf;
server {
server_name localhost;
disable_symlinks if_not_owner;
listen 80;
listen [::]:80;
include /etc/nginx/vhosts-includes/*.conf;
location @fallback {
error_log /dev/null crit;
proxy_pass http://127.0.0.1:8080;
proxy_redirect http://127.0.0.1:8080 /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
access_log off ;
}
location ~ \.php$ {
try_files $fastcgi_script_name =404;
fastcgi_index			index.php;
fastcgi_param			script_FILENAME /scripts$fastcgi_script_name;
include				fastcgi_params;
}
}
}

И конфигурация домена для opencart (использую ISPmanager) так:

server {
server_name site.com.ua www.site.com.ua;
rewrite ^ https://site.com.ua$request_uri? permanent; 
charset off;
index index.html index.php;
disable_symlinks if_not_owner from=$root_path;
include /etc/nginx/vhosts-includes/*.conf;
include /etc/nginx/vhosts-resources/site.com.ua/*.conf;
#return 301 https://$host:443$request_uri;
return 301 https://site.com.ua$request_uri ;
error_log /dev/null crit;
set $root_path /var/www/login/data/www/site.com.ua;
root $root_path;
gzip on;
gzip_comp_level 9;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
if ($image) {
rewrite ^(.*)\.(jpg|jpeg) $1.webp last;
}
location / { 
location ~* ^.+\.(webp|jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff2)$ {
expires 365d;
}
rewrite ^/sitemap.xml$ /index.php?route=feed/google_sitemap last;
rewrite ^/googlebase.xml$ /index.php?route=feed/google_base last;
rewrite ^/system/download/(.*) /index.php?route=error/not_found last;
if (!-f $request_filename){
set $rule_3 1$rule_3;
}
if (!-d $request_filename){
set $rule_3 2$rule_3;
}
if ($uri !~ ".*.(jpg|jpeg|ico|gif|png|js|css)"){
set $rule_3 3$rule_3;
}
if ($rule_3 = "321"){
rewrite ^/([^?]*) /index.php?_route_=$1 last;
}
location ~ [^/]\.ph(p\d*|tml)$ {
try_files /does_not_exists @php;
}
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff2)$ {
expires 365d;
}
}
location ~ [^/]\.php(/|$) {
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
if (!-f $document_root$fastcgi_script_name) {
return  404;
}
fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f info@site.com.ua";
fastcgi_pass unix:/var/www/php-fpm/login.sock;
fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
try_files $uri =404;
fastcgi_index   index.php;
include         /etc/nginx/fastcgi_params;
}
ssi on;
location @php {
fastcgi_index index.php;
fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f info@site.com.ua";
fastcgi_pass unix:/var/www/php-fpm/login.sock;
fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
try_files $uri =404;
include fastcgi_params;
}
rewrite ^/zapchasti-dlia-smartfonov/ekrany-i-sensory/(.*)$ https://site.com.ua/zapchasti-dlia-smartfonov/lcd-displays/ permanent;
rewrite ^/uk/zapchasti-dlia-smartfonov/ekrany-i-sensory/(.*)$ https://site.com.ua/uk/zapchasti-dlia-smartfonov/lcd-displays/ permanent;
return 301 https://$host:443$request_uri;
access_log off;
listen 185.156.56.43:80 default_server;
}
server {
server_name site.com.ua www.site.com.ua;
if ($host ~* ^www.site.com.ua$) {
return 301 $scheme://site.com.ua$request_uri;
}
ssl on;
ssl_certificate "/var/www/httpd-cert/login/site.com.ua_le1.crtca";
ssl_certificate_key "/var/www/httpd-cert/login/site.com.ua_le1.key";
ssl_ciphers EECDH:+AES256:-3DES:RSA+AIS:!NULL:!RG4;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
add_header Strict-Transport-Security "max-age=31536000;";
ssl_dhparam /etc/ssl/certs/dhparam4096.pem;
charset off;
index index.html index.php;
disable_symlinks if_not_owner from=$root_path;
include /etc/nginx/vhosts-includes/*.conf;
include /etc/nginx/vhosts-resources/site.com.ua/*.conf;
error_log /dev/null crit;
ssi on;
set $root_path /var/www/login/data/www/site.com.ua;
root $root_path;
gzip on;
gzip_comp_level 9;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
if ($image) {
rewrite ^(.*)\.(jpg|jpeg) $1.webp last;
}
location / { 
location ~* ^.+\.(webp|jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff2)$ {
expires 365d;
}
rewrite ^/sitemap.xml$ /index.php?route=feed/google_sitemap last;
rewrite ^/googlebase.xml$ /index.php?route=feed/google_base last;
rewrite ^/system/download/(.*) /index.php?route=error/not_found last;
if (!-f $request_filename){
set $rule_3 1$rule_3;
}
if (!-d $request_filename){
set $rule_3 2$rule_3;
}
if ($uri !~ ".*.(jpg|jpeg|ico|gif|png|js|css)"){
set $rule_3 3$rule_3;
}
if ($rule_3 = "321"){
rewrite ^/([^?]*) /index.php?_route_=$1 last;
}
location ~ [^/]\.ph(p\d*|tml)$ {
try_files /does_not_exists @php;
}
}
location @php {
fastcgi_index index.php;
fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f info@site.com.ua";
fastcgi_pass unix:/var/www/php-fpm/login.sock;
fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$;
try_files $uri =404;
include fastcgi_params;
}
access_log off;
listen 185.156.71.55:443 ssl default_server http2;
}

Теперь же, браузерам которые выдают заголовок, что поддерживают .webp выдаются изображения .webp, а если нет, то jpg.

Читайте:  Как поставить счетчик на сайт
Настраиваем отдачу webp в nginx
5 (100%) 2 vote[s]

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *