Github Action에서 build에 실패했다. (전에는 잘 됐고, 이번에만 갑자기 실패)
deploy.yml
(workflow file)를 확인하니,
지금은 develop 브랜치에 커밋되면 deploy.sh
에서
docker-compose로 컨테이너를 빌드해서 실행하고 있다.
이때 같은 이름의 컨테이너가 있으면 안 돼서, 새 컨테이너 실행 전에 기존 컨테이너를 삭제한다.
문제는 deploy.sh
에서 compose로 생성한 컨테이너만 삭제하고 있었다는 거다. 팀원이 어제 배포하고 ec2에서 문제 해결하면서 cli에서 docker run으로 컨테이너를 직접 생성했는지, 그 컨테이너는 삭제가 안 됐다.
그래서 deploy.sh
에 한 줄 추가해서 run으로 직접 실행한 컨테이너도 삭제할 수 있도록 했다.
로그를 확인하면 어느 단계에서 문제가 생겼는지 알 수 있다.
아래 ERROR: 부분을 보면 docker 컨테이너 생성 중에 같은 이름의 컨테이너가 이미 있어서 충돌이 발생하고 있다.
이전 게시물에서 설명했듯, 위쪽 네모가 workflow file에서 name이다. 그걸 찾아보자.
트리거 지정
on:
push:
branches:
# - main
- develop
pull_request:
branches:
# - main
- release
실제로 수행할 작업
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
(생략)
# 서버에 접속한 뒤 deploy.sh(배포 스크립트)를 실행
- name: 📌executing remote ssh commands using password📌
(생략)
script: |
sh /(생략)/config/scripts/deploy.sh
1에서 본 name을 찾았다!
(📌executing remote ssh commands using password📌
)
물론 실제 코드에 압정 이모티콘은 없다. 설명하려고 표시했다.
여기서 아래 커맨드 실행를 실행하나보다.
sh /(생략)/config/scripts/deploy.sh
deploy.sh 파일을 까보자.
# Docker 설치 여부 확인, 없으면 설치
if ! type docker > /dev/null
then
echo "docker does not exist"
echo "Start installing docker"
(생략)
# Docker Compose 설치 여부 확인, 없으면 설치
if ! type docker-compose > /dev/null
then
echo "docker-compose does not exist"
echo "Start installing docker-compose"
(생략)
# 기존 orphan 컨테이너 정리
echo "stop and remove old containers (with orphans)"
sudo docker-compose -f /(생략)/docker-compose.prod.yml down --remove-orphans
# Docker Compose로 서버 빌드 및 실행
echo "start docker-compose up: ubuntu"
sudo docker-compose -f /(생략)/docker-compose.prod.yml up --build -d
기존 컨테이너를 정리하는 코드에 문제가 있는 것 같다.
보니까 파일 내용에 echo가 있고, (print문 같은 것)
그게 로그에 출력되는 것 같다.
Docker, Docker Compose 설치는 이미 되어있어서 실행되지 않았고,
아래 부분은 잘 실행되고 있다.
결론 : 기존 컨테이너를 정리하는 명령어가 실행되지만, 제대로 정리되지 않았다.
sudo docker-compose -f /(생략)/docker-compose.prod.yml down --remove-orphans
같은 명령어를 EC2 cli에서 직접 실행해도 여전히 기존 컨테이너가 삭제되지 않았다.
알고 보니 docker-compose로 down을 하면 docker-compose로 up(생성)한 컨테이너만 다운된다고 한다.
docker run으로 개별 컨테이너를 직접 생성한 경우 docker stop, docker rm으로만 제거가 가능하다.
팀원이 어제 배포하고 ec2에서 문제 해결하면서 cli에서 docker run
으로 컨테이너를 직접 생성했는지, 그 컨테이너는 docker-compose down으로 삭제가 안 됐던 거다.
그래서 deploy.sh
에 한 줄 추가해서 compose를 통하지 않고 직접 run한 web 컨테이너도 삭제하도록 했다.
# 기존 orphan 컨테이너 정리
echo "stop and remove old containers (with orphans)"
sudo docker-compose -f /home/ubuntu/srv/ubuntu/docker-compose.prod.yml down --remove-orphans
📌sudo docker rm -f web || true📌
(물론 실제 코드에 압정은 없다. 설명을 위해 표시한 거다.)
참고로 web은 컨테이너 이름이고, docker-compose.prod.yml
에서 이름을 지정하고 있다.
deploy.sh에 있던 명령어를 뜯어보자.
sudo docker-compose -f /(생략)/docker-compose.prod.yml down --remove-orphans
sudo
: 관리자 권한으로 명령어 실행
docker-compose down
: docker 컨테이너를 종료(down)시킨다.
docker-compose.yml
또는 지정한 파일)에 정의된 서비스들의 컨테이너를 중지하고 제거-f /(생략)/docker-compose.prod.yml
: 파일 지정
docker-compose.yml
에 정의된 컨테이너를 빌드한다.docker-compose.prod.yml
를 빌드하려면 파일을 지정해야 한다.docker-compose.yml
를, 서버에서는 docker-compose.prod.yml
를 쓴다. product(제품)의 prod다.--remove-orphans
: (docker-compose.yml
또는 지정한 파일)에 정의되지 않은 서비스의 컨테이너도 함께 제거
sudo docker-compose -f /(생략)/docker-compose.prod.yml up --build -d
docker-compose up
: 이미지 빌드(필요시) + 컨테이너 생성 + 실행
--build
: 컨테이너 실행 전에 이미지를 새로 빌드
--build
안 쓰면 기존 이미지로 컨테이너만 실행docker-compose build
) 이미지를 빌드만하고 실행하지 않음. 이 경우 별도로 docker-compose up
필요.-d
: 백그라운드에서 실행 (데몬 모드)