Переменные окружения
Любое нетривиальное приложение взаимодействует с внешним миром: использует базу данных, обращается к внешним сервисам (например, платежным), отправляет письма и получает список друзей, например, из Facebook. Для подавляющего большинства этих операций необходимы специальные параметры: ключи, пароли, адреса серверов и порты. Все эти параметры называются конфигурацией приложения.
Возникает вопрос, где хранить конфигурацию? Самый простой и самый неправильный ответ – прямо в приложении. Проблем у такого подхода две:
- Часть этих данных секретная. Хранить их в репозитории просто нельзя из-за возможных проблем с безопасностью. Любой кто имеет доступ к репозиторию сможет получить любой доступ. Правда еще есть вариант с шифрованием, но он выходит за рамки обсуждаемой темы (для интересующихся Ansible Vault).
- При изменении этих параметров придется заново "деплоить" (то есть выкладывать) сайт, хотя, по сути, ничего не изменилось, нет новых фич, нет исправления старых багов. Просто изменилась конфигурация.
В 2011 году разработчики компании Heroku выложили в интернете сайт, который называется 12factors. Он описывает методологию для создания веб-приложений, которая уменьшает затраты на установку и настройку приложения, повышает переносимость между средами исполнения, позволяет масштабироваться без существенных изменений в инструментах, архитектуре и практике разработки. С тех пор эта методология фактически стала стандартом в индустрии.
Я крайне рекомендую прочитать этот документ целиком, но прямо сейчас нас интересует один его аспект – конфигурация. 12 факторов требуют строгого разделения конфигурации и кода. Конфигурация может меняться между развертываниями (локальное окружение разработчика, продакшен, среда для тестирования), код – нет. Конфигурация должна передаваться в приложение снаружи, и единственный универсальный способ сделать это — использовать переменные окружения.
Laravel имеет большое число настроек для разных подсистем, которые задаются через переменные окружения. Например, вот как можно запустить фреймворк в режиме отладки:
# при запуске устанавливается переменная окружения APP_DEBUG со значением true
APP_DEBUG=true php artisan serve
Таких переменных довольно много, они отвечают за настройку кеширования, за отправку почты и многое другое. Для простоты конфигурации, Laravel использует библиотеку phpdotenv, которая позволяет загружать переменные не только из окружения, но и из специального файла .env, находящегося в корне проекта. Этот файл не хранится в репозитории, так как он специфичен для окружения, в котором идет запуск. Вот его небольшой кусок:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:MUD1rJ2GkEp7P5PdlsGe5MGfdwxu0v08IVDLodGW3zE=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
Это обычный текстовый файл, в каждой строке которого находится имя переменной и ее значение. Laravel автоматически подгружает его, и затем эти переменные используются в коде (если они там используются, конечно).
Возможно у вас возникает вопрос, каким образом формируется этот файл? После генерации проекта, Laravel создает файл .env.example, который хранится в репозитории, а в момент выполнения команды composer install он копируется в файл .env. Благодаря этому проект на Laravel стартует из коробки без необходимости дополнительной конфигурации. По крайней мере в режиме разработки. А вот для конфигурации продакшен-окружения одним фреймворком не обойтись. Здесь нужно применять либо системы управления конфигурацией, такие как Ansible, либо использовать системы оркестрации, например, Kubernetes, либо системы подобные Vault.
База данных
По умолчанию Laravel хочет взаимодействовать с MySQL, одной из самых популярных баз данных используемых в веб-разработке (наряду с PostgreSQL). Мы же поменяем базу данных и запустим наше приложение с SQLite. SQLite крайне проста в первоначальной настройке и запуске, это позволит нам прямо сейчас не отвлекаться на борьбу с операционной системой.
Учтите что SQLite нельзя использовать в конкурентной среде, то есть там где много пользователей. Она на это не рассчитана. Основное применение SQLite это мобильные приложения, настольные приложения (например, браузеры). Еще SQLite используют как базу данных для прогона тестов или запуска сайта в режиме разработки. Последнее это наш случай.
SQLite хранит данные в обычном файле. Создадим его:
# Это место, куда по умолчанию смотрит Laravel в поиске SQLite базы данных
touch database/database.sqlite
Этот файл не может находится в репозитории, поскольку он изменяется при любых изменениях данных. Laravel уже учел это, добавив все файлы с расширением sqlite в .gitignore.
Теперь необходимо настроить приложение так, чтобы оно начало использовать SQLite. Для этого откройте .env и установите там тип соединения:
DB_CONNECTION=sqlite
Кроме того, нужно закомментировать или удалить переменную окружения DB_DATABASE. В таком случае Laravel попробует искать файл с базой данных по пути database/database.sqlite.
Проверить что подключение работает можно в репле:
php artisan tinker
Psy Shell v0.10.0 (PHP 7.3.11 — cli) by Justin Hileman
>>> DB::select('select 1')
# Если нет ошибок, значит все хорошо
Самостоятельная работа
- Изучите файл .env.example
- Найдите в composer.json код, который отвечает за копирование .env.example в .env
- Настройте подключение к SQLite и проверьте, работает ли оно. Возможно, вам понадобится установить в систему пакет, который подключает sqlite3 к PHP. Точное имя пакета зависит от системы и версии PHP
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.