Как ускорить сайт на WordPress через кеширование в Nginx: рецепт для тех, кто устал ждать

Как ускорить сайт на WordPress через кеширование в Nginx: рецепт для тех, кто устал ждать

Рецепт от IT Аптека · Время лечения: 20–40 минут · Побочные эффекты: сайт начнёт работать

Состав статьи:
  • Диагноз: почему твой WordPress тормозит как дизельный трактор в мороз
  • Причины: 5 факторов, которые убивают скорость
  • Рецепт: полная настройка Nginx FastCGI Cache на Ubuntu — от установки до боевого конфига
  • Скрипт очистки кеша при публикации постов
  • Осложнения: что делать, когда «не работает»
  • Прогноз и профилактика

Диагноз: у тебя снова тормозит WordPress?

Картина знакомая: поставил WordPress, накидал плагинов, запустил. Сначала всё нормально. Потом — первые 500–1000 посетителей в сутки, и сервер начинает стонать. Time To First Byte (TTFB) — секунда. Две. PageSpeed Insights светит красным. Клиент звонит и говорит «сайт не грузится».

Ты лезешь в мониторинг, видишь 100% CPU на PHP-FPM, очередь запросов, и думаешь: «Ну и что теперь, брать сервер подороже?». Иногда — да. Но чаще — нет. Проблема не в железе. Проблема в том, что твой Nginx каждый раз тупо перекидывает запрос в PHP, PHP поднимает WordPress, WordPress идёт в базу, база думает, PHP рендерит HTML — и всё это ради страницы, которая не менялась последние три часа.

Лечим это кешем прямо на уровне Nginx. Он запоминает готовый HTML и отдаёт его следующим посетителям, не трогая PHP вообще. Называется это FastCGI Cache. После правильной настройки TTFB падает до 5–30 миллисекунд. Это не маркетинг — это физика.

После этого рецепта ты получишь:
  • Готовый конфиг Nginx с FastCGI Cache для WordPress на Ubuntu
  • Bash-скрипт для автоматической очистки кеша при публикации новых постов
  • Чеклист проверки, что всё работает как надо
  • Список типичных граблей — с готовыми командами для их обхода
[МЕМ: мем с дядей Фёдором «Я работаю с PHP-FPM» — 50мс TTFB vs без кеша — 2300мс TTFB]

Причины: почему WordPress без кеша — это боль

Давай без соплей. Вот что происходит при каждом запросе к незакешированному WordPress:

  1. PHP-FPM поднимает весь WordPress. Это десятки файлов, инициализация ядра, загрузка плагинов. Даже «лёгкий» сайт с 10 плагинами — это 50–100 мс только на bootstrap.
  2. WordPress идёт в MySQL. Главная страница — это легко 10–30 SQL-запросов. С плохо написанными плагинами — и все 100. База думает, блокировки, ждём.
  3. PHP генерирует HTML. Шаблон, виджеты, хуки, фильтры — всё это исполняется заново для каждого посетителя.
  4. Параллельные запросы убивают CPU. Пришло 50 человек одновременно — 50 процессов PHP, 50 соединений к базе. Сервер начинает задыхаться.
  5. Большинство страниц — статика по факту. Страница «О нас», статья в блоге, карточка товара — они меняются раз в день, если не реже. Но PHP честно пересобирает их каждый раз.
[СХЕМА: стрелочная схема «Запрос → Nginx → PHP-FPM → WordPress → MySQL → HTML → Ответ» vs «Запрос → Nginx → Кеш → Ответ (PHP и MySQL не трогаем)]
Короче: ты платишь за вычисления, которые уже делал. Кеш — это просто способ не делать одно и то же дважды. Nginx справляется с этим лучше всех плагинов типа W3 Total Cache или WP Super Cache, потому что работает до PHP — запрос до него просто не доходит.

Рецепт: настройка FastCGI Cache в Nginx для WordPress на Ubuntu

Что нам понадобится

  • Ubuntu 20.04 / 22.04 / 24.04 (на других дистрибутивах — аналогично, пути могут отличаться)
  • Nginx (не Apache, не OpenLiteSpeed — именно Nginx)
  • PHP-FPM (8.0, 8.1, 8.2, 8.3 — без разницы)
  • WordPress уже установлен и работает
  • Root или sudo-доступ к серверу

Если у тебя ещё нет связки Ubuntu + Nginx + PHP + WordPress — сначала разворачиваем стек с нуля (см. шаг 0). Если уже есть — пропускай сразу к шагу 1.

Шаг 0 (опционально): установка Nginx и PHP-FPM на Ubuntu с нуля

Если сервер голый — делаем так:

# Обновляем пакеты
sudo apt update && sudo apt upgrade -y

# Ставим Nginx
sudo apt install nginx -y

# Ставим PHP-FPM (пример для PHP 8.2)
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.2-fpm php8.2-mysql php8.2-xml php8.2-curl \
  php8.2-gd php8.2-mbstring php8.2-zip php8.2-intl php8.2-bcmath -y

# Ставим MySQL
sudo apt install mysql-server -y
sudo mysql_secure_installation

# Проверяем, что всё запустилось
sudo systemctl status nginx
sudo systemctl status php8.2-fpm
sudo systemctl status mysql

Создаём базу для WordPress:

sudo mysql -u root -p

# Внутри MySQL:
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'СЮДА_НОРМАЛЬНЫЙ_ПАРОЛЬ';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Качаем WordPress:

cd /var/www
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
[СКРИНШОТ: вывод команды ls -la /var/www/example.com — должны видеть wp-admin, wp-content, wp-includes]

Шаг 1: создаём директорию для кеша Nginx

Nginx будет складывать закешированные ответы на диск. Даём ему место:

sudo mkdir -p /var/cache/nginx/fastcgi
sudo chown -R www-data:www-data /var/cache/nginx
sudo chmod -R 755 /var/cache/nginx
Совет из практики: если у тебя SSD — отлично, кеш будет работать быстро. Если сервер с HDD и высокой нагрузкой — рассмотри tmpfs (RAM-диск). Но для начала обычный путь на диске — это уже кратный прирост.

Шаг 2: настраиваем глобальный конфиг Nginx (nginx.conf)

Открываем основной конфиг:

sudo nano /etc/nginx/nginx.conf

Находим блок http { ... } и добавляем внутрь него (перед закрывающей фигурной скобкой) строки для FastCGI Cache:

# Добавить в блок http {}

# Зона кеша: 10m — это размер памяти под ключи кеша (не сами данные)
# 1d — хранить кеш максимум 1 день
# max_size=2g — максимум 2 гигабайта на диске под файлы кеша
fastcgi_cache_path /var/cache/nginx/fastcgi
    levels=1:2
    keys_zone=WORDPRESS:10m
    inactive=1d
    max_size=2g;

# Ключ кеша: URI + метод + хост — это уникальный ID каждой страницы
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Сохраняем: Ctrl+O, Enter, Ctrl+X.

Шаг 3: создаём виртуальный хост Nginx для WordPress

Это центральная часть рецепта. Создаём конфиг сайта:

sudo nano /etc/nginx/sites-available/example.com

Вставляем весь конфиг целиком — с комментариями по каждому блоку:

# =============================================================
# Nginx конфиг для WordPress с FastCGI Cache
# Замени example.com на свой домен
# Замени php8.2-fpm на свою версию PHP
# =============================================================

# Переменная: пропускать кеш или нет
# По умолчанию — кешируем всё
map $http_cookie $skip_cache {
    default 0;
    # Залогиненные пользователи WordPress — мимо кеша
    "~*wordpress_logged_in" 1;
    # Пользователи, только что оставившие комментарий — мимо кеша
    "~*comment_author" 1;
    # Корзина WooCommerce — мимо кеша
    "~*woocommerce_cart_hash" 1;
    "~*woocommerce_items_in_cart" 1;
}

map $request_uri $skip_cache_uri {
    default 0;
    # Админка — без кеша
    "~*/wp-admin/" 1;
    # wp-login.php — без кеша
    "~*/wp-login.php" 1;
    # Страница оформления заказа WooCommerce — без кеша
    "~*/checkout/" 1;
    # Личный кабинет — без кеша
    "~*/my-account/" 1;
    # Корзина — без кеша
    "~*/cart/" 1;
    # wp-cron и xmlrpc — без кеша
    "~*/wp-cron.php" 1;
    "~*/xmlrpc.php" 1;
}

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # Перенаправляем HTTP → HTTPS (раскомментируй после настройки SSL)
    # return 301 https://$host$request_uri;

    root /var/www/example.com;
    index index.php index.html;

    # Логи
    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    # Лимиты и <a class="wpil_keyword_link" href="https://it-apteka.com/category/security/" target="_blank"  rel="noopener" title="Безопасность" data-wpil-keyword-link="linked"  data-wpil-monitor-id="1137">безопасность</a>
    client_max_body_size 64M;
    server_tokens off;

    # --------------------------------------------------------
    # Заголовок X-Cache-Status — чтобы видеть, из кеша или нет
    # --------------------------------------------------------
    add_header X-Cache-Status $upstream_cache_status;

    # --------------------------------------------------------
    # Статика отдаём напрямую — PHP не нужен
    # --------------------------------------------------------
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|webp|avif)$ {
        expires 1y;
        add_header Cache-Control &quot;public, immutable&quot;;
        access_log off;
        try_files $uri =404;
    }

    # --------------------------------------------------------
    # Скрываем чувствительные файлы
    # --------------------------------------------------------
    location ~ /\. {
        deny all;
    }

    location ~ /wp-config.php {
        deny all;
    }

    location = /xmlrpc.php {
        deny all;
    }

    # --------------------------------------------------------
    # Основной роутинг WordPress (Permalink)
    # --------------------------------------------------------
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # --------------------------------------------------------
    # PHP-FPM + FastCGI Cache
    # --------------------------------------------------------
    location ~ \.php$ {
        # Защита от Nginx + PHP-FPM path traversal
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # Сокет PHP-FPM (замени версию если нужно)
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        # Таймауты
        fastcgi_read_timeout 300;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 300;

        # Буферы (ускоряют отдачу)
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;

        # =====================================================
        # FastCGI CACHE — главная магия
        # =====================================================

        # Используем зону WORDPRESS из nginx.conf
        fastcgi_cache WORDPRESS;

        # Кешируем 200 и 301 ответы на 1 час
        fastcgi_cache_valid 200 301 1h;
        # 404 — на 15 минут
        fastcgi_cache_valid 404 15m;

        # Логика пропуска кеша
        fastcgi_cache_bypass $skip_cache $skip_cache_uri;
        fastcgi_no_cache $skip_cache $skip_cache_uri;

        # Если бэкенд упал — отдаём устаревший кеш (stale)
        fastcgi_cache_use_stale error timeout updating http_500 http_503;

        # Пока кеш обновляется — отвечает одним запросом к PHP, остальным — из старого кеша
        fastcgi_cache_lock on;
        fastcgi_cache_lock_timeout 5s;

        # Фоновое обновление кеша (не блокирует пользователя)
        fastcgi_cache_background_update on;

        # Метод кеширования — только GET и HEAD
        fastcgi_cache_methods GET HEAD;

        # Передаём реальный IP если за балансировщиком
        fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
    }

    # --------------------------------------------------------
    # Кеш для wp-cron — отключаем стандартный, запускаем через crontab
    # --------------------------------------------------------
    location = /wp-cron.php {
        internal;
    }
}

# =============================================================
# HTTPS блок (раскомментируй после certbot)
# =============================================================
# server {
#     listen 443 ssl http2;
#     listen [::]:443 ssl http2;
#     server_name example.com www.example.com;
#
#     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
#     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
#     ssl_protocols TLSv1.2 TLSv1.3;
#     ssl_prefer_server_ciphers on;
#
#     # ... остальное — копируй из HTTP-блока выше ...
# }

Активируем сайт и проверяем конфиг:

# Создаём симлинк
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

# Удаляем дефолтный сайт, если мешает
sudo rm -f /etc/nginx/sites-enabled/default

# Проверяем синтаксис конфига — ОБЯЗАТЕЛЬНО перед перезапуском
sudo nginx -t

# Если всё чисто — перезапускаем
sudo systemctl reload nginx
[СКРИНШОТ: вывод nginx -t — должно быть «syntax is ok» и «test is successful»]

Шаг 4: настраиваем PHP-FPM под WordPress

PHP-FPM по умолчанию настроен на «среднее» значение. Поправим его под WordPress:

sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Находим и правим эти параметры (или добавляем если нет):

; Количество одновременных PHP-процессов — считай по формуле:
; pm.max_children = (RAM в МБ - 256) / 50
; Пример для 2GB RAM: (2048 - 256) / 50 = ~35
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500

; Статус PHP-FPM (полезно для мониторинга)
pm.status_path = /status

; Таймаут запроса (секунды)
request_terminate_timeout = 300

Перезапускаем PHP-FPM:

sudo systemctl restart php8.2-fpm

Шаг 5: устанавливаем WordPress через WP-CLI

Если WordPress ещё не установлен — ставим через WP-CLI. Это быстрее и надёжнее, чем веб-установщик.

# Ставим WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
# Переходим в директорию WordPress
cd /var/www/example.com

# Создаём wp-config.php
sudo -u www-data wp config create \
  --dbname=wordpress \
  --dbuser=wpuser \
  --dbpass=СЮДА_НОРМАЛЬНЫЙ_ПАРОЛЬ \
  --dbhost=localhost \
  --dbcharset=utf8mb4

# Устанавливаем WordPress
sudo -u www-data wp core install \
  --url=http://example.com \
  --title="Мой сайт" \
  --admin_user=admin \
  --admin_password=СЛОЖНЫЙ_ПАРОЛЬ \
  --admin_email=admin@example.com \
  --skip-email
[СКРИНШОТ: вывод wp core install — «Success: WordPress installed successfully.»]

Шаг 6: скрипт автоочистки кеша при публикации постов

По факту, это самый важный шаг после настройки кеша. Ты опубликовал новую статью — а посетители ещё час видят старую главную страницу. Это лечится двумя способами: плагином или скриптом.

Вариант А: плагин Nginx Cache (для простых сайтов)

sudo -u www-data wp plugin install nginx-cache --activate

Идёшь в WordPress → Настройки → Nginx Cache, указываешь путь /var/cache/nginx/fastcgi — и плагин будет чистить кеш при обновлении записей.

Но у плагина есть ограничения: он чистит весь кеш целиком, что неэффективно. Для нагруженных сайтов — смотри Вариант Б.

Вариант Б: bash-скрипт точечной очистки кеша

Создаём скрипт:

sudo nano /usr/local/bin/nginx-cache-purge.sh
#!/bin/bash
# nginx-cache-purge.sh
# Скрипт точечной очистки FastCGI Cache Nginx для WordPress
# Вызывается из wp-config.php или cron

CACHE_DIR="/var/cache/nginx/fastcgi"
LOG_FILE="/var/log/nginx/cache-purge.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# Если передан URI — чистим только конкретную страницу
if [ -n "$1" ]; then
    URI="$1"
    echo "[$DATE] Purge URI: $URI" >> "$LOG_FILE"

    # Вычисляем ключ кеша: схема + метод + хост + URI
    # По умолчанию Nginx кеширует GET-запросы
    CACHE_KEY="httpGETyourdomain.com${URI}"
    CACHE_FILE=$(echo -n "$CACHE_KEY" | md5sum | awk '{print $1}')

    # Ищем файл по первым символам хеша (levels=1:2)
    SUBDIR1="${CACHE_FILE: -1}"
    SUBDIR2="${CACHE_FILE: -3:2}"
    FULL_PATH="${CACHE_DIR}/${SUBDIR1}/${SUBDIR2}/${CACHE_FILE}"

    if [ -f "$FULL_PATH" ]; then
        rm -f "$FULL_PATH"
        echo "[$DATE] Deleted: $FULL_PATH" >> "$LOG_FILE"
    else
        echo "[$DATE] Cache file not found: $FULL_PATH" >> "$LOG_FILE"
    fi
else
    # Без аргументов — чистим весь кеш
    echo "[$DATE] Full cache purge started" >> "$LOG_FILE"
    find "$CACHE_DIR" -type f -delete
    echo "[$DATE] Full cache purge done" >> "$LOG_FILE"
fi
sudo chmod +x /usr/local/bin/nginx-cache-purge.sh
sudo chown www-data:www-data /usr/local/bin/nginx-cache-purge.sh

Тестируем:

# Полная очистка кеша
sudo -u www-data /usr/local/bin/nginx-cache-purge.sh

# Проверяем лог
tail -20 /var/log/nginx/cache-purge.log

Вариант В: через WordPress хук (для разработчиков)

Добавляем в functions.php темы или в плагин-мю:

# Создаём mu-plugin для автоочистки кеша
sudo nano /var/www/example.com/wp-content/mu-plugins/nginx-cache-clear.php
<?php
/**
 * MU Plugin: Nginx FastCGI Cache Purge
 * Очищает кеш при сохранении/обновлении записей
 */

// При публикации или обновлении поста
add_action('save_post', 'nginx_cache_purge_on_save', 10, 2);
function nginx_cache_purge_on_save($post_id, $post) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if ($post->post_status !== 'publish') return;
    
    // Чистим весь кеш (можно сделать точечным — по URL поста)
    shell_exec('sudo -u www-data /usr/local/bin/nginx-cache-purge.sh 2>/dev/null');
    
    // Логируем
    error_log('[Nginx Cache] Purged on post save: ' . $post_id);
}

// При смене темы или настроек
add_action('switch_theme', 'nginx_cache_full_purge');
add_action('update_option_blogdescription', 'nginx_cache_full_purge');
function nginx_cache_full_purge() {
    shell_exec('sudo -u www-data /usr/local/bin/nginx-cache-purge.sh 2>/dev/null');
}
sudo chown www-data:www-data /var/www/example.com/wp-content/mu-plugins/nginx-cache-clear.php

Шаг 7: SSL через Let’s Encrypt (Certbot)

Кеш работает и по HTTP, но без HTTPS сайт теряет позиции в поиске. Ставим сертификат:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com

Certbot сам пропишет SSL в конфиге Nginx. После этого раскомментируй HTTPS-блок из шага 3 и проверь, что редирект с HTTP работает.

# Автообновление сертификата — certbot уже добавляет таймер systemd
sudo systemctl status certbot.timer

Шаг 8: проверяем, что кеш работает

Самый быстрый способ — смотреть заголовок X-Cache-Status:

# Первый запрос — MISS (PHP отработал, результат закешировался)
curl -I http://example.com | grep X-Cache-Status

# Второй запрос — должен быть HIT (отдал из кеша, PHP не трогали)
curl -I http://example.com | grep X-Cache-Status
[СКРИНШОТ: вывод curl с заголовком X-Cache-Status: HIT]

Значения заголовка:

  • HIT — страница из кеша. PHP не трогали. Всё работает.
  • MISS — первый запрос, кеш только заполняется. Норма.
  • BYPASS — запрос попал под условие пропуска (залогиненный пользователь, корзина и т.д.).
  • EXPIRED — кеш устарел, идёт обновление.
  • STALE — бэкенд упал, отдаётся старый кеш. Жить можно.
Проверь TTFB до и после: открой Chrome DevTools → Network → выбери главную страницу → смотри Waiting (TTFB). До кеша: 500–2000 мс. После: 5–50 мс. Если меньше 50 — всё сделал правильно.

Шаг 9 (бонус): настройка wp-cron через системный cron

WordPress по умолчанию запускает wp-cron при каждом визите — это лишняя нагрузка. Отключаем и переводим на системный cron:

# Добавляем в wp-config.php
sudo -u www-data wp config set DISABLE_WP_CRON true --raw
# Добавляем задачу в crontab
sudo crontab -u www-data -e

# Добавляем строку:
*/5 * * * * cd /var/www/example.com && php wp-cron.php > /dev/null 2>&1

Осложнения: что делать, если не работает

Чеклист диагностики
  1. Всегда начинай с sudo nginx -t — синтаксические ошибки в конфиге убивают всё
  2. Смотри логи: sudo tail -50 /var/log/nginx/error.log
  3. Смотри логи PHP-FPM: sudo tail -50 /var/log/php8.2-fpm.log
  4. Проверяй права на кеш: ls -la /var/cache/nginx/ — владелец должен быть www-data

Проблема: Nginx не запускается после изменения конфига

# Проверяем синтаксис
sudo nginx -t

# Смотрим подробные ошибки
sudo journalctl -xeu nginx.service | tail -30

Типичные причины: лишняя запятая в конфиге, неправильный путь к сокету PHP-FPM, указана зона кеша которой нет в nginx.conf.

Проблема: 502 Bad Gateway

# Проверяем, что PHP-FPM запущен
sudo systemctl status php8.2-fpm

# Проверяем путь к сокету
ls -la /run/php/
# Должен быть файл php8.2-fpm.sock

# Если сокета нет — перезапускаем PHP-FPM
sudo systemctl restart php8.2-fpm

Если сокет есть, но 502 продолжается — проверяем права:

# Nginx и PHP-FPM должны использовать одного пользователя
grep "^user" /etc/nginx/nginx.conf
grep "^user\|^listen.owner" /etc/php/8.2/fpm/pool.d/www.conf

Проблема: X-Cache-Status всегда MISS

Кеш не записывается. Проверяем:

# Права на директорию кеша
ls -la /var/cache/nginx/fastcgi/

# Ставим диагностику: смотрим, появляются ли файлы после запросов
watch -n 1 'find /var/cache/nginx/fastcgi -type f | wc -l'
# В соседнем терминале:
curl -s http://example.com > /dev/null
curl -s http://example.com > /dev/null

# Если файлы не появляются — проверяем, что зона WORDPRESS объявлена в nginx.conf
grep -n "fastcgi_cache_path" /etc/nginx/nginx.conf

Проблема: X-Cache-Status всегда BYPASS

Кеш обходится для всех запросов. Смотрим в cookies:

# Проверяем, нет ли в браузере WordPress-куки
curl -v --cookie "" http://example.com 2>&1 | grep -i "x-cache\|cookie\|bypass"

# Если ты залогинен в WP-Admin — выйди и проверь из инкогнито-вкладки

Проблема: сайт отдаёт устаревший контент после публикации поста

# Ручная очистка кеша
sudo -u www-data /usr/local/bin/nginx-cache-purge.sh

# Проверяем, работает ли mu-plugin
sudo -u www-data wp eval 'do_action("save_post", 1, get_post(1));'

# Проверяем права на скрипт очистки
ls -la /usr/local/bin/nginx-cache-purge.sh
# Должно быть: -rwxr-xr-x 1 www-data www-data

Проблема: WooCommerce — корзина и checkout кешируются

Это критично. Проверяем, что в конфиге прописаны исключения:

grep -A5 "skip_cache_uri" /etc/nginx/sites-available/example.com
# Должны видеть: checkout, cart, my-account

# Также добавляем исключение по cookie WooCommerce
grep -A10 "skip_cache" /etc/nginx/sites-available/example.com
# Должны видеть: woocommerce_cart_hash, woocommerce_items_in_cart

Проблема: WordPress не видит реальный IP пользователя (все запросы с 127.0.0.1)

sudo nano /etc/nginx/sites-available/example.com

# Добавить в server {} блок:
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

Прогноз: что мы сделали и чего ждать

Итог

Короче, по факту ты сделал следующее:

  • Настроил Nginx FastCGI Cache с зоной WORDPRESS
  • Прописал умные исключения — кеш обходит залогиненных пользователей, WooCommerce, корзину и админку
  • Настроил PHP-FPM с адекватными лимитами под реальную нагрузку
  • Добавил скрипт и хук для очистки кеша при публикации постов
  • Отключил wp-cron от посетителей и перевёл на системный cron
Что получаешь на выходе
  • TTFB для закешированных страниц: 5–50 мс вместо 500–3000 мс
  • CPU на PHP-FPM: снижение в 10–50 раз для типичного блога/новостного сайта
  • Сайт выдерживает в 20–50 раз больше одновременных посетителей без апгрейда железа
  • При падении бэкенда (PHP или MySQL) — посетители получают стейл-кеш, а не белый экран

Профилактика: что делать дальше

  • Настрой мониторинг TTFB — через UptimeRobot, BetterUptime или Zabbix. Если TTFB вырос — первым делом смотри, не переполнился ли кеш и не сломался ли скрипт очистки.
  • Следи за размером кешаdu -sh /var/cache/nginx/fastcgi/. Если растёт бесконтрольно — уменьши max_size или inactive в конфиге зоны.
  • Обновляй PHP — каждая минорная версия PHP быстрее предыдущей. PHP 8.3 быстрее 8.0 примерно на 15–20% по бенчмаркам.
  • Используй OPcache — это кеш скомпилированного PHP-кода. Проверяй: php -r "phpinfo();" | grep opcache.enable. Должно быть On.
# Проверяем OPcache одной командой
php -r "echo ini_get('opcache.enable') ? 'OPcache включён' : 'OPcache ВЫКЛЮЧЕН — срочно включи!';"

# Если выключен — правим php.ini
sudo nano /etc/php/8.2/fpm/php.ini
# Находим и ставим:
# opcache.enable=1
# opcache.memory_consumption=256
# opcache.interned_strings_buffer=16
# opcache.max_accelerated_files=10000
# opcache.revalidate_freq=2

sudo systemctl restart php8.2-fpm
Нужен сервер под WordPress? Для небольшого сайта (до 10 000 визитов в сутки) с FastCGI Cache хватит VPS с 1–2 vCPU и 2 GB RAM. Ключевые параметры выбора: скорость дисков (NVMe лучше SSD, SSD лучше HDD), наличие датацентра в регионе твоих пользователей и нормальная техподдержка. Протестируй скорость диска после аренды: dd if=/dev/zero of=/tmp/test bs=1M count=512 oflag=dsync — меньше 200 MB/s на запись означает HDD или медленный SSD.

Вопросы и обратная связь

Если что-то пошло не так — пиши в комментарии. Описывай: дистрибутив, версию Nginx, версию PHP и что конкретно выводит nginx -t и curl -I. С этим набором данных лечится 90% случаев.

 

over_dude
Author: over_dude

Руководитель ИТ / Кризис-менеджер 25 лет в IT: от инженера в МегаФоне до руководителя отдела. Знаю, как выглядит бардак: нестабильные сети, устаревшая инфраструктура, конфликты в команде, раздутые сроки. Помогаю бизнесу выходить из кризиса: навожу порядок в легаси, стабилизирую то, что разваливается, выстраиваю прогнозируемые процессы. Дважды возвращал к жизни ИТ-структуры — знаю цену хаосу. 📍 Ищу проект для полной реорганизации / стабилизации. 📬 Telegram: @over_dude ✉️ mail@it-apteka.com

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →

Мы ВКонтакте

IT-Аптека — советы, новости и помощь рядом.

Вступить в группу ВКонтакте →
Поделитесь:

Оставьте комментарий

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

Прокрутить вверх