iBetter Books
수정

Ch 05. 장애 대응 체크리스트

배포하면 이상한 일이 생깁니다. 로컬에서는 잘 됐는데 서버에서 안 된다, 어제까지 됐는데 오늘 갑자기 안 된다. 당황하지 않는 것이 먼저입니다. 순서대로 확인하면 대부분 원인을 찾을 수 있습니다.

사이트 접속 불가 시 진단 순서

1단계: 컨테이너 상태 확인

# 컨테이너가 실행 중인지 확인ssh ibetter "docker compose ps"# 예상 출력# NAME          STATUS    PORTS# my-blog-app   Up        0.0.0.0:3000->3000/tcp# my-blog-db    Up        5432/tcp```text컨테이너가 `Exited` 상태라면 재시작합니다.```bashssh server "cd /app && docker compose up -d"```text#### 2단계: 로그 확인```bash# 최근 100줄 로그 확인ssh server "docker logs my-blog-app --tail 100"# 실시간 로그 스트리밍ssh server "docker logs my-blog-app -f"```text에러 메시지를 찾습니다. 일반적인 에러들입니다.

데이터베이스 연결 실패

Error: Can't reach database server at 'db:5432'

환경변수 누락

Error: Environment variable not found: AUTH_SECRET

포트 충돌

Error: address already in use

#### 3단계: next_cache 볼륨 삭제캐시 볼륨이 이전 빌드와 충돌할 수 있습니다.```bashssh server "cd /app && \  docker compose down && \  docker volume rm app_next_cache && \  docker compose up -d"```text볼륨 이름은 `docker-compose.yml`의 프로젝트명과 볼륨명의 조합입니다. `docker volume ls`로 확인합니다.#### 4단계: --no-cache 강제 재빌드`Dockerfile`이나 `package.json`을 변경했다면, 캐시를 무시하고 완전히 다시 빌드해야 합니다.```bashssh server "cd /app && \  docker compose build --no-cache app && \  docker compose up -d app"```text이미지 크기가 크면 시간이 걸립니다. 로그를 모니터링합니다.### 데이터베이스 연결 실패 처리```bash# DB 컨테이너 상태 확인ssh server "docker compose ps db"# DB 로그 확인ssh server "docker logs my-blog-db --tail 50"# DB 직접 접속 테스트ssh server "docker compose exec db psql -U blogs -d myblog -c 'SELECT 1'"```textDB가 실행 중인데 앱이 연결 못 한다면 환경변수의 `DATABASE_URL`을 확인합니다. 컨테이너 내부에서 DB는 `localhost`가 아닌 서비스 이름(`db`)으로 접근해야 합니다.```bash# 잘못된 DATABASE_URLDATABASE_URL="postgresql://user:pass@localhost:5432/myblog"# 올바른 DATABASE_URL (docker-compose 내부 통신)DATABASE_URL="postgresql://user:pass@db:5432/myblog"```text### 롤백 절차배포 후 문제가 발생했을 때 이전 버전으로 돌아가는 방법입니다.```bash# 이전 커밋으로 코드 되돌리기ssh server "cd /app && git log --oneline -5"# 커밋 해시 확인ssh server "cd /app && \  git checkout {이전_커밋_해시} && \  docker compose build --no-cache app && \  docker compose up -d app"```text또는 이전 Docker 이미지를 저장해두었다면 그것을 사용합니다.```bash# 이미지 태그 목록 확인ssh server "docker images my-blog-app"# 특정 버전의 이미지로 롤백ssh server "docker compose down && \  docker tag my-blog-app:previous my-blog-app:latest && \  docker compose up -d"```text### 장애 예방 — 배포 전 체크리스트배포하기 전에 확인하는 습관을 들이면 장애를 줄일 수 있습니다.```text배포 전 체크리스트:[ ] npm run build가 로컬에서 성공하는가?[ ] 환경변수가 프로덕션에 모두 설정되어 있는가?[ ] 데이터베이스 마이그레이션이 필요한가?    - 필요하다면 배포 전 먼저 적용한다[ ] Dockerfile 또는 package.json을 변경했는가?    - 변경했다면 --no-cache 재빌드가 필요하다[ ] 변경 사항이 로컬에서 예상대로 동작하는가?

자주 발생하는 장애와 해결 요약

증상 가능한 원인 해결 방법
컨테이너가 계속 재시작 환경변수 누락, 포트 충돌 로그 확인, 환경변수 점검
페이지 응답 없음 (hang) standalone 빌드 + 볼륨 마운트 충돌 standalone 제거, next start 모드 사용
정적 파일 403 에러 파일 권한 문제 chown -R nextjs:nodejs /app
DB 연결 실패 DATABASE_URL 잘못됨 db 호스트명 사용 확인
빌드 후 캐시 충돌 next_cache 볼륨 docker volume rm 후 재시작
API 타임아웃 Vercel 무료 플랜 10초 제한 쿼리 최적화 또는 Pro 플랜

장애는 피할 수 없지만, 빠르게 대응하는 능력을 키울 수 있습니다. 매번 장애를 겪을 때마다 원인과 해결 방법을 기록해두면 다음에는 훨씬 빠르게 해결할 수 있습니다.

다음 PART에서는 이 긴 여정을 마무리하며 앞으로의 방향을 이야기합니다.