에러들...
1. CI 도중 Redis 연결이 안됨
2. CI 서버에서 배포 서버로 docker-compose.yml 파일 전송이 안됨.
3. 배포서버의 deploy.sh 에서 에러가 발생함.
문제를 해결하고 난 뒤 보니까 간단해보이지만... 새벽에 3시간넘게 붙잡고 있었다...
(함께 에러 해결을 위해 정보를 찾아준 최고의 개발리드 성민아 고마워🥹)
시너지 프로젝트 작업 중 Redis를 사용하게 되었다.
NCP를 지원받았지만 , Cloud for Redis 비용이 막대했기에 Redis는 컨테이너로 띄워서 배포하기로 결정했다.
이때부터 CI/CD 에서 에러가 터지기 시작했다.
1. CI 도중 Redis 연결이 안됨
일단 첫번째 에러는 CI 도중 Redis 연결이 안됐고, 의존성 주입이 되지 않았다.
CI 도중 테스트 진행 시 contextLoads() 에러를 보자마자 지난 기업 프로젝트에서 맞닥뜨렸던 에러가 떠올랐다.
https://securityinit.tistory.com/236 (참고)
위 방법대로 디버깅을 해보니!
의존성 주입이 되지 않고 있었다.
왜인지 모르겠는데, 배포 스크립트를 docker-compose를 사용하도록 바꾸면서 application.yml 파일을 주입하는 로직을 지워버렸다.
또한 Redis 설정도 빼먹었어서 CI 과정에 추가했다! (성민이가 찾아줬다 ㅎㅎ)
services:
redis:
image: redis
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
위와 같이 CI 과정에 redis 컨테이너를 실행해 Github Action 서버에서 redis를 사용할 수 있게 만들었다.
헬스체크도 추가해 확실하게 redis가 실행됐음을 확인한다
그렇게 일단 이 문제는 해결했다...
(바보같지만 여기서 가장 오랜 시간을 허비했다 ㅜ... ci 스크립트를 잘 확인해보자...)
2. CI 서버에서 배포 서버로 docker-compose.yml 파일 전송이 안됨
docker-compose 파일을 통해 배포를 진행하기로 했다.
여기선 고민이 있었다.
서버에 수동으로 docker-compose 파일을 만들면 조금은 간단하게 배포를 진행할 수 있었지만, 그러고 싶지 않았다.
docker-compose 파일이 바뀔때마다 서버에 들어가 수동으로 수정하는 건 좀 ㅎ....
쨋든 ci 과정에서 docker-compose 파일을 ncp 서버로 넘겨주는 방식을 선택했다.
- name: Docker Compose 파일 NCP 서버로 전송
run: scp -o StrictHostKeyChecking=no -P ${{ secrets.NCP_PORT }} docker-compose.yml ${{ secrets.NCP_USERNAME }}@${{ secrets.NCP_HOST }}:./
여기선 권한 문제가 발생했다.
Github Actions 서버에서 NCP 서버로 파일을 전송하려는데 권한이 없어 전송이 되지 않았다.
이를 해결하는 방법으론 2가지를 찾았다.
1. SSH 키를 사용한 방법
2. sshpass를 사용한 방법
- name: Docker Compose 파일 NCP 서버로 전송
run: sshpass -p ${{ secrets.NCP_PASSWORD }} scp -o StrictHostKeyChecking=no -P ${{ secrets.NCP_PORT }} docker-compose.yml ${{ secrets.NCP_USERNAME }}@${{ secrets.NCP_HOST }}:./
결론부터 말하면 1번을 사용했다.
2번의 경우 훨씬 간단했다.
Github Secrets에 비밀번호를 추가하면 끝이다.
그러나 보안 문제가 있었다.
https://stackoverflow.com/questions/32255660/how-to-install-sshpass-on-mac
개발자가 2022년 이후로 프로젝트를 업데이트하고 있지 않다는 정보를 발견했고, 1번을 선택하기로 했다.
이제 방법은 간단하다.
1. 로컬 컴퓨터에서 공개키 암호 생성
2. 공개키를 서버에 설치
3. 개인키를 통해 전송
순서대로 해보자.
1. 로컬 컴퓨터에서 공개키 암호 생성
ssh-keygen -t rsa -b 4096 -C "넣고싶은 정보 아무거나 넣으면 된다. 안넣어도 된다."
그 후 ~/.ssh 에 들어가보면
이렇게 공개키와 비밀키가 생성되어 있다.
2. 공개키를 서버에 설치
id_rsa.pub의 내용을 서버로 옮겨야 한다.
ncp 서버에 .ssh 디렉토리가 없다면 생성하자.
mkdir -p ~/.ssh
chmod 700 ~/.ssh
(700을 줘서 다른 사람의 접근을 막자.)
로컬호스트에 생성한 id_rsa.pub 파일의 내용을 ncp 서버의 ~/.ssh/authorized_keys 파일에 등록한다.
(참고로 authorized_keys는 폴더가 아니고 파일이다. 처음엔 없으니까 vim, vi를 사용해 파일을 만들고 안에 내용을 복붙하면 된다.)
chmod 600 ~/.ssh/authorized_keys
600 권한을 줘서 소유자만 읽고 쓸 수 있도록 제한하자.
여기까지 했으면 ssh 설정을 확인해보자.
ssh 서버가 authorized_keys 파일을 인식할 수 있도록, ssh 설정을 확인하자.
nano /etc/ssh/sshd_config
그리고 다음 항목이 설정되어 있는지 확인하자.
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
다 확인했다면!
(ctrl+o (수정완료) -> enter(파일 이름 확인) -> ctrl + x(nano 에디터 빠져나오기)) 의 순서로 빠져나오자.
sudo systemctl restart sshd
3. 개인키를 통해 전송
이제 로컬호스트의 비밀키를 Github Secrets에 추가하자.
GitHub 저장소에서 Settings > Secrets > New repository secret으로 이동한 뒤
NCP_SSH_PRIVATE_KEY 이름으로 id_rsa의 내용을 저장한다.
(꼭 위의 이름으로 저장할 이유는 없지만 명시적인 이름이 좋으니까..!)
다시 CI 스크립트를 실행하면 NCP 서버로 docker-compose가 전송이 된다!!!
3. 배포서버의 deploy.sh 에서 에러가 발생함
끝난 줄 알았지만....
아직 끝나지 않았다...!
처음 배포를 했을 땐 정상적으로 동작을 했다.
그러나 다시 한번 배포를 했을 땐 에러가 발생했다.
내가 작성한 deploy.sh 파일의 조건문에서 에러가 발생하고 있었다.
# 이미지로 실행되고 있는 컨테이너가 있다면 종료 후 삭제
echo "도커 컴포즈로 실행되는 컨테이너를 삭제 중..."
if [ "$(sudo docker ps -q -f name=cnergy-backend)" ]; then
sudo docker stop cnergy-backend
sudo docker rm cnergy-backend
else
echo "실행 중인 기존 컨테이너가 없습니다."
fi
(deploy.sh 의 일부이다.)
이렇게 cnergy-backend로 돌아가는 컨테이너가 있다면 종료한 뒤 , 새로운 컨테이너를 실행한다.
docker-compose로 실행하기 전엔 docker run 명령어를 통해 container의 이름을 지정했다.
그러나 docker-compose로 배포하고 난 뒤 재배포를 하면 에러가 발생했다.
원인은 docker-compose 파일에 container 이름을 설정하지 않았기 때문이다.
docker-compose의 경우 , 특정한 이름을 설정하지 않으면 다음과 같은 형식으로 컨테이너 이름이 정해진다.
[프로젝트 이름]_[서비스 이름]_[서비스 내에서 컨테이너의 번호]
그러다보니 , docker-compose로 배포한 우리 프로젝트의 이름은
root_cnergy-backend_1
위와 같은 형식으로 작성되었다.
그러다보니 sh 파일의 조건문을 통과하지 못했다.
docker-compose.yml에서 각 service의 container_name을 지정해주니 배포시 에러가 사라졌다.
느낀점
새벽 12시부터 3시가 넘는 시간까지 이것저것 찾아보고 문제를 해결했다.
에러란 해결하면 쉬워보이지만, 막상 그 순간엔 아무것도 보이지 않는다.
이번 밋업에서 잊히지 않을 순간이 되었다...
또 도커, 도커 컴포즈, CI/CD에 대해 더 깊게 알게 되었다.
에러는 선생님이다 선생님...
근데 왜 안되는지 찾는것도 나름 재밌다 ㅎ
아무튼 끗!