티스토리 뷰
✏️ 발단
서버 배포 방식을 점검하다가 위험한 부분을 발견했다. 현재 배포 흐름은 아래와 같다.
GitHub Actions
→ Docker 이미지 빌드
→ Docker Hub push
→ EC2 SSH 접속
→ 기존 컨테이너 삭제
→ 새 컨테이너 실행
문제는 기존 컨테이너를 삭제하는 명령어였다. 이 명령어는 EC2에 떠 있는 모든 Docker 컨테이너를 삭제한다. 지금은 애플리케이션 컨테이너 하나만 실행 중이라 문제가 없어 보이지만, 나중에 같은 EC2에 Nginx, Redis, 모니터링 도구 같은 컨테이너가 추가되면 배포할 때 전부 같이 날아갈 수 있다. 운영 서버에서는 위험한 방식이다.
sudo docker rm -f $(docker ps -qa)
✏️ 기존 배포 스크립트의 문제
기존 스크립트는 대략 이런 형태였다.
sudo docker ps
sudo docker rm -f $(docker ps -qa)
sudo docker pull eatssu/eatssu-dev
sudo docker run -d -p 9000:9000 \
--log-driver=awslogs \
--log-opt awslogs-region=ap-northeast-2 \
--log-opt awslogs-group=dev-ec2-group \
eatssu/eatssu-dev
문제를 정리하면 다음과 같다.
- EC2의 모든 컨테이너를 삭제한다.
- 컨테이너 이름이 고정되어 있지 않다 (dazzling_spence 같은 랜덤 이름).
- EC2 재부팅 시 컨테이너 자동 재시작 정책이 없다.
랜덤 이름 컨테이너 문제
Docker에서 --name을 지정하지 않으면 랜덤 이름이 붙는다. 이 상태에서 단순히 배포 스크립트를 아래처럼 바꾸면 문제가 생긴다. 기존 컨테이너 이름은 eatssu-dev가 아니므로 삭제되지 않는다. 그러면 새 컨테이너를 실행할 때 9000 포트가 이미 점유되어 있어 실패한다. 그래서 기존 랜덤 이름 컨테이너도 안전하게 정리하는 전환 과정이 필요했다.
sudo docker rm -f eatssu-dev || true
port is already allocated
✏️ 개선 방향
이번 개선의 목표는 다음과 같았다.
- 전체 컨테이너 삭제 금지
- 애플리케이션 컨테이너만 삭제
- 컨테이너 이름 고정
- restart policy 추가
- 기존 랜덤 이름 컨테이너도 안전하게 정리
최종적으로 수정한 스크립트는 다음과 같다.
sudo docker ps
# 이름 기반으로 먼저 삭제 시도 (이미 이름이 고정된 경우 대응)
sudo docker rm -f eatssu-dev || true
# 9000 포트를 점유한 컨테이너 정리 (랜덤 이름 컨테이너 대응)
PUBLISHED_CONTAINERS=$(sudo docker ps -q --filter publish=9000)
if [ -n "$PUBLISHED_CONTAINERS" ]; then
sudo docker rm -f $PUBLISHED_CONTAINERS
fi
sudo docker pull eatssu/eatssu-dev
sudo docker run -d --name eatssu-dev --restart unless-stopped -p 9000:9000 \
--log-driver=awslogs \
--log-opt awslogs-region=ap-northeast-2 \
--log-opt awslogs-group=dev-ec2-group \
eatssu/eatssu-dev
✏️ 의사결정 기록
1. publish=9000으로 컨테이너를 찾은 이유
처음에는 이미지 이름 기준으로 찾는 방법도 고려했다.
sudo docker ps -aq --filter ancestor=eatssu/eatssu-dev
하지만 이미지 이름이나 태그가 바뀌면 신뢰하기 어렵다.
이 서버에서는 애플리케이션이 항상 9000 포트를 사용하므로, 포트 기준으로 찾는 방식이 더 단순하고 확실했다.
sudo docker ps -q --filter publish=9000
이 방식은 컨테이너 이름이 랜덤이어도 잡을 수 있다. 단, 해당 EC2에서 9000 포트를 사용하는 컨테이너는 이 애플리케이션뿐이어야 한다는 전제가 있다. 실제로 서버에서 확인해보니 9000 포트를 사용하는 컨테이너는 하나뿐이었다.

2. xargs 대신 if 문을 사용한 이유
처음에는 이렇게 작성했다.
sudo docker ps -q --filter publish=9000 | xargs -r sudo docker rm -f
xargs -r은 GNU xargs 옵션으로, Ubuntu EC2에서는 문제없지만 macOS에서는 동작하지 않는다.
이식성과 가독성을 위해 if 문으로 바꿨다. 조금 길어졌지만 의도가 더 명확하고 환경 의존성도 줄었다.
PUBLISHED_CONTAINERS=$(sudo docker ps -q --filter publish=9000)
if [ -n "$PUBLISHED_CONTAINERS" ]; then
sudo docker rm -f $PUBLISHED_CONTAINERS
fi
3. restart policy 추가
기존에는 restart policy가 없었다.
docker run -d -p 9000:9000 ...
이 경우 EC2가 재부팅되거나 Docker daemon이 재시작되면 컨테이너가 자동으로 다시 올라오지 않는다. --restart unless-stopped 옵션을 추가했다. unless-stopped는 사용자가 직접 중지하지 않은 컨테이너를 Docker 재시작 시 자동으로 다시 실행한다. 운영 서버에서는 기본적으로 넣는 것이 좋다.
sudo docker run -d --name eatssu-dev --restart unless-stopped -p 9000:9000 ...
✏️ 배포 후 확인
1. 컨테이너 상태
컨테이너 이름이 랜덤에서 eatssu-dev로 고정된 것을 확인했다.

2. restart policy 확인

3. Health check

4. CloudWatch 에러 로그 확인
아무 로그도 출력되지 않았다. 최근 10분간 ERROR 로그 없음.

✏️ 최종 결과
| 항목 | 기존 | 개선 |
| 컨테이너 삭제 범위 | EC2 전체 | 애플리케이션 컨테이너만 |
| 컨테이너 이름 | 랜덤 | eatssu-dev 고정 |
| restart policy | 없음 | unless-stopped |
| 기존 랜덤 이름 컨테이너 정리 | — | 포트 기반 정리 |
✏️ 마무리
이번 작업은 무중단 배포까지 적용한 것은 아니다. 여전히 기존 컨테이너를 내리고 새 컨테이너를 올리는 방식이다.
하지만 전체 컨테이너 삭제라는 위험한 동작을 제거했고, 컨테이너 관리 기준을 명확히 했다. 무중단 배포로 가기 전 단계에서 반드시 해야 하는 안정화 작업이라고 볼 수 있다.
https://github.com/EAT-SSU/Server/pull/369
fix: 배포 스크립트 컨테이너 관리 안정화 by pooreumjung · Pull Request #369 · EAT-SSU/Server
#️⃣ Issue Number resolved fix: 배포 스크립트 컨테이너 관리 안정화 #368 📝 요약(Summary) sudo docker rm -f $(docker ps -qa) 제거 → 이름 기반(eatssu-prod / eatssu-dev) 삭제로 변경하여 다른 컨테이너가 함께 종
github.com
'Back-End > 잇슈' 카테고리의 다른 글
| [EAT-SSU / 잇슈] - Grafana Cloud + Alloy로 모니터링 구축 (0) | 2026.06.30 |
|---|---|
| [EAT-SSU / 잇슈] OAuth 토큰 로그 노출 방지 작업 정리 (0) | 2026.06.23 |
| [EAT-SSU / 잇슈] GitHub Actions 빌드 시간 줄이기 (0) | 2026.06.22 |
| [EAT-SSU / 잇슈] RDS 데이터 다른 AWS 계정으로 이전하기 (0) | 2026.05.03 |
| [EAT-SSU / 잇슈] DNS 설정 실수로 인한 서버 장애 트러블슈팅 (0) | 2026.04.30 |
- Total
- Today
- Yesterday
- c++ string
- 카운팅 정렬
- 자료구조
- DP
- C++
- 이분 매칭
- 유클리드 호제법
- 알고리즘 공부
- 자바스크립트
- 스택
- 백준 풀이
- 우선순위 큐
- 알고리즘
- 스프링 부트 crud 게시판 구현
- 반복문
- DFS
- js
- 백준
- BFS
- 세그먼트 트리
- 투 포인터
- 에라토스테네스의 체
- 유니온 파인드
- html
- HTML5
- CSS
- 자바
- Do it!
- C++ Stack
- java
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |