← Все статьи

SiteGuard12 мин чтения

Изменения .env не работают в Laravel: как проверить кэш конфигурации

Вы изменили .env, сохранили файл и обновили страницу, но Laravel продолжает использовать прежний адрес сервиса, название приложения или режим работы. Повторное сохранение не помогает, а команда из терминала иногда показывает совсем другое поведение. В такой ситуации нужно проверить путь настройки до конкретного процесса, который выполняет запрос.

Причина может находиться в выбранном окружении, связи переменной с конфигурацией, готовом кеше или состоянии работающего приложения. Ниже — порядок диагностики для Laravel 13.x. Команды выполняет ответственный разработчик в согласованном окружении; для другой версии сначала сверяют документацию. Примеры названий, значений и проверок учебные.

1. Уточните, какое изменение не применяется

Начните с одного параметра и одного наблюдаемого действия. Формулировка «Laravel не видит env» слишком широкая. Полезная запись выглядит так: изменён параметр уведомления, в новом веб-запросе остаётся прежний текст, в фоновой задаче результат ещё не проверялся. Это позволяет построить проверяемую гипотезу вместо случайного удаления кешей.

Укажите имя переменной, конфигурационный ключ, ожидаемое значение и место использования. Если связь между ними неизвестна, её нужно найти в коде. Само появление новой строки в файле не заставляет приложение использовать её: разработчик должен явно подключить настройку к нужному поведению.

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

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

2. Проверьте приложение, каталог и способ запуска

Убедитесь, что редактируете файл того приложения, которое обслуживает нужный домен. При выпуске релизов рядом могут существовать текущий каталог, предыдущая версия и подготовленная новая сборка. Успешная команда в старом каталоге ничего не меняет в экземпляре, на который направлен веб-трафик.

Сверьте рабочий каталог, версию приложения, пользователя процесса и контейнер, если он используется. Отдельно проверьте, где выполняется Artisan: на хосте, внутри рабочего контейнера или в контейнере сборки. Совпадение имени проекта не означает совпадения файлов и окружения.

Для обзора окружения в Laravel предусмотрена команда php artisan about --only=environment. Сопоставьте её результат с обслуживающим веб-процессом через закрытую диагностику проекта. Сводка терминала описывает именно этот запуск; её нельзя автоматически переносить на PHP-FPM, обработчик очереди или другой узел.

Не меняйте права на весь проект, пытаясь заставить файл читаться. Проверьте конкретный путь, владельца, доступ исполняющего пользователя и принятую схему размещения секретов. Если настройки доставляет платформа, ручная правка внутри временного контейнера может исчезнуть при его замене. Исправление должно попасть в источник, из которого создаётся следующий экземпляр.

3. Найдите источник переменной и выбранный env-файл

В загрузчике окружения Laravel предусмотрен выбор дополнительного файла через внешнюю APP_ENV или аргумент --env. Если соответствующий файл существует, он может использоваться вместо обычного .env. При стандартном запуске не следует ожидать, что строка внутри уже выбранного файла задним числом переключит его на другой.

Проверьте и внешние переменные: настройки сервиса, контейнера, панели хостинга и процесса сборки. Документация phpdotenv объясняет приоритет уже существующих значений при неизменяемом репозитории переменных. В обычной конфигурации Laravel внешнее значение способно перекрыть запись из файла. Поэтому несколько одинаковых правок .env могут давать один и тот же старый результат.

Практический пример: в файле стоит учебная метка release-b, а окружение сборочного процесса задаёт release-a. Если конфигурацию собирают именно там, искать проблему только в содержимом файла недостаточно. Сравните разрешённый несекретный параметр на входе сборки и в запущенном приложении, затем определите единственный согласованный источник.

Название файла тоже не является доказательством его загрузки. При активном кеше загрузчик вообще пропускает чтение env-файла. Сначала установите, каким способом сформировано действующее значение, и лишь затем исправляйте конфликт. Не удаляйте все внешние переменные подряд: часть из них может быть необходима другим настройкам сервиса.

4. Свяжите env с конфигурацией и используйте config в приложении

Рекомендуемый Laravel путь: переменная окружения читается в конфигурационном файле, а прикладной код обращается к готовому конфигурационному ключу. Рассмотрим собственную настройку информационной плашки, которая не содержит секретов. В .env для учебного примера задают:

SITE_NOTICE_TEXT="Доставка работает по обычному графику"

В отдельном конфигурационном файле config/site.php разработчик возвращает массив:

<?php

return [
    'notice_text' => env('SITE_NOTICE_TEXT', ''),
];

Прикладной код получает значение через config('site.notice_text'). Такой пример позволяет проверить всю связь: имя переменной, имя файла, ключ массива и место вывода. Если код читает site.notice, изменение SITE_NOTICE_TEXT не исправит ошибку в названии ключа.

Проверьте также, не перезаписывает ли приложение нужный ключ позднее, например в собственном провайдере или настройках конкретного клиента. Временная подмена конфигурации в ходе выполнения отличается от исходного значения при загрузке. Полезно измерить параметр возле места использования, а не только сразу после старта приложения.

Не переносите чтение .env вручную в каждый контроллер. Это создаёт отдельный механизм конфигурации, который легко расходится с установленным порядком загрузки. Исправьте связь один раз и проверьте её при том же способе развёртывания, который используется на рабочем сайте.

5. Установите, используется ли кеш конфигурации

Согласно документации конфигурации Laravel, config:cache собирает параметры в единый файл. После этого фреймворк не загружает .env при веб-запросах и командах Artisan. Вызов env() получает только доступные внешние переменные либо значение по умолчанию, если соответствующей переменной нет.

Отсюда следуют два разных симптома. Старый config() может означать, что используется ранее подготовленная конфигурация. Пустой результат прямого env() в контроллере может означать, что код обходит предусмотренный конфигурационный слой. Вторую проблему не стоит маскировать постоянным отказом от кеширования.

ДействиеНазначениеЧто проверить после него
php artisan config:clearУдалить кеш конфигурацииИз какого источника следующий запуск получает параметры
php artisan config:cacheПодготовить кеш конфигурацииЗавершение команды и фактический ключ в нужном экземпляре

Проверяйте не только наличие файла, но и значение возле проблемного действия. Если кеш подготовлен с ошибочным внешним параметром, он может быть свежим по времени и всё равно неправильным по содержанию. Обновлённая дата файла не заменяет проверку результата.

Обратная ситуация тоже показательна: внешнюю переменную уже исправили, но конфигурационный ключ продолжает содержать значение, зафиксированное при предыдущей сборке. Прямой вызов env() и обращение через config() тогда описывают разные источники. Не выбирайте правильный результат голосованием между двумя выводами. Определите, какой путь реально использует проблемная операция, и обновите именно предусмотренную для неё конфигурацию.

6. Проверяйте значение без публикации секретов

Для диагностики обычно достаточно небольшого набора разрешённых полей. В API приложения Laravel есть метод configurationIsCached(), а также методы получения пути кеша и окружения. Следующий фрагмент иллюстрирует данные для уже существующего закрытого диагностического механизма после загрузки приложения:

$diagnostic = [
    'environment' => app()->environment(),
    'config_cached' => app()->configurationIsCached(),
    'notice_text' => config('site.notice_text'),
];

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

Для пароля или токена проверяйте наличие и результат разрешённой операции, а не печатайте значение. Успешная загрузка строки ещё не подтверждает её действительность у внешнего провайдера. Проверку подключения проводят отдельным безопасным действием без лишних отправок, списаний или повторного создания заказов.

Зафиксируйте, где получены данные: CLI, HTTP или очередь. Один и тот же диагностический фрагмент в разных процессах может обнаружить расхождение, которое было незаметно по сообщению «файл сохранён». После завершения разбора временные диагностические выводы убирают.

Сам признак наличия кеша не сообщает, когда долгоживущий обработчик загрузил свои параметры. Кроме того, объект подключения мог сохранить отдельную копию настройки при создании. Поэтому при спорном результате сравнивайте конфигурационный ключ, фактически используемый объект и время запуска процесса. Иначе новая строка в диагностике будет соседствовать со старым уже открытым подключением, а причина останется незамеченной.

7. Пересоберите конфигурацию в нужном окружении

Перед изменением сохраните прежние настройки и способ возврата к рабочей версии. Затем исправьте подтверждённый источник переменной и конфигурационный ключ. На стенде проверьте путь без кеша, после чего повторите проверку с кешированием. Так можно выявить ошибку, которая проявляется только в рабочей схеме запуска.

Для production подготовку кеша включают в согласованный процесс выпуска. Важно, чтобы в момент сборки были доступны именно целевые параметры. Перенос готовой конфигурации из тестового окружения вместе с приложением способен перенести и тестовые подключения. Поэтому окружение сборки входит в проверку релиза наравне с кодом.

Команда должна завершиться успешно. Если возникла ошибка синтаксиса, доступа или загрузки приложения, остановите распространение релиза и разберите её. Не считайте, что любое завершение Artisan означает подготовленный рабочий кеш; состояние текущего экземпляра проверяют отдельно.

Руководство по развёртыванию различает отдельные команды оптимизации. В частности, optimize:clear затрагивает также ключи стандартного кеш-хранилища. Для исправления конкретного конфигурационного параметра не нужно автоматически очищать всё подряд. Выбирайте действие по установленной причине и сохраняйте возможность сопоставить результат до и после него.

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

8. Обновите обработчики очереди и проверьте получение сигнала

Обработчики очереди Laravel сохраняют загруженное приложение в памяти. Новый HTTP-запрос и давно работающий queue:work поэтому могут использовать разное состояние. Если настройка влияет на письма, выгрузки или обработку заказов, проверка только страницы не завершает работу.

Штатная команда php artisan queue:restart предлагает обработчикам завершиться после текущего задания. Для последующего запуска нужен настроенный менеджер процессов. Сообщение об отправке сигнала не доказывает, что старый процесс уже закончил работу, а новый получил ожидаемые параметры.

Сигнал передаётся через кеш; нужно проверить доступность соответствующего хранилища и включённое получение таких сигналов. Если как раз меняются кеш-драйвер, адрес или префикс, старый обработчик и новая команда могут обращаться в разные места. Это отдельная проверяемая причина, почему обычный сигнал не приводит к ожидаемой смене процессов.

Сопоставьте время старта обработчика, версию приложения и результат контролируемого задания. Используйте безопасную задачу, не создающую реальную покупку или массовую рассылку. Длительное текущее задание может объяснять задержку обновления; решать вопрос его остановки нужно по принятой процедуре, учитывая завершённые действия и возможность повтора.

9. Учтите Octane, Horizon и окружение самого сервиса

Если HTTP обслуживает Laravel Octane, приложение также остаётся в памяти между запросами. Для перечитывания приложения предусмотрена команда php artisan octane:reload. Обычное обновление страницы браузера не выполняет эту работу.

Для Horizon используется собственный порядок развёртывания с php artisan horizon:terminate и последующим запуском менеджером процессов. Эти команды относятся к разным реально используемым сервисам; их не нужно запускать полным набором на каждом сайте. Сначала составьте список процессов проекта.

Отдельный уровень — внешние переменные самого сервиса. В конфигурации PHP-FPM предусмотрены настройки окружения пула и clear_env, по умолчанию очищающий наследуемое окружение перед добавлением заданных переменных. Поэтому наличие значения в вашей оболочке не доказывает его наличие у веб-обработчика.

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

10. Отделите серверную конфигурацию от сборки JavaScript

Когда изменение касается клиентского интерфейса, проверьте, откуда браузер получает параметр. Интеграция Laravel с Vite позволяет передавать переменные с префиксом VITE_ через import.meta.env. Это отдельный путь по сравнению с PHP-конфигурацией.

Согласно документации Vite, значения статически подставляются во время сборки. Изменение серверного файла после выпуска JavaScript не переписывает уже созданный файл. Для такого параметра нужна новая сборка с правильными входными значениями и её доставка пользователю.

Проверьте режим сборки, применяемые env-файлы и внешние переменные сборочного процесса. В режиме разработки после изменения env-файла требуется перезапуск сервера Vite. Это не повод перезапускать все серверные службы: сначала установите, что изменяемая настройка действительно относится к этой ветке.

Не добавляйте префикс VITE_ к серверному секрету ради доступности в интерфейсе: такие значения попадают в клиентский код. Для приёмки используйте публичную метку и идентификатор собранного ресурса. Если новая сборка уже опубликована, а конкретный браузер получает старую, дальше проверяют доставку статических файлов и кеширование ответа.

11. Проверьте изменение во всех нужных контекстах

Возьмём учебную смену текста плашки с варианта A на вариант B. На сайте работают два веб-экземпляра и отдельный обработчик очереди, который использует тот же конфигурационный ключ при подготовке служебного документа. Один успешный запрос проверяет только тот путь, которым он прошёл.

КонтекстРезультатСледующий шаг
CLI нового релизаВариант BПроверить веб-экземпляры и очередь отдельно
Веб-экземпляр 1Вариант BЗафиксировать релиз и источник результата
Веб-экземпляр 2Вариант AСравнить релиз, окружение и состояние кеша именно этого узла
Старый обработчик очередиВариант AПроверить обновление процесса и выполнение контрольного задания

Эта таблица описывает пример, а не результат проверки вашего сайта. Она показывает, почему случайное обновление страницы до первого правильного ответа создаёт ложное ощущение завершения. При нескольких узлах нужна подтверждённая проверка каждого предусмотренного пути.

После совпадения значений выполните исходное пользовательское действие. Проверьте правильный результат, отсутствие новых ошибок и нормальную обработку фоновых задач. Для изменения подключения одного текстового сравнения недостаточно: нужен разрешённый запрос к нужному ресурсу и подтверждение ожидаемого ответа.

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

12. Закрепите исправление в процессе выпуска

В итоговой записи укажите причину, источник параметра, конфигурационный ключ, затронутые процессы и доказательства приёмки. Формулировка «очистили кеш, стало работать» не объясняет, почему проблема не вернётся при следующем развёртывании. Полезнее зафиксировать конкретный конфликт или пропущенный шаг.

Включите проверку конфигурации в обычный выпуск: подготовить целевые параметры, собрать приложение, проверить ожидаемые значения, обновить необходимые процессы и выполнить контрольный сценарий. Если развёртывание остановилось на промежуточном шаге, его состояние должно быть видно исполнителю, а следующий узел не должен автоматически получать непроверенный вариант.

План возврата должен учитывать и код, и настройки. Возврат старого каталога при оставшемся новом окружении не обязательно восстанавливает прежнее поведение. Заранее определите совместимую пару и проверьте её для HTTP и фоновых действий. Это особенно полезно при смене подключений к базе, очереди или внешнему сервису.

Подключите SiteGuard для внешнего контроля HTTP-доступности сайта после изменения конфигурации. Применение конкретного параметра подтвердите проверкой в приложении.