Laravel читає значення через env() у файлах config/*.php. Джерела:
- змінні оточення процесу - те, що передав Docker (
-e,environment,env_fileу Compose, секрети оркестратора); - файл
.env- його завантажує бібліотека phpdotenv при старті.
Пріоритет: справжні змінні оточення важливіші за .env - phpdotenv не перезаписує вже встановлені змінні. Тому в контейнері можна взагалі не мати .env: усі значення приходять від Docker.
Чому .env не варто класти в образ:
- образ стає прив'язаним до одного середовища - для staging і продакшену потрібні різні образи;
- секрети (
APP_KEY, паролі бази, ключі API) потрапляють у шари образу й у реєстр - їх видно будь-кому з доступом до образу; .envмає бути в.dockerignore.
Пастка config:cache:
php artisan config:cache зберігає всю конфігурацію з уже підставленими значеннями в bootstrap/cache/config.php. Після цього .env і змінні оточення більше не читаються.
- якщо зробити
config:cacheпід час збирання образу, туди потраплять значення з середовища збирання (чи порожні) - а змінні, передані при запуску, буде проігноровано; - тому кешувати конфігурацію треба при старті контейнера, коли оточення вже відоме:
#!/bin/sh
# entrypoint.sh
php artisan config:cache
php artisan route:cache
php artisan view:cache
exec "$@"
Ще один наслідок: після config:cache функція env() поза файлами config/ повертає null. У коді застосунку - лише config('services.stripe.key'), а не env('STRIPE_KEY').
Перевірка в контейнері:
docker exec app php artisan about # середовище, драйвери, чи закешовано конфігурацію
docker exec app php artisan config:show database.default