원격 데스크톱 자동 복구 워치독
원격 데스크톱 웹 서비스가 멈추면 사람이 없어도 스스로 되살리도록 설계한 감시 장치를 만들었다.
무엇을 만들었나
컨테이너 실행 환경(Docker)이 한밤중에 꺼져 원격 데스크톱 웹 서비스가 약 9시간 멈춘 일을 계기로, 5분마다 상태를 확인하고 필요할 때만 되살리는 감시 프로그램을 만들었다. 정상일 때는 조용히 있고, 복구를 시도하거나 포기할 때만 알림을 보낸다. 복구가 반복해서 실패해도 무한 재시도로 폭주하지 않게 했다. 실제 설치와 장애 주입 시험은 검수 후 사람이 하도록 남겨 두었고, 이 작업에서는 시험 실행(dry-run)과 모의 환경 검사 13개까지 확인했다.
구현 방식과 보안 설계는 ‘기술 상세’에 있습니다.
구조와 설계
bash 워치독 스크립트와 macOS LaunchAgent(RunAtLoad + StartInterval 300초)로 구성했다. 정상 판정은 docker info 성공, 스택 컨테이너가 모두 running, 웹 포트 HTTP 응답이며 정상일 때는 상태 파일만 갱신한다. 데몬이 죽으면 Docker Desktop을 띄우고 최대 180초 재확인하고, 컨테이너가 빠지면 이 저장소의 compose 프로젝트에만 up -d를 실행하며 down·stop·rm·prune과 강제 재생성은 쓰지 않는다. 상태 JSON에 마지막 복구 시각과 연속 실패 수를 기록해 10분 내 재시도 금지, 5회째 실패에서 중단하는 백오프를 구현했고, 주기 실행 스크립트라 KeepAlive는 의도적으로 쓰지 않았다. 실제 LaunchAgent 설치·복구·알림 발송은 검수 후 사람이 하도록 이 작업에서는 실행하지 않았다.
사용 기술
bash, Docker / Docker Compose, macOS launchd (LaunchAgent), 웹 기반 원격 접속 게이트웨이, Python (모의 검증 스크립트), plutil, Discord 웹훅 알림
보안·안정성 설계
- 저장소에 킬 스위치 파일이 있으면 즉시 종료하는 장치를 두어 일부러 Docker를 꺼 둔 경우 간섭하지 않는다.
- 복구 명령 범위를 이 저장소의 compose 프로젝트로 한정하고 down·stop·rm·prune·강제 재생성을 쓰지 않아 다른 컨테이너나 데이터를 건드리지 않는다.
- 복구 폭주 방지: 10분 내 재시도 금지, 5회째 실패에서 중단, 성공 시 카운터 초기화. 컨테이너는 모두 running인데 HTTP만 실패하는 경우는 자동 복구 대상에서 빼고 수동 점검으로 기록한다.
- 알림 웹훅 주소는 별도 env 파일에서 읽고 로그에 남기지 않는다. 파일이 없으면 알림만 건너뛰고 복구는 계속하며, 오류 기록에도 비밀값을 넣지 않는다.
- set -euo pipefail, LaunchAgent용 PATH 명시, docker 호출 타임아웃을 적용하고, 전체 실행을 주기(300초)보다 짧은 240초 이내로 끝나게 설계했다.
- 로그는 1MB 초과 시 1회 회전하고, --dry-run 모드는 판정만 출력하고 아무것도 바꾸지 않는다.
작업 기록
Docker 감시 워치독과 launchd 서비스 추가
필요할 때만 되살리는 bash 워치독과 5분 주기 LaunchAgent를 만들고 킬 스위치, 백오프, 알림, dry-run 모드를 넣었다. 실제 환경 dry-run은 '정상, 조치 없음'으로 판정됐고 모의 환경 13개 검사가 통과했다.
이 페이지는 작업 기록 문서 1건을 바탕으로 정리했습니다. 고객 정보, 접속 주소, 비밀값은 공개 전에 걸러 냅니다.