Налаштовуємо віддачу 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 адреса не оприлюднюватиметься. Обов’язкові поля позначені *