Top.Mail.Ru
OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Переезд с Apache на Nginx: чек‑лист миграции и проверок

Практическое руководство по миграции с Apache на Nginx для админов и девопсов: инвентаризация vhost и .htaccess, перенос rewrite, прокси к бэкендам, PHP‑FPM, настройка логов и производительности, чек‑лист проверок без простоя и понятный план отката.
Переезд с Apache на Nginx: чек‑лист миграции и проверок

Когда сайт уже упирается в производительность Apache или конфигурации стали слишком разношерстными из‑за множества .htaccess, переход на Nginx выглядит логичным шагом. Но «просто заменить веб‑сервер» — путь к неожиданностям: отличия в синтаксисе, приоритетах правил, модели обработки PHP и поведении прокси легко приводят к 404/502, сломанным редиректам и просадке SEO. Ниже — подробный чек‑лист миграции, ориентированный на практику и быструю верификацию.

Стратегия миграции: параллельный запуск и план отката

Безопаснее всего запускать Nginx параллельно Apache на соседних портах или вторичном адресе. Это позволяет прогнать функциональные и нагрузочные тесты, не затрагивая боевой трафик. Затем выполняется переключение (порт/Firewall/DNS) и короткая валидация. Не забывайте о плане отката: четко описанные шаги, как вернуть Apache в дело за минуты. Для стенда удобно арендовать тестовый VDS, чтобы не трогать боевой сервер.

Правило ноль: миграция — это не только перенос конфигов. Это инвентаризация правил и согласование ожиданий приложения с новой моделью обработки запросов Nginx.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Карта соответствия: Apache → Nginx

Ключевые различия, которые определяют форму миграции:

  • vhostserver: виртуальные хосты Apache переезжают в server‑блоки Nginx. Директивы ServerName/ServerAlias соответствуют server_name.
  • .htaccess исчезают: Nginx не читает .htaccess. Все rewrite/доступ/индексы переносятся в конфиги. Это плюс к производительности и предсказуемости.
  • rewrite: синтаксис и приоритеты другие. В Nginx локации и try_files играют ключевую роль; избыточные rewrite упрощаются.
  • DirectoryIndexindex, Optionsautoindex, AllowOverride → отсутствует концептуально.
  • ProxyPass/ProxyPassReverseproxy_pass с явными заголовками и буферами.
  • mod_phpPHP‑FPM: FastCGI вместо встроенного интерпретатора. Нужна корректная передача SCRIPT_FILENAME и PATH_INFO.
  • MPM против событийной модели Nginx: иное влияние на память и конкуренцию сокетов.
  • Журналы: Combined формат можно воспроизвести через log_format; ротация — через системные инструменты.

Чек‑лист подготовки

  • Соберите список всех vhost: домены, поддомены, порты, TLS/ALPN, требования к HTTP/2/HTTP/3.
  • Слейте все .htaccess в единый реестр: редиректы, правила ЧПУ, ограничения доступа, Basic‑Auth, кеш‑контроль, CORS. Отмечайте приоритеты и порядок.
  • Инвентаризируйте PHP: версии, расширения, лимиты (memory_limit, max_execution_time, post_max_size, upload_max_filesize), особенности PATH_INFO.
  • Опишите прокси‑бэкенды: адреса upstream (PHP‑FPM, Node.js, Python/WSGI, Go), таймауты, поддержка WebSocket/SSE, требования к буферизации.
  • Проверьте TLS: цепочки сертификатов, ключи, шифры, OCSP‑Stapling. Путь хранения и права. Если требуется выпуск/подмена, оформите SSL‑сертификаты заранее.
  • Уточните лимиты и загружаемые файлы: целевые значения client_max_body_size, ожидаемые типы и объемы.
  • Подготовьте SEO‑карту редиректов: канонические домены, хвосты слешей, HTTP→HTTPS, перевод старых URL. Приоритизируйте 301 над 302.
  • Учтите реальный IP за балансировщиками/CDN: план real_ip_header и доверенных источников.
  • Определите требования к производительности: RPS, пиковые нагрузки, целевая латентность, кеш‑стратегии (статические, микрокеш).
  • Опишите мониторинг и логи: форматы, ротацию, алерты по 4xx/5xx, объемы логов.

Для выбора архитектуры и компромиссов полезно взглянуть на актуальное сравнение Nginx и Apache.

Схема server‑блоков и локаций в Nginx

Базовый каркас Nginx

Стартовый скелет для изоляции виртуальных хостов и чёткой логики:

user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    multi_accept on;
}

http {
    include mime.types;
    default_type application/octet-stream;
    log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent"';
    access_log /var/log/nginx/access.log combined;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65s;
    types_hash_max_size 4096;

    server {
        listen 80;
        server_name example.com www.example.com;
        root /var/www/example/public;
        index index.php index.html;

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass unix:/run/php/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_read_timeout 60s;
        }

        location ~* \.(css|js|png|jpe?g|gif|svg|webp|ico)$ {
            expires 30d;
            access_log off;
        }
    }
}

Важно: директива root действует в пределах контекста; при использовании alias для подкаталогов следите за формами путей (см. раздел «Частые грабли»).

Миграция rewrite и try_files

Большая часть «магии» .htaccess — это две категории: простые редиректы и внутренние перезаписи к фронт‑контроллеру. В Nginx вместо каскадов RewriteRule чаще выигрывает try_files.

Примеры переноса:

# Apache: Redirect 301 /old /new
# Nginx — эквивалент в server:
location = /old {
    return 301 /new;
}

# Apache: RewriteRule ^category/(.*)$ /catalog/$1 [R=301,L]
# Nginx:
rewrite ^/category/(.*)$ /catalog/$1 permanent;

# Apache (WordPress/фронт-контроллер):
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule . /index.php [L]
# Nginx (эквивалент через try_files):
location / {
    try_files $uri $uri/ /index.php?$args;
}

Где у Nginx отличия:

  • Приоритет: location выбирается до применения rewrite, а rewrite внутри локации применяются по ходу обработки. Не смешивайте глобальные и локальные правила без необходимости.
  • Флаги QSA, NC, L имеют иные соответствия. Объединение аргументов запроса в Nginx делается явно: /path?$args&new=value.
  • Регулярные выражения используют синтаксис PCRE; обратите внимание на экранирование и порядок локаций (~, ~*, =, префиксные).

Прокси к бэкендам: proxy_pass и заголовки

Перенос ProxyPass на Nginx требует явной передачи заголовков и корректной буферизации. Базовый шаблон:

upstream app_backend {
    server 127.0.0.1:3000;
    keepalive 32;
}

location /api/ {
    proxy_pass http://app_backend;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering on;
    proxy_buffers 16 8k;
    proxy_busy_buffers_size 64k;
    proxy_read_timeout 60s;
}

# WebSocket/СSE:
location /ws/ {
    proxy_pass http://app_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 1d;
    proxy_buffering off;
}

Частая причина 502/504 — несовпадение таймаутов и буферов с реальными профилями ответов. Если бэкенд отдаёт крупные JSON или генерирует ответ долго, увеличьте proxy_read_timeout, а для потоковых ответов отключите буферизацию.

Поток запросов через Nginx к бэкенду и WebSocket

PHP‑FPM: аккуратная передача скриптов и PATH_INFO

Переезд с mod_php требует пересборки цепочки FastCGI. Ключевые моменты:

  • fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; — путь к скрипту. Не путать с request_filename при сложных alias.
  • Если используется PATH_INFO, добавьте fastcgi_param PATH_INFO $fastcgi_path_info; и настройте регулярную локацию для захвата.
  • Согласуйте лимиты: client_max_body_size в Nginx ≥ post_max_size в PHP, иначе будут 413/500.
  • Проверьте fastcgi_read_timeout и max_execution_time — они должны соответствовать ожиданиям приложения.
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_read_timeout 120s;
}

# Альтернативно, для "разрыва" PATH_INFO:
location ~ ^(.+\.php)(/.*)$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$1;
    fastcgi_param PATH_INFO $2;
}

Производительность: быстрые выигрыши

Переход на Nginx уже даёт профит по статике и конкуренции соединений, но есть быстрые твики:

  • Сетевые параметры: worker_processes auto, разумные worker_connections, включенный sendfile, tcp_nopush, tcp_nodelay.
  • Кэширование статики: длительные expires, аккуратные Cache-Control, ETag/Last-Modified для экономии трафика. Смотрите также наш материал про настройку Cache-Control и ETag для статики.
  • open_file_cache: уменьшает статс‑звонки к FS под нагрузкой.
  • Upstream keepalive: снижает накладные расходы на частые короткие запросы к бэкенду.
  • Микрокеш для динамики (если уместно): секунда‑две кэша часто дают сильное сглаживание пиков.
  • Буферизация прокси: подгоните proxy_buffers/proxy_busy_buffers_size под типичные ответы, чтобы избежать лишних дисковых операций.
http {
    open_file_cache max=10000 inactive=60s;
    open_file_cache_valid 120s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

Журналы и мониторинг

Чтобы не терять совместимость с текущей аналитикой, настройте формат, близкий к Apache Combined:

log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent"';
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log warn;

Минимальные алерты: всплески 5xx и рост латентности upstream. На этапе миграции включите временно повышенный уровень логирования для проблемных локаций. Заодно проверьте защитные заголовки — поможет наш гайд по HTTP security headers.

Проверки перед переключением

Прогоняем функционал, метрики и SEO‑критичные сценарии:

  • curl‑проверки: статические файлы (200), динамика (200), редиректы (301/308), HEAD/GET идентичны по заголовкам к Apache.
  • Коды и заголовки: Content-Type, Cache-Control, Vary, ETag, Last-Modified, Location у редиректов.
  • Пути: чувствительность к слешу, регистру и завершающим слешам; файл /robots.txt, /sitemap.xml, /.well-known/.
  • Загрузки: граничные размеры POST/файлов; корректность 413/422/500 и сообщений.
  • Аутентификация: Basic‑Auth, куки, сессии PHP; кросс‑доменные запросы, если используется CORS.
  • Потоки: WebSocket/SSE, таймауты, отсутствие лишней буферизации.
  • Кеш: статика с правильным TTL; условные запросы (If-Modified-Since/If-None-Match).
# Примеры быстрых тестов
curl -I http://127.0.0.1:8080/
curl -I -L http://127.0.0.1:8080/old
curl -I -H "Accept-Encoding: gzip" http://127.0.0.1:8080/style.css
curl -I http://127.0.0.1:8080/robots.txt
curl -I http://127.0.0.1:8080/.well-known/acme-challenge/test
curl -I -H "Connection: upgrade" -H "Upgrade: websocket" http://127.0.0.1:8080/ws/

Переключение трафика без простоя

Три базовых подхода:

  • Перепривязка портов: Nginx слушает 80/443, Apache временно уходит на 8080/8443. После проверки — остановка Apache.
  • Firewall DNAT/REDIRECT: трафик направляется на новый порт/процесс, быстрое возвратное переключение при откате.
  • DNS с низким TTL: заранее уменьшите TTL, затем смените A/AAAA. Учитывайте кеши клиентов и промежуточных резолверов.
# Проверка конфигов
nginx -t

# Грациозная перезагрузка
nginx -s reload
systemctl reload nginx

# Диагностика занятых портов
ss -ltnp | grep ':80\|:443'

Частые грабли

  • Порядок location: регулярные локации перехватывают больше, чем ожидается; используйте = для точных совпадений и корректные префиксы.
  • root vs alias: при alias путь строится иначе. Для location /img/ с alias /data/images/ запрос /img/a.jpg ищется по пути /data/images/a.jpg — не добавляйте лишний суффикс.
  • Зацикливание редиректов: проверяйте условия редиректов с учетом протокола/домена; храните канонический домен в одной директиве.
  • Размеры запросов: 413 из‑за маленького client_max_body_size при больших загрузках; синхронизируйте с PHP.
  • 502 при PHP: неверный путь к сокету fastcgi_pass или ошибка SCRIPT_FILENAME. Смотрите error.log PHP‑FPM и Nginx.
  • Заголовок Host: без proxy_set_header Host $host; многие бэкенды дают 404/400.
  • Кодировки: явно задайте charset при необходимости и проверьте отдачу статических файлов.
  • Индекс: index index.php index.html; — порядок важен для фронт‑контроллеров.
  • Права и SELinux/AppArmor: проверьте доступ Nginx к web‑root, сокетам PHP‑FPM и каталогам временных файлов.

Контрольный чек‑лист перед выкладкой

  • Все vhost хозяйства заведены серверами с корректными server_name и корнями.
  • Критичные rewrite перенесены и покрыты автотестами или ручными сценариями.
  • PHP через PHP‑FPM работает, загружаются большие файлы, корректны таймауты.
  • Прокси к бэкендам стабильны, включены нужные заголовки, WebSocket/SSE проверены.
  • Логи пишутся, ротация настроена, уровни ошибок на время миграции повышены.
  • Параметры производительности соответствуют целям: keepalive, буферы, кеш статики.
  • Канонические редиректы (HTTP→HTTPS, www↔non‑www, слеши) отрабатывают единственным прыжком 301.
  • Реальный IP посетителя восстанавливается (если есть внешний балансировщик/CDN).
  • Проверены /robots.txt, /sitemap.xml, /.well-known/ и ответы на HEAD.
  • Описан и проверен план отката: как вернуть Apache или старый маршрут трафика.
FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Откат и документация

Откат — не поражение, а гарантия контроля рисков. Держите рядом рабочие юниты и конфиги Apache, сохраните старые правила редиректов, зафиксируйте команды возврата портов или изменения правил Firewall. После успешного перехода обновите документацию: реестр серверов, upstream‑пулы, чек‑лист эксплуатации и точки мониторинга.

Миграция с Apache на Nginx — это проект: инвентаризация, перенос логики, верификация, оптимизация и устойчивая эксплуатация. Хороший чек‑лист экономит часы ночных разбирательств.

Следуя этому плану, вы перенесете сервисы без сюрпризов, получите предсказуемый стек и заодно улучшите производительность и управляемость инфраструктуры.

Поделиться статьей

Вам будет интересно

Nginx SSI и подзапросы: сборка страниц из блоков с кэшированием OpenAI Статья написана AI Fastfox

Nginx SSI и подзапросы: сборка страниц из блоков с кэшированием

Практическое руководство по Nginx SSI и subrequest: сборка страницы из блоков, фрагментное кэширование, разделение гостей и автори ...
Мониторинг OPcache: метрики, алерты и быстрая диагностика утечек OpenAI Статья написана AI Fastfox

Мониторинг OPcache: метрики, алерты и быстрая диагностика утечек

OPcache ускоряет PHP, но под нагрузкой может «захлебнуться»: заканчивается память, растёт фрагментация, падает hit rate. Разбираем ...
rclone для больших файлов: multipart‑загрузки, параллелизм и контроль памяти OpenAI Статья написана AI Fastfox

rclone для больших файлов: multipart‑загрузки, параллелизм и контроль памяти

Большие файлы и S3 требуют точной настройки rclone: multipart‑загрузка, параллелизм потоков, контроль памяти и полосы, устойчивост ...