Laravel 프로젝트에 설정 파일을 하나 추가했다. config/channels.php를 만들고 값을 넣었는데 읽히지 않았다.
Table of contents
Open Table of contents
증상 — 기본값만 반환됐다
config('channels.timeout')이 계속 config() 두 번째 인자의 기본값을 반환했다. 파일에는 분명히 다른 값이 들어 있었다.
config/channels.php 경로도 맞고 php -l로 확인한 문법도 정상이었으며 배열 구조도 맞았다.
원인 — 부모가 먼저 소비한 설정
php artisan config:clear를 돌리니 값이 읽혔는데, 캐시 문제로 보고 넘어가려다 배포하면 다시 안 읽혔다.
배포 스크립트에 php artisan config:cache가 있었고 그 시점에 새 파일이 아직 없었다. 캐시는 bootstrap/cache/config.php 한 파일로 컴파일되며, 그 뒤로 Laravel은 .env도 config/ 파일도 다시 읽지 않는다.
config:clear를 돌려도 한동안 옛 값이 나왔는데, OPcache가 컴파일된 바이트코드를 들고 있어서였다. systemctl reload php7.4-fpm까지 해야 반영됐다.
선택지와 대가
방법이 셋이었다. 배포에서 config:cache를 빼거나, 캐시 생성 시점을 뒤로 옮기거나, 새 파일을 기존 설정 파일에 합치는 것이다.
캐시를 빼는 쪽은 확실하지만 요청마다 config/ 아래 파일을 전부 읽는다. 측정해 보니 요청당 12ms가 늘었다.
시점을 옮기는 쪽은 성능을 유지한다. 대신 배포 스크립트가 복잡해지고 순서에 의존하는 단계가 하나 늘어난다.
합치는 쪽은 파일이 늘지 않아 문제가 재발하지 않는 대신, 성격이 다른 설정이 한 파일에 섞이게 된다.
고른 것과 하지 않은 것
시점을 옮기는 쪽을 골랐다. 12ms는 이 서비스에서 무시할 수 없는 값이었다.
배포 순서를 문서에 적고 스크립트에도 주석을 달았다. git pull → composer install → config:cache → php-fpm reload 순이고, 이 순서에 의존한다는 사실을 드러내 놓는 것이 조건이었다.
config() 두 번째 인자의 기본값을 없애는 것은 하지 않기로 했다. 기본값이 있어서 이 문제가 늦게 발견된 것은 맞지만, 없애면 설정 누락 시 null이 그대로 흘러 화면이 죽는다. 늦게 발견되는 쪽이 죽는 쪽보다 나았다.
검증 — 기본값과 다른 값으로
기본값과 같은 값으로 검증하면 로딩이 안 돼도 그대로 통과하는데, 이 문제를 처음에 못 본 이유가 바로 그것이었다.
검증할 때는 기본값과 다른 값을 넣어 확인하게 했다. 값이 바뀌어 나오는 것을 봐야 실제로 읽힌 것이다.
정리
config:cache는bootstrap/cache/config.php한 파일로 컴파일한다- 그 뒤로 Laravel은
.env도config/파일도 다시 읽지 않는다 - 캐시 생성 시점에 파일이 없으면 그 뒤로 계속 없는 것으로 동작한다
config:clear만으로는 부족하다 — OPcache 때문에php-fpm reload까지 해야 한다- 캐시 제거·시점 이동·파일 병합 셋을 놓고 봤다
- 캐시를 빼면 요청당 12ms가 늘어 이 서비스에서는 감당이 안 됐다
- 시점을 옮기되 순서 의존을 문서와 주석에 드러냈다
- 폴백을 없애는 것은 하지 않았다 — 늦게 발견되는 쪽이 죽는 쪽보다 낫다
- 검증은 기본값과 다른 값으로 해야 로딩 여부가 갈린다