(진짜 트러블슈팅!!! (절대 아닙니다.))
이번에 애플리케이션 구조에 이것저것을 더하는 와중에
CI-CD 파이프라인을 구축해둔 Github Actions
에서 자꾸 말썽을 부려서
이에 대한 2개 이슈와 트러블슈팅에 대해 기록해 두려고 한다.
- Github Actions 환경에서 Redis 의존 테스트 실행
- Github Actions 환경에서 secret으로 선언한 json 파일 주입
두 케이스 모두 흔히 있을 것으로 판단되기 때문에
몇몇 분들께 (혹은 미래의 나에게) 소소한 도움이 되리라 기대한다.
사진의 on.pull_request
항목을 보면 알 수 있듯
위 yml 파일은 PR을 올리고 중심 브랜치에 합치기 전에 테스트를 돌릴 목적으로 작성되었다.
그리고 이번에 리프레시 토큰을 저장하기 위한 캐시 데이터베이스로
Redis
를 선택하고 이에 대한 리팩토링을 진행했다.
그런데,,,
(임산부 노약자 심장이 약하신분은 위 사진 시청에 주의가 필요합니다)
Github Actions에서 테스트를 실행하니
위와 같이 다발적으로 동일한 이유로 실패했다.
처음에는 test 모듈의 application.yml
에서 redis에 대한 설정이 원인이라고 예상했지만
로컬에서 테스트는 잘 통과하는 걸 보니 잘못된 접근이었다.
그렇게 에러 로그를 뚫어져라 보는 와중에 직관적으로 내 머리를 스친 것이 있다.
Github Actions에 Redis가 깔려있지 않은 거라면..?
그도 그럴 것이, 당장 Test.yml 파일을 보더라도 JDK를 세팅해주고 있었다.
JDK도 깔아야 하는데, Redis도 당연히 깔아야 하는 게 아닌지 ...
의외로 해답은 간단했다.
redis를 제공해주는 소스를 찾아서 버전에 맞게 쓰기만 하면 그만이었다.
(참고로, 다른 코드에서는 redis-version
에 matrix를 걸어서
[6, 7]
2개 redis 버전에 대해 테스트를 2번 돌리기도 했다)
서버 애플리케이션에 Firebase Cloud Messaging
을 도입하면서
구글에서 받은 크레덴셜 json 파일을 활용해 FirebaseApp
을 초기화해야 했다.
그래서 json 파일이 테스트할 때나 애플리케이션 빌드할 때도 필요했고,
비밀 정보로 판단했기 때문에 Github Actions의 Repoisotry Secret에 복붙해서 등록해줬다.
그래서 yml 파일에 위와 같이 작성했다.
application.yml 주입할 때와 동일한 로직이다.
그러나 테스트 실패가 떴다...
처음에는 이 사실을 부정하고 싶어서 여러 번 돌려봤지만 결과는 동일했다.
그런데 테스트 실패 로그를 살펴 보니
FirebaseApp을 초기화하는 과정에서 문제가 발생하고 있음을 알 수 있었다.
그래서 찾아 보니 Github에 등록한 secret 값은 json의 형식을 따르지 않기 때문에
쌩 텍스트 값인 secret 값을 json 형식에 맞춰 변경하는 작업이 필요하다고 한다.
(하단 블로그 링크 참조)
https://velog.io/@godkimchichi/Github-Actions-secret에-json-넣고-싶을-때
그래서 테스트용 yml과 배포용 yml 각각에 위와 같은 내용을 추가했다.
secret 값을 json으로 바꿔 파일을 생성하고, 원하는 위치에 mv
명령어로 옮겼다.
AWS EC2에 배포할 때 지속적으로 FirebaseApp을 초기화하지 못하는 오류가 발생했다.
예외의 원인을 로그로 찍어 보니, firebase-key.json
파일을 참조하지 못했다.
@Slf4j
@Configuration
public class FirebaseConfig {
@Value("${firebase.key-file}")
private String keyFile;
@Bean
public FirebaseMessaging firebaseMessaging() {
initializeFirebaseApp();
return FirebaseMessaging.getInstance();
}
private void initializeFirebaseApp() {
try {
if (FirebaseApp.getApps().isEmpty()) {
FileInputStream key = new FileInputStream(keyFile);
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(key))
.build();
FirebaseApp.initializeApp(options);
log.info("firebase messaging initialized");
}
} catch (IOException e) {
e.printStackTrace();
log.error("failed to initialize firebase", e);
}
}
}
생각해보니 firebase-key.json
파일은 application.yml
과 달리
어플리케이션 시작 시에 명확한 위치에서 참조를 해야 한다.
그런데 테스트는 깃헙 액션 위에서 돌아가고, 애플리케이션을 실제로 시작하는 건 EC2로
서로 다르기 때문에 @Value
를 활용해서 프로필마다 다른 값을 주입했다.
그런데 더 큰 문제는 EC2에 firebase-key.json 파일을 옮겨도 참조하지 못했다.
그래서 든 생각이...
도커 컨테이너는 호스트 머신과 격리된 환경에서 실행되기 때문에
"/home/ubuntu"로 직접적인 접근이 불가능하다.
green:
container_name: green
image: jinkonu/omg:latest
volumes:
- ./firebase-key.json:/home/ubuntu/firebase-key.json
그래서 위처럼 볼륨 마운트를 해줘야 한다...
에휴!
이제야 작동한다.
(그래서?)
깃헙 액션은 Git을 활용한 버전 컨트롤과 동시에 배포를 한꺼번에 할 수 있어
아주 편안하게 사용할 수 있고, 설정도 너무너무 간단해서 좋다.
그렇지만 빌드 환경이 특수하다는 점 때문에
가끔 이런 귀여운 문제들을 만들어주곤 한다...
그래도 웬만한 부분들은 이처럼 쉽게 다른 라이브러리를 참조함으로써 해결할 수 있기 때문에
아직까진 젠킨스에 대한 욕구가... 없다.
깃헙 액션 짱!