인수한 Java 서비스의 설정을 고치려는데 비슷한 이름의 파일이 여섯 개라 어느 것인지 알 수 없었다. 같은 항목이 여러 파일에 들어 있어서 실제로 쓰이는 값이 어디서 오는지 확인이 필요했다.
Table of contents
Open Table of contents
배경 — 여섯 개의 비슷한 파일
application.properties 와 application-dev.properties 와 application-prod.properties 가 있었다. 그 옆에 application-local.properties 와 옛 db.properties 와 jdbc.properties 도 한자리에 있었다. 이름만 봐서는 무엇이 무엇을 덮는지 알 수 없었다.
spring.datasource.url 이 들어 있는 파일을 세어 보니 셋이었다. 셋 다 값이 있으니 어느 것이 최종 값인지가 문제였다.
해 본 것 — 무엇이 이기는지 확인한다
Spring Boot 공식 문서에는 우선순위가 적혀 있다. 설정 파일 위에 OS 환경 변수가 덮고 그 위에 시스템 속성과 명령줄 인자가 덮는다. 파일끼리는 jar 안의 기본 파일 위에 프로파일 파일이 덮고 jar 밖의 파일이 다시 덮는다.
실제로 그런지 시작할 때 확인했다. Environment 의 PropertySource 를 훑어 그 키가 어느 소스에서 왔는지 찍었다. 값 자체는 안 찍고 어디서 온 것인지만 남겼다.
SPRING_DATASOURCE_URL 같은 환경 변수가 설정돼 있으면 파일을 아무리 고쳐도 값이 안 바뀌므로 이것을 모르면 왜 안 바뀌는지 알 수 없다.
조치 — 각 파일의 역할과 안 쓰는 것
파일마다 무엇을 담는 자리인지를 파일 안과 별도 문서에 함께 적었다. 저장소에 넣는 것과 안 넣는 것도 구분해 적었다.
정리하다 보니 db.properties 와 jdbc.properties 는 어디서도 읽지 않는 옛 파일이었고 그것들이 헷갈림의 원인이었다. 지우기 전에 이름을 바꿔서 애플리케이션을 띄워 보니 정상이었다. 코드를 뒤지는 것보다 이 확인이 확실했다.
막힌 지점 — 비밀 값과 남겨 둔 키
운영 파일에 spring.datasource.password 가 평문으로 들어 있어서 SPRING_DATASOURCE_PASSWORD 환경 변수로 옮겼다. 저장소에는 안 올라가고 있었지만 서버에는 그대로 남아 있었기 때문이다.
파일에서 항목을 통째로 없애지 않고 값만 비워 두는 쪽을 골랐다. 이유는 무엇이 필요한 설정인지가 파일에서 보이는 편이 나아서다. 대신 빈 값이 든 키가 기본값처럼 보일 수 있는 것을 감수했다.
검증 — 없으면 시작할 때 죽게
필요한 값이 비어 있으면 ApplicationRunner 에서 멈춘다. 무엇이 없는지와 어떻게 넣는지를 메시지에 적게 했다. 전에는 첫 조회에서 죽었고 그때는 원인이 설정이라는 것이 드러나지 않았다.
지금 적용된 설정을 보는 /actuator/env 는 dev 프로파일에서만 열었다. 공식 문서대로 password 와 secret 과 key 로 끝나는 키는 기본으로 가려지지만 노출 범위는 따로 잠갔다. 이 값이 무엇으로 들어갔는지를 파일을 뒤지지 않고 확인할 수 있게 된 것이 이 정리의 실질이었다.
정리
- 설정 파일이 여럿이면 어느 것이 이기는지 실제로 확인한다
- 문서의 우선순위가 이 환경에서 참인지는 별개다
- 환경 변수가 있으면 파일을 고쳐도 값이 안 바뀐다
- 각 파일의 역할을 파일 안과 별도 문서에 적는다
- 안 쓰는 파일은 이름을 바꿔 띄워 보고 지운다
- 비밀 값은 빼되 키는 비워서 남긴다
- 필요한 값이 없으면 시작할 때 멈추고 넣는 법을 알린다
- 적용된 설정 조회는 개발 환경에서만 열고 비밀 값을 거른다