Setting Log/Docker

[Docker] 도커 컴포즈 restart: 서버가 터져도 스스로 살아나는 인프라 구축

odong 2026. 7. 10. 09:53

도커 컴포즈로 백엔드 API 서버나 데이터베이스를 배포하면, 새벽에 예외 처리가 안 된 치명적인 에러(OOM, 세그멘테이션 폴트, DB 커넥션 끊김 등)가 발생해 컨테이너 프로세스가 죽어버렸고, 아침에 일어나 보니 서비스가 통째로 다운(Exited (1))되어 있는 상황을 겪습니다.

이를 방지하고 서버 인프라가 알아서 컨테이너의 상태를 감시하고 Self-healing하도록 가드레일을 쳐주는 옵션이 바로 restart 속성입니다. 오늘은 docker-compose.yml 파일에서 사용할 수 있는 4가지 재시작 정책의 차이점을 확실하게 비교 정리해 둡니다.

1. restart 정책 4가지

도커 컴포즈 명세서 내부에 적재할 수 있는 설정값은 아래 테이블과 같이 딱 4가지가 존재합니다.

정책 (Value) 설명 실무 권장 용도
no 어떤 상황에서도 컨테이너를 자동으로 재시작하지 않음 (기본값) 로컬 테스트, 일회성 마이그레이션 배치
on-failure 컨테이너가 에러 코드를 뱉고 죽었을 때만(Exit Code가 0이 아닐 때) 재시작 백엔드 API 애플리케이션 서버
always 정상 종료든 에러 종료든, 심지어 도커 데몬이 켜질 때도 무조건 재시작 데이터베이스, 인메모리 캐시 (Redis)
unless-stopped always와 거의 같으나, 개발자가 명시적으로 중지(docker-compose down/stop)한 경우는 예외 [강력 추천] 프로독션 운영 인프라의 표준 스택

2. 속성별 차이점

① no (디폴트 세팅)

명시하지 않으면 무조건 이 상태입니다. 프로세스가 비정상 종료되어도 그대로 멈춰 있습니다. 로컬 개발 환경에서 디버깅을 하며 에러 로그를 추적해야 할 때는 유용하지만, 실제 운영 서버 환경에서는 절대로 방치해선 안 되는 값입니다.

② on-failure

services:
  api-server:
    image: my-backend-app:latest
    restart: on-failure
  • 동작: 정상적으로 작업을 끝내고 종료된 경우(Exit Code: 0)에는 가만히 두고, 예외 버그나 메모리 부족으로 터진 경우(Exit Code: 1 등)에만 도커 엔진이 컨테이너를 다시 살려냅니다.
  • on-failure:5 처럼 콜론 뒤에 숫자를 붙이면 "최대 5번까지만 재시도하고, 계속 터지면 포기해라"라는 방어벽을 칠 수 있습니다.

③ always vs unless-stopped

두 옵션 모두 컨테이너가 어떤 이유로 죽든 살려낸다는 공통점이 있습니다. 리눅스 서버 가동 자체가 리부팅되어 도커 데몬이 처음 켜질 때도 컨테이너들을 자동으로 띄워줍니다.

하지만 결정적인 차이점은 '개발자가 수동으로 껐을 때' 드러납니다.

  • always: 개발자가 점검을 위해 docker-compose stop으로 컨테이너를 잠시 꺼두었더라도, 훗날 리눅스 서버를 리부팅하거나 도커 데몬이 재시작되면 "어? 너 왜 꺼져있어? 무조건 켜!" 하고 살려내 버립니다.
  • unless-stopped: 똑같이 자가 치유를 하지만, "개발자가 명시적으로 멈춰둔 녀석은 리부팅되어도 깨우지 않고 존중해 준다"는 예외 필터가 작동합니다. 이 때문에 실무 DevOps 환경에서는 unless-stopped를 표준적인 가드레일로 채택합니다.

3. docker-compose.yml 템플릿

version: '3.8'

services:
  # 주기적으로 데이터를 쌓고 정상 종료되는 배치 컨테이너
  migration-task:
    image: data-miner:1.0
    restart: "no" # 정상 종료 후 꺼져 있어야 하므로 no 지정

  # 예외 에러 레이턴시를 방어해야 하는 백엔드 API
  web-api:
    image: node:alpine
    restart: on-failure:3 # 에러 발생 시 딱 3번까지만 스스로 재기동 시도

  # 서버가 켜져 있는 한 365일 무중단 가동되어야 하는 DB 안정망
  database:
    image: postgres:15
    restart: unless-stopped # 무인 자가 치유를 하되, 작업자가 의도적으로 껐을 때는 대기

 

도커 컴포즈 아키텍처를 설계할 때 restart: unless-stopped 한 줄을 적재하는 습관만 들여도, 새벽에 알 수 없는 일시적인 가용성 오버헤드로 서버가 다운되었을 때 시스템이 컨테이너를 재시작 해주는 자동화 가치를 누릴 수 있습니다.

내 컨테이너 프로세스의 생명 주기 특성을 고려하여 알맞은 인프라 옵션을 바인딩해 보시기 바랍니다.