Skip to content
VDS · Docker 및 컨테이너

다운타임 없이 컨테이너 업데이트하기

서비스가 유지되고 롤백할 수 있도록 이미지를 업데이트하는 방법이에요. 버전 고정, 상태 확인, 단계 순서, 그리고 자동화를 알아봐요.

업데이트 2026년 8월 23일

컨테이너 업데이트는 “새 이미지를 당겨오는 것”이 아니라 “실행 중인 버전을 새 버전으로 교체하고 롤백할 수 있게 만드는 것”이에요. 이 차이는 딱 한 번 드러나요. 새 버전이 시작되지 않을 때요.

통하는 절차

cd /opt/myapp
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f --tail 100

Compose는 이미지가 바뀐 서비스만 다시 만들고 나머지는 그대로 둬요. 다운타임은 컨테이너를 재시작하는 몇 초뿐이에요.

하지만 이걸 하기 전에 두 가지 조건을 충족해야 해요.

첫째: 버전이 고정되어 있어야 해요. 파일에 postgres:latest가 아니라 postgres:17.2가 지정되어 있어야 해요. 그렇지 않으면 언젠가 pull이 데이터 형식을 다시 쓰는 메이저 버전을 가져오고, 롤백이 불가능해져요.

둘째: 백업이 최신이어야 해요. 데이터베이스를 망가뜨리는 업데이트는 되돌릴 수 없이 망가뜨려요. 메이저 버전을 바꾸기 전에는 덤프를 떠 두세요. 무엇을 백업할까요를 참고하세요.

끊김 없이 교체하기

리버스 프록시 뒤에 있는 웹 서비스라면 컨테이너에 헬스 체크가 있을 때 다운타임이 거의 0에 가까워져요. 프록시가 준비된 인스턴스에만 요청을 보내기 시작하거든요.

services:
  app:
    image: ghcr.io/example/app:1.5.0
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 5s
      timeout: 3s
      retries: 6
      start_period: 20s
docker inspect -f '{{.State.Health.Status}}' <container>

헬스 체크가 없으면 Compose는 프로세스가 시작되는 순간 컨테이너를 준비된 것으로 간주해요. 애플리케이션이 아직 설정을 읽고 마이그레이션을 적용하는 중인데도요.

새 버전이 최소 한 시간 동안 실행된 뒤에야 이전 이미지를 삭제하세요. 롤백은 image: ...:1.4.2를 복원하고 docker compose up -d를 실행하는 것이지만, 이전 이미지가 디스크에 남아 있을 때만 가능해요. 업데이트 직후의 docker image prune -a는 그 선택지를 여러분에게서 빼앗아 가요.

롤백

sed -i 's|app:1.5.0|app:1.4.2|' compose.yaml
docker compose up -d app
docker compose logs -f --tail 50 app

새 버전이 이미 데이터베이스 스키마를 바꿨다면 이미지만 되돌리는 것으로는 충분하지 않아요. 백업에서 복원해야 해요. 그래서 메이저 업데이트는 한산한 시간에 검증된 백업과 함께 진행해요. 복원 훈련을 참고하세요.

자동화: 조심하세요

Watchtower는 스스로 컨테이너를 업데이트할 수 있어요. 홈 서비스에는 편리하지만 프로덕션에서는 위험이에요. 업데이트가 밤에 도착해 데이터베이스를 망가뜨리고, 아무도 눈치채지 못하거든요. 합리적인 절충안은 알림만 받는 것이에요.

services:
  watchtower:
    image: containrrr/watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: --monitor-only --schedule "0 0 6 * * *"

새 버전이 나온 걸 알게 되고, 원하는 시간에 직접 업데이트하는 거예요.

머신 재부팅하기

시스템 패키지는 컨테이너와 별개로 업데이트돼요. 커널 업데이트 후에는 재부팅이 필요하고, restart: unless-stopped가 설정된 컨테이너는 스스로 다시 올라와요. 미리 테스트하세요. 장애 상황이 아니라 한산한 시간에 sudo reboot으로요. 제어판에서의 소프트 재부팅은 시스템에 qemu-guest-agent가 설치되어 있을 때 작동해요.

흔한 실수

  • up -d 없이 pull만 하기. 새 이미지는 내려받았지만 이전 컨테이너가 여전히 실행 중이에요.
  • 디스크가 이전 이미지로 가득 차 있기. 한 달에 한 번 docker image prune을 실행하세요. 단, 업데이트 직후에는 하지 마세요. 디스크 공간을 참고하세요.
  • 한꺼번에 전부 업데이트하기. 뭔가 망가지면 무엇 때문인지 알 수 없어요. 한 번에 서비스 하나씩 업데이트하세요.
  • 릴리스 노트를 읽지 않기. 호환되지 않는 설정 파일이 메이저 버전 변경 후 실패하는 가장 흔한 원인이에요. 흔한 Docker 문제의 분석을 참고하세요.