- [etc] 쉘 스크립트 에러 핸들링하기2024년 01월 23일 05시 36분 26초에 업로드 된 글입니다.작성자: @kimyu0218
서버 터뜨리는 경우의 수 다 해보기 😵💫
(예비 서버 개발자지만 서버를 터뜨려요)지난 번에는 health check를 안 해줘서 서버를 터뜨렸는데, 이번에는 도커 컴포즈에 오타를 내서 서버를 터뜨렸다!
하이픈인 줄 알았으나 언더바였다. 이번 포스팅에서는 배포 스크립트에서 발생할 수 있는 에러를 선별하고, 에러가 발생하면 곧바로 종료하여 잘 돌아가는 서버에 영향을 미치지 않도록 만들어 줄 것이다.
문제의 배포 스크립트
echo "The $STOP_TARGET version is currently running on the server. Starting the $RUN_TARGET version." DOCKER_COMPOSE_FILE="compose.$RUN_TARGET-deploy.yml" sudo docker-compose -f "$DOCKER_COMPOSE_FILE" pull sudo docker-compose -f "$DOCKER_COMPOSE_FILE" up -d sleep 50
이번에 서버가 터지게 된 원흉을 가져왔다. 도커 컴포즈 파일에 문법 오류가 발생하여 컨테이너들이 실행되지 않았는데 이에 대한 에러 핸들링이 없어 다음 작업들이 계속 진행된다. (
뒤에 기존 버전의 어플리케이션을 종료하는 작업들이 있는데 여기서 안 멈추는 바람에 서버가 꺼졌다 ㅎㅎ)
현재 스크립트를 기준으로 에러가 발생할 수 있는 부분을 추려봤다. (이외에도 에러 핸들링할 게 엄청 많지만, 자주 수정되는 부분에 대해서만 처리하기로 했다)- 도커 컴포즈 파일이 존재하지 않거나 도커 허브 권한 제한 등으로 이미지를 받아오지 못한 경우
- 도커 컴포즈 파일의 문법 오류로 인해 컨테이너를 실행하지 못하는 경우
- 엔진엑스 설정파일을 수정하고 리로드 하는 과정에서 업스트림을 찾지 못하는 경우
에러가 발생하면 곧바로 종료하기
에러 난 시점에 바로 종료하여 에러가 더 큰 에러로 번지는 것을 막아보자.
set -e : exit immediately
bash의 `set` 명령은 쉘 환경을 조작할 수 있다. `-e` 옵션을 사용하여 비정상적으로 종료되었을 때 즉시 종료할 수 있다. 해당 명령을 쉘 스크립트 상단에 적어 에러가 발생하면 곧바로 종료되도록 하자.
#!/bin/bash set -e
명시적으로 비정상 종료하기
이제 `set -e`가 실행될 수 있도록 에러가 발생할 수 있는 부분에 명시적으로 종료하는 작업이 필요하다. 이때 `0`이 아닌 숫자로 종료해야 한다.
sudo docker-compose -f "$DOCKER_COMPOSE_FILE" pull || exit 1 sudo docker-compose -f "$DOCKER_COMPOSE_FILE" up -d || exit 1
or 연산자로 왼쪽 명령에 실패했을 때 `exit 1`을 호출하여 비정상 종료를 수행할 수 있도록 한다. (
엔진엑스 리로드에도 이와 같은 처리를 해줬다!)디버깅을 위한 로그를 남겨보자
위의 코드로 에러가 더 큰 에러로 번지는 것을 막았다. 하지만 근본적인 문제가 남았다. 우리는 오류를 해결해야 한다ㅎ
오류를 빠르게 바로 잡기 위해서는 어디에서 에러가 났는지, 어떤 에러가 났는지 확인할 수 있는 지표가 있어야 한다. 종료 전에 로그를 남겨보자.trap
`trap`은 특정 이벤트나 신호에 대한 처리를 지정하는 데 사용되는 명령이다. 주로 오류 처리나 스크립트 종료 시 정리 작업을 수행하는 데 활용된다.
trap [COMMAND] [SIGNALS|EVENTS]
나는 trap으로 스크립트가 비정상적으로 종료되었을 때 로그를 출력할 것이다.
trap 'echo "Error occured: $ERR_MSG. Exiting deploy script."; exit 1' ERR
*ERR : 쉘 스크립트에서 명령이 실패했을 때 발생하는 이벤트
이제 비정상 종료를 수행할 때 로그 메시지를 출력하도록 명령을 수정해보자. `ERR_MSG`라는 변수에 에러에 대한 정보를 전달해야 한다.sudo docker-compose -f "$DOCKER_COMPOSE_FILE" pull || { ERR_MSG='Failed to pull docker image'; exit 1; } sudo docker-compose -f "$DOCKER_COMPOSE_FILE" up -d || { ERR_MSG='Failed to start docker image'; exit 1; }
중괄호로 명령들을 그룹화하여 한 줄에 `ERR_MSG`에 로그 메시지 값을 대입하고, 종료 이벤트를 발생시켰다.
위의 두 가지 작업을 통해 하나의 에러가 다른 작업에 영향을 미치는 것을 방지하고, 신속하게 에러를 수정할 수 있게 되었다!🔗 배포 스크립트 전문 보러가기
다음글이 없습니다.이전글이 없습니다.댓글