Налаштовуємо віддачу WebP в nginx | Блог ТехноЭра

Налаштовуємо віддачу 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.

Читайте:  Як і де можна продати сайт

Leave a Comment