WordPress на сервере: частые ошибки и решения
На своём VPS WordPress ломается не так, как на шаред-хостинге: сайт просит FTP-доступ для обновления, все страницы кроме главной отдают 404, медиатека отвечает 413 Request Entity Too Large, браузер уходит в ERR_TOO_MANY_REDIRECTS. Почти все ошибки WordPress на сервере — не баги движка, а стык между PHP-FPM, веб-сервером, правами на файлы и памятью. Ниже — как понять, какой слой сломался, и что в нём чинить.
Содержание
- С чего начинать разбор ошибок WordPress
- Права и владелец: запрос FTP и «не удалось создать директорию»
- 404 на всех страницах, кроме главной
- Загрузка файлов и таймауты: 413, 504 и молча обрезанные настройки
- HTTPS и редиректы: ERR_TOO_MANY_REDIRECTS и смешанный контент
- Память, воркеры и база: OOM, max_children и «gone away»
- Какой сервер под WordPress брать в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →С чего начинать разбор ошибок WordPress
Запрос проходит четыре слоя: Nginx (или Apache) → PHP-FPM → WordPress → MariaDB. Ошибка каждого выглядит по-своему — это и есть способ не гадать по симптому.
| Симптом | Куда смотреть |
|---|---|
| 404 везде, кроме главной | правила rewrite веб-сервера |
413 Request Entity Too Large | client_max_body_size в Nginx |
| 502 / 504, «зависает» | pm.max_children, таймауты FPM |
| Пустая белая страница | debug.log, лимит памяти PHP |
| Просит FTP-доступ при обновлении | владелец файлов |
| «Ошибка соединения с базой данных» | MariaDB, следы OOM |
Сначала — кто ответил:
curl -sI https://example.com | head -5
tail -f /var/log/nginx/error.log
journalctl -u php8.3-fpm -n 50 --no-pager
Заголовок Server: nginx без X-Powered-By — до PHP запрос не дошёл. Дошёл, но пусто — включайте WP_DEBUG и WP_DEBUG_LOG в wp-config.php, задав свой путь вроде /var/log/wp/debug.log: по умолчанию файл ложится в wp-content и открыт по прямой ссылке любому. Каталог создайте заранее и отдайте www-data.
Два сообщения сбивают с толку. Письмо «Ваш сайт столкнулся с технической ошибкой» — не спам, а режим восстановления: по ссылке ?action=enter_recovery_mode админка открывается с отключённым сбойным плагином. А Briefly unavailable for scheduled maintenance значит, что оборвавшееся обновление оставило файл-флаг: rm -f /var/www/example.com/.maintenance.
Права и владелец: запрос FTP и «не удалось создать директорию»
Самая частая серверная ошибка выглядит так: при установке плагина открывается форма «Для обновления WordPress необходим доступ к вашему серверу по FTP» или приходит Installation failed: Could not create directory.
Механика простая: перед записью WordPress создаёт временный файл от имени процесса PHP. Не вышло — движок считает прямой доступ закрытым и переключается на ftpext. Значит, владелец файлов не тот, что у PHP-FPM.
ps -o user= -C php-fpm8.3 | sort -u
stat -c '%U:%G %a %n' /var/www/example.com/wp-content
Вывод root:root при пользователе www-data — диагноз поставлен.
chown -R www-data:www-data /var/www/example.com
find /var/www/example.com -type d -exec chmod 755 {} \;
find /var/www/example.com -type f -exec chmod 644 {} \;
chmod 640 /var/www/example.com/wp-config.php
Честно про два обхода. chmod -R 777 проблему «чинит» и делает сайт мишенью: любой процесс на машине, включая чужой скрипт с соседнего сайта, допишет код в wp-includes. define('FS_METHOD', 'direct'); убирает форму FTP, но прав не даёт: при чужом владельце придёт Не удалось создать директорию. — честнее, но не легче.
Если файлы выкатывает отдельный пользователь (deploy, Git, CI), chown слетает после каждого деплоя: тогда владельцем оставляют deploy, а запись для PHP выдают точечно через setfacl -R -d -m u:www-data:rwX .../wp-content/uploads. А на AlmaLinux и Rocky при верных 755 в логе бывает (13)Permission denied — это SELinux: chcon -R -t httpd_sys_rw_content_t wp-content/uploads; на Ubuntu и Debian такого слоя нет.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть WordPress404 на всех страницах, кроме главной
Классика переезда. Проверяется за десять секунд — постучитесь по «некрасивой» ссылке:
curl -s -o /dev/null -w '%{http_code}\n' 'https://example.com/?p=1' # 200
curl -s -o /dev/null -w '%{http_code}\n' 'https://example.com/hello-world/' # 404
?p=1 работает, ЧПУ — нет: дело в правилах перезаписи. В Nginx файла .htaccess не существует вообще, советы «проверьте .htaccess» тут бесполезны. Нужен один блок:
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Типичная ошибка — конфиг из инструкции по статическому сайту с try_files $uri $uri/ =404;. Вариант той же беды: пропущен index index.php, в error.log появляется directory index of "/var/www/example.com/" is forbidden, браузер видит 403.
На Apache нужны a2enmod rewrite и AllowOverride All вместо None: при None файл .htaccess игнорируется молча — ошибок в логе нет, просто 404. После правки пересохраните структуру ссылок или выполните wp rewrite flush --hard.
Загрузка файлов и таймауты: 413, 504 и молча обрезанные настройки
413 Request Entity Too Large — ответ Nginx, PHP запрос даже не увидел; в error.log строка client intended to send too large body: 27262976 bytes. Лечит client_max_body_size 64m; в http или server.
«Файл превышает upload_max_filesize, указанный в php.ini» — уже ответ WordPress: лимит в PHP. Правьте /etc/php/8.3/fpm/php.ini, затем systemctl reload php8.3-fpm:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 300
max_input_vars = 5000
Три подводных камня:
php -iпоказывает не то — у CLI отдельныйphp.iniв/etc/php/8.3/cli/. Значения FPM смотрите в админке: «Здоровье сайта → Информация → Сервер».- Пул перебивает php.ini — строка
php_admin_value[upload_max_filesize] = 8Mв/etc/php/8.3/fpm/pool.d/www.confприоритетнее:grep -r php_admin_value /etc/php/8.3/fpm/pool.d/. .user.iniв корне сайта кэшируется 300 секунд (user_ini.cache_ttl) — правка «не применяется» ещё пять минут.
504 Gateway Time-out при импорте или бэкапе — это upstream timed out (110: Connection timed out) while reading response header в логе Nginx. Нужны три согласованных значения: fastcgi_read_timeout 300s; у Nginx, request_terminated_timeout = 300s в пуле PHP-FPM и max_execution_time = 300 в PHP; поднимете одно — упрётесь в остальные.
Отдельно стоит max_input_vars: по умолчанию 1000, превышение не выдаёт ошибки вообще — меню на 200 пунктов сохраняется наполовину, настройки темы теряют поля, в debug.log тишина.
HTTPS и редиректы: ERR_TOO_MANY_REDIRECTS и смешанный контент
Браузер показывает ERR_TOO_MANY_REDIRECTS, curl считает круги:
curl -sIL -o /dev/null -w '%{num_redirects}\n' https://example.com
sudo -u www-data wp --path=/var/www/example.com option get siteurl
Адрес в базе не совпадает с фактическим. В wp_options осталось http://example.com или вариант с www, а веб-сервер редиректит на https:// без www. Лечится константами:
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');
Минус честный: поля в админке станут неактивными, а ссылки внутри статей останутся старыми — константы их не переписывают.
Сайт за обратным прокси или Cloudflare. TLS до WordPress не доходит, $_SERVER['HTTPS'] пуст, движок отдаёт http://-ссылки, прокси снова гонит на https://. Лечится в wp-config.php до строки require_once ABSPATH:
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
Со стороны прокси нужен proxy_set_header X-Forwarded-Proto $scheme;. Риск, о котором молчат мануалы: заголовку вы теперь верите на слово, а прислать его может кто угодно — держите бэкенд на 127.0.0.1, наружу только ufw allow 22/tcp и ufw allow 80,443/tcp.
Смешанный контент после переезда на HTTPS — замок перечёркнут, картинки не грузятся. Массовая замена — через WP-CLI, сначала с --dry-run и свежим дампом:
sudo -u www-data wp --path=/var/www/example.com search-replace \
'http://example.com' 'https://example.com' --all-tables --dry-run
Прямой UPDATE ... REPLACE() делать нельзя: настройки тем и виджетов хранятся сериализованными, рядом со строкой записана её длина. После http → https длина меняется, а число нет — блоки исчезают. WP-CLI пересобирает сериализацию.
Память, воркеры и база: OOM, max_children и «gone away»
Сайт падал ночью без нагрузки, а утром работает — почти наверняка отработал OOM killer: dmesg -T | grep -i 'killed process'.
[Tue Aug 25 03:11:44 2026] Out of memory: Killed process 8123 (php-fpm8.3)
total-vm:512864kB, anon-rss:196404kB, file-rss:0kB
Если жертвой стал mariadbd, симптом другой — «Ошибка установки соединения с базой данных», хотя виновата память; её разбор — в отдельной статье.
Дальше — арифметика. Размер воркера покажет ps -ylC php-fpm8.3 --sort:rss | awk 'NR>1 {print int($8/1024)" MB"}' | tail -5. Ориентиры: блог с кэширующим плагином — 45–70 МБ на воркер, WooCommerce с конструктором страниц — 120–190 МБ. Формула (RAM − память MariaDB − 350 МБ на систему) / размер воркера для 2 ГБ и MariaDB на 600 МБ даёт (2048 − 600 − 350) / 90 ≈ 12. Прописываем в /etc/php/8.3/fpm/pool.d/www.conf:
pm = ondemand
pm.max_children = 12
pm.process_idle_timeout = 30s
pm.max_requests = 500
pm.max_requests перезапускает воркер каждые 500 запросов — страховка от утечек в плагинах. Строка WARNING: [pool www] server reached pm.max_children setting (5), consider raising it означает очередь: запросы ждут воркера и получают 502 или 504. Поднимать значение вслепую бессмысленно — падение переедет в OOM.
Со стороны базы регулярны две вещи: MySQL server has gone away при импорте большого дампа лечится max_allowed_packet = 64M в /etc/mysql/mariadb.conf.d/50-server.cnf, а буфер InnoDB по умолчанию 128 МБ — для базы в 1–2 ГБ разумно 256–512 МБ.
Swap на VPS часто отсутствует, а он снимает большую часть ночных падений: fallocate -l 2G /swapfile, mkswap, swapon, строка в /etc/fstab, vm.swappiness=10. Это подушка, а не решение — сайт в swap медленный даже на NVMe. Тормозит панель, а не сайт — медленная админка; страница пустая — белый экран смерти.
Какой сервер под WordPress брать в MAATRIX
Половина разобранного выше — следствие тесной машины: OOM ночью, очередь на max_children, 504 на импорте. Конфигурация и есть профилактика.
Минимум: 1 vCPU, 2 ГБ RAM, 25–30 ГБ NVMe плюс 2 ГБ swap. Хватает на блог или визитку с кэшированием страниц: MariaDB с буфером 256 МБ и 8–10 воркеров PHP-FPM. Ограничение честное — это конфигурация под кэш. Магазин на WooCommerce с визуальным конструктором сюда не влезет: воркер весит под 180 МБ, и третий запрос в корзину кончается OOM. Вариант с 1 ГБ рабочим не считаю.
Комфортный вариант: 2 vCPU, 4 ГБ RAM, 60–80 ГБ NVMe. Три-пять небольших сайтов или один магазин: Redis под объектный кэш, буфер InnoDB на 1 ГБ, 15–20 воркеров, место под медиа и бэкапы. Магазину с тысячами товаров нужны 4 vCPU и 8 ГБ: узкое место — процессор на некэшируемых корзине и оплате.
Локация — Лондон. Для европейской аудитории это минимальный пинг и соседство с GDPR-периметром, а из Москвы до площадки 45–60 мс — на TTFB кэшированной страницы разница неразличима. Если сайт собирает персональные данные россиян и вы работаете по 152-ФЗ, берите Россию: пинг 5–15 мс и никакой трансграничной передачи. Франция равноценна Лондону, США — под американскую аудиторию.
Как это выглядит при заказе. WordPress есть в каталоге приложений MAATRIX и устанавливается автоматически — команды из этой статьи вручную вводить не нужно. Автоустановка работает на Ubuntu и Debian, включая 24.04 LTS: приезжает связка Nginx + PHP-FPM + MariaDB с владельцем www-data, рабочим try_files и вменяемыми лимитами загрузки, то есть без трёх самых частых поломок выше. Доступы появляются в личном кабинете, раздел «Доступ». Оплата — картами российских банков, по СБП, криптой или токеном MAAT. Тариф помогут выбрать разборы лучшего VPS для WordPress в Великобритании и ускорения на слабом VPS, конфигурации — на странице аренды VPS.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть WordPressОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
WordPress просит FTP-доступ при установке плагина. Что вписать?
Ничего: это признак того, что владелец файлов не совпадает с пользователем PHP-FPM. Выполните chown -R www-data:www-data /var/www/example.com — форма исчезнет. FS_METHOD без прав только сменит текст ошибки.
После включения ЧПУ все страницы отдают 404. Куда смотреть?
В конфиг Nginx: нужен try_files $uri $uri/ /index.php?$args;, а не =404; файла .htaccess в Nginx нет. На Apache проверьте a2enmod rewrite и AllowOverride All.
Сайт падает ночью и сам поднимается. Это атака?
Чаще нет: dmesg -T | grep -i 'killed process' покажет, что OOM killer убил php-fpm или mariadbd во время планового задания. Пересчитайте pm.max_children и добавьте swap.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.