Search
☁️

자동 배포 수정기

Person
태그
배포
서버

왜 자동배포가 제대로 실행이 안되었을까?

application.yml 파일을 .gitignore 에 추가하고, 레포에서 지우면서 빌드시 application.yml 읽을 수 없기때문에 발생하는 문제였습니다. 처음에는 서버에 이를 추가하면 안되는걸까? 했는데 동작과정을 생각해보니 이는 안될 수 밖에 없었습니다.

자동배포 과정

깃허브 액션 배포 스크립트에 지정한 브랜치에 프로젝트 파일을 올리면 작성한 배포 스크립트가 실행됩니다.
스크립트 내용에 따라 다르지만 제가 작성한 스크립트의 경우 아래와 같은 순서로 되어 있습니다.
1.
sdk 설치
2.
빌드
3.
프로젝트 .zip 으로 압축
4.
AWS 권한 확인 후 S3 배포 버킷에 배포
5.
codedeploy 가 배포한 .zip 을 ec2 에 배포
6.
script 실행: 현재 실행중인 프로젝트 종료 → 새로 배포한 프로젝트 실행
만약 2 번 과정에서 프로젝트에 application.yml 파일이 존재하지 않으면 문제가 생기게 됩니다. 로컬에서 프로젝트 빌드할때 application.yml 파일이 없으면 빌드에 문제가 생기는 것과 같습니다. 민감 정보가 들어있기 때문에 yml 파일은 .gitignore 로 처리하여 깃허브에 올리지 않는것이 맞지만 이렇게 하면 GithubActions 에서는 yml 파일이 없어 빌드가 되지 않습니다. 이를 어떻게 해결해야 할까요?

Submodule 생성과 등록

application.yml 파일을 관리하는 방법은 여러가지가 있겠습니다. 그중에서도 저는 서브 모듈로 private repository 를 생성하는 것을 선택했습니다. 프로젝트를 진행하다보니 application.yml 파일의 변경이 생기게 되었고, 앞으로도 안생길거란 보장이 없었기 때문입니다. 그래서 private repository 를 이용하여 파일만 따로 관리해야 겠다는 생각이 들었습니다.
저희 프로젝트의 경우 운영 서버와 개발 서버가 존재하기 때문에 application.yml 도 종류가 두가지 이며, workflow 도 두개가 될 것입니다. 그래서 각각의 yml 을 넣을 private repository 를 생성하고, 이를 각각의 workflow 에 연결해 주었습니다.

Submodule 과 프로젝트 레포 연결

git submodule update --remote
Java
복사
 프로젝트 최상단에서 이 명령어를 입력하면 오른쪽과 같이 등록한 서브 모듈이 생길거에요. yml 수정은 이곳이 아닌 각 레포를 클론받아하고, 프로젝트를 업데이트 해주어야 합니다.

GithubActions 에 Submodule 등록

steps: - uses: actions/checkout@v3 with: token: ${{ secrets.SUBMODULE_TOKEN }} submodules: true
Java
복사
토큰은 profile → setting → <> developer ~ 에서 토큰을 생성한 뒤에 repository 설정에서 시크릿 키로 등록해주면 됩니다. 토큰 생성시 반드시 유효기간을 설정해야 합니다!

build.gradle 설정 변경

이렇게 배포를 한다면 나중에 서브 모듈은 잘 들어와 있지만 빌드시 이 application.yml 을 끌고 오지 않아 실행 시 데이터 베이스를 찾을 수 없다는 오류가 발생합니다. 때문에 아래와 같이 application.yml 을 알맞게 복사해주는 코드를 추가해주세요.
// 빌드 시 application.yml 을 서브모듈에서 복사하기 task copySubmoduleYml(type: Copy) { from './dev-submodule' include '*.yml' into './src/main/resources' } // build 태스크가 copySubmoduleYml 태스크에 의존하도록 설정 processResources.dependsOn copySubmoduleYml
Java
복사

yml 수정과 프로젝트 레포에서 yml 최신화 하기

각각의 yml 수정은 private 레포를 클론받아 수정하고 올려주시면 됩니다. 수정한 yml 은 프로젝트에서 업데이트를 시켜줘야 합니다. 저희 프로젝트의 경우 개발 서버는 BE 브랜치를 잡도록 되어있고, 지금 1차 배포 후 운영중인 운영 서버는 1차배포-임시브랜치 를 잡도록 되어 있습니다.
때문에 이 두 브랜치 에서만 아래 명령어를 이용하여 배포전 yml 을 최신화 해주면 됩니다.
// 프로젝트 최상단에서 이 명령어를 입력해 주세요. git submodule update --remote // remote 레포에 반영 시키기 위해 이 명령어를 입력해 주세요. git submodule foreach git pull // 이후 변화한 서브모듈을 push 하면 remote 레포에 적용이 됩니다.
Java
복사
여기서 yml 을 수정하는게 아닙니다!
각 레포를 클론받아서 수정해 주세요 ~

배포는 잘 되지만… 무한로딩?

EC2 에 프로젝트까지 잘 배포가 되지만 잘 되었나 확인하기 위해 스웨거 문서를 들어가면 아래와 같은 화면이 저를 반겨주었습니다… (보고싶지 않았어요. )
어랏… 무슨 문제야! 하고 인스턴스 모니터링을 하면 시간이 갈수록 치솟는 CPU 사용률을 볼 수 있었습니다.
문제의 원인을 확인하기 위해 deploy.log 를 확인해보았습니다.
[ec2-user@ip-172-31-10-248 deploy]$ sudo tail -f deploy.log Thu Sep 28 08:02:24 2023 > /home/ec2-user/app/deploy/build/libs/demo-ROOT.jar 파일 실행 Thu Sep 28 08:02:24 2023 > 실행된 프로세스 아이디 902902 입니다. Thu Sep 28 08:07:05 2023 > 현재 실행중인 애플리케이션이 없습니다 Thu Sep 28 08:07:06 2023 > /home/ec2-user/app/deploy/build/libs/demo-ROOT.jar 파일 복사 Thu Sep 28 08:07:06 2023 > /home/ec2-user/app/deploy/build/libs/demo-ROOT.jar 파일 실행 Thu Sep 28 08:07:06 2023 > 실행된 프로세스 아이디 입니다. Thu Sep 28 08:18:57 2023 > 현재 실행중인 애플리케이션이 없습니다 Thu Sep 28 08:18:58 2023 > /home/ec2-user/app/deploy/build/libs/demo-ROOT.jar 파일 복사 Thu Sep 28 08:18:58 2023 > /home/ec2-user/app/deploy/build/libs/demo-ROOT.jar 파일 실행 Thu Sep 28 08:18:58 2023 > 실행된 프로세스 아이디 입니다.
Plain Text
복사
실행되어야 하는 프로젝트는 demo-SPRINT2.jar 인데 왜 demo-ROOT.jar 이 실행되고 있는걸까? ^^..
호다닥 스크립트를 바꿔주었습니다.
그럼에도 불구하고 반겨주는 하얀색 페이지. 굴하지 않고 로그를 확인합니다.
Thu Sep 28 08:45:23 2023 > 현재 실행중인 애플리케이션이 없습니다 Thu Sep 28 08:45:24 2023 > /home/ec2-user/app/deploy/build/libs/demo-SPRINT2.jar 파일 복사 Thu Sep 28 08:45:24 2023 > /home/ec2-user/app/deploy/build/libs/demo-SPRINT2.jar 파일 실행 ================ ssionManagementFilter@134c38, org.springframework.security.web.access.ExceptionTranslationFilter@6c5ae8fd, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1fc1c7e] 2023-09-28T08:45:48.584Z INFO 2938 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2023-09-28T08:45:48.588Z INFO 2938 --- [ main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... 2023-09-28T08:45:48.588Z INFO 2938 --- [ main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2ffa91dc]] 2023-09-28T08:45:48.588Z INFO 2938 --- [ main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. 2023-09-28T08:45:48.619Z INFO 2938 --- [ main] t.project.demo.DemoApplication : Started DemoApplication in 21.69 seconds (process running for 23.558) 2023-09-28T08:46:44.620Z INFO 2938 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect fai
Plain Text
복사
프로젝트는 제대로 실행된 상황. 포스트맨으로 한번 요청을 날려 뭐가 문제인지 확인해보겠습니다.
하아..  그렇다면.. 정답은 하나.
ec2 재부팅을 하면서 nginx 가 꺼져버렸을 가능성 거의 99.9%.
바로 확인해보았습니다.
[ec2-user@ip-172-31-10-248 libs]$ sudo service nginx status Redirecting to /bin/systemctl status nginx.service ○ nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: disabled) Active: inactive (dead) // 다시 실행 [ec2-user@ip-172-31-10-248 libs]$ sudo service nginx start Redirecting to /bin/systemctl start nginx.service [ec2-user@ip-172-31-10-248 libs]$ sudo service nginx status Redirecting to /bin/systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: disabled) Active: active (running) since Thu 2023-09-28 08:51:44 UTC; 7min ago Process: 3281 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Process: 3282 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 3283 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Main PID: 3284 (nginx) Tasks: 2 (limit: 1114) Memory: 4.8M CPU: 83ms CGroup: /system.slice/nginx.service ├─3284 "nginx: master process /usr/sbin/nginx" └─3285 "nginx: worker process" Sep 28 08:51:44 ip-172-31-10-248.ap-northeast-2.compute.internal systemd[1]: Starting nginx.service - The nginx HTTP and reverse proxy server... Sep 28 08:51:44 ip-172-31-10-248.ap-northeast-2.compute.internal nginx[3282]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Sep 28 08:51:44 ip-172-31-10-248.ap-northeast-2.compute.internal nginx[3282]: nginx: configuration file /etc/nginx/nginx.conf test is successful Sep 28 08:51:44 ip-172-31-10-248.ap-northeast-2.compute.internal systemd[1]: Started nginx.service - The nginx HTTP and reverse proxy server.
Plain Text
복사

정리

깃허브 액션 워크 플로우를 어떻게 작성하냐에 따라 다르지만 배포 시 특정 브랜치 안의 모든 파일을 가져다가 배포 파일을 만듭니다. 이 파일을 빌드하기 때문에 이곳에 application.yml 이 없으면 안됩니다.
민감정보인 application.yml 을 관리하기 위해 서브모듈을 만들면 쉽게 관리가 가능합니다. 하지만 이또한 프로젝트에 .gitignore 로 추가해주어야 합니다.
서브모듈은 조직 내부의 사람들에게는 보이지만 외부인은 볼 수 없습니다. (404 로 뜹니다.)
ec2 가 두개라면 codedeploy 배포 그룹도, s2 bucket 내에 폴더도 따로 생성해주어야 합니다. (배포 그룹 설정시 태그를 주의해서 등록해주세요.)
블루/그린 배포를 도전해보려 했는데, 어려워서 일단 후퇴… 하였습니다.