Skip to content

Nginx / Apache

Настраивал nginx как production reverse proxy и frontend edge-слой для Dockerized-приложения.

Что настраивал на практике:

  • reverse proxy для PHP-FPM;
  • проксирование WebSocket/Reverb с корректными Upgrade / Connection заголовками;
  • HTTPS termination, redirect 80 -> 443, http2;
  • security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy);
  • отдача статических файлов и настройка cache headers (Cache-Control, expires, immutable);
  • точечное response caching через fastcgi_cache для публичных API-ответов;
  • rate limiting для динамики и чувствительных API-эндпоинтов;
  • разделение правил для hashed build-ассетов и прочей статики;
  • работа с precompressed-ассетами (gzip / brotli);
  • выборочное кэширование публичных API-ответов на уровне web-server.

Production-конфигурация

В production-конфиге настраивал:

  • upstream для app:9000 (PHP-FPM);
  • upstream для reverb:8080;
  • try_files-маршрутизацию для Laravel через index.php;
  • отдельные location-блоки для:
    • /build/ с агрессивным кэшированием hashed Vite-ассетов;
    • WebSocket endpoint;
    • чувствительных API-ручек (/api/login, /api/register, /api/password, /api/export);
    • общей динамики приложения.
  • snippets для выборочного fastcgi_cache публичного timezone endpoint-а.

Пример rate limit-подхода:

nginx
limit_req_zone $binary_remote_addr zone=rl_dynamic:20m rate=50r/s;
limit_req_zone $binary_remote_addr zone=rl_auth:20m rate=15r/s;
limit_req_status 429;

Использовал более строгие лимиты для auth/export endpoint-ов и отдельный лимитер для общей динамики.

Response cache на уровне nginx

Настраивал ограниченный fastcgi_cache для публичных API endpoint-ов.

Что учитывал в такой конфигурации:

  • отдельная cache zone и директория хранения;
  • TTL для успешных 200 ответов;
  • cache key, завязанный на схему, метод, host и URI;
  • bypass/no-cache условия по HTTP-методу;
  • диагностический заголовок X-Cache-Status;
  • защита от stampede через fastcgi_cache_lock;
  • отдача stale response во время обновления или временной ошибки upstream.

Такой cache включал точечно, только для безопасных публичных GET-ответов. Для приватных пользовательских API-ответов и динамических страниц глобальный web-server cache не включал.

Статика и кэширование

Настраивал отдачу frontend-ассетов через nginx:

  • hashed ассеты из /build/ кэшируются агрессивно:
    • Cache-Control: public, max-age=31536000, immutable;
  • прочая статика кэшируется отдельно и мягче;
  • для динамических HTML/приложения используются другие правила, без бессрочного кэша.

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

Gzip и Brotli

Настраивал схему с precompressed-ассетами:

  • генерация .gz и .br на этапе frontend build;
  • отдача готовых файлов через gzip_static on; и brotli_static on;;
  • fallback-цепочка:
    • br для клиентов с поддержкой Brotli;
    • gzip как запасной вариант;
    • исходный файл как последний fallback.

Проверка делается по response headers, например через Content-Encoding: br / gzip.

Brotli-модули в Docker-образе

Готовил production nginx-образ под Brotli:

  • сборка dynamic modules для nginx;
  • подключение модулей через load_module в nginx.conf;
  • разделение main nginx.conf и application conf.d/default.conf.

Модуль brotli_static сам по себе в конфиге недостаточен: он должен реально присутствовать в production-образе.

Docker / deploy-контекст

Работал с nginx в Docker production-схеме:

  • отдельный production Dockerfile для nginx;
  • копирование статического public/ и собранного public/build;
  • согласование nginx-конфига с CI/CD и release-потоком;
  • использование prebuilt nginx-образа в production deploy вместо сборки на сервере.

В таком подходе сервер получает уже готовый runtime-образ с конфигом, статикой и модулями, а на deploy делает только pull и restart.

Отдельно удобен подход с production nginx-образом, куда уже во время сборки попадают:

  • public и public/build;
  • конфиг nginx;
  • динамические модули brotli.

Apache

Есть также практический опыт работы с Apache.

На уровне задач он во многом пересекается с уже описанным опытом по nginx: настройка web-server слоя, проксирование запросов к приложению, работа со статикой, базовые правила безопасности и конфигурация production-окружения.

Сайт обновлен и проверен: