사무실 서버를 운영하면 정전을 피할 수 없다. 주말에 건물 전기 점검으로 전원이 나간 적이 있는데, 월요일 아침에 출근해보니 서버가 꺼져 있었다. 서비스 전부 다운. 원격으로 켤 수도 없어서 직접 전원 버튼을 눌러야 했다. 그 뒤로 자동 복구를 세팅해뒀고, 이후에는 정전이 와도 전기 복구 후 알아서 서버가 켜지고 서비스까지 올라온다.

BIOS 설정: 전원 복구 시 자동 부팅

서버나 PC의 BIOS에 “AC Power Recovery” 또는 “After Power Loss” 같은 옵션이 있다. 보통 세 가지 중 하나를 선택할 수 있다:

  • Power Off: 전원이 들어와도 꺼진 상태 유지 (기본값)
  • Power On: 전원이 들어오면 자동으로 켜짐
  • Last State: 정전 전 상태를 복원 (켜져 있었으면 켜짐)

Power On으로 설정하면 된다. BIOS 진입 방법은 메인보드마다 다르지만 보통 부팅 시 DEL이나 F2를 누른다.

  • ASUS: Advanced → APM Configuration → Restore AC Power Loss → Power On
  • Dell: Power Management → AC Recovery → On
  • HP: Advanced → Power-On Options → After Power Loss → On
  • Supermicro: Advanced → Chipset Configuration → Restore on AC Power Loss → Power On

서버용 메인보드라면 거의 100% 이 옵션이 있다. 일반 데스크탑 보드도 대부분 지원한다.

Docker Restart Policy

서버가 켜지면 OS는 부팅되지만 Docker 컨테이너는 자동으로 안 올라올 수 있다. restart policy를 설정해둬야 한다:

# docker-compose.yml
services:
  app:
    image: your-app:latest
    restart: unless-stopped

  db:
    image: postgres:15
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    restart: unless-stopped

restart policy 옵션:

옵션 동작
no 자동 재시작 안 함 (기본값)
always 항상 재시작 (수동 중지해도 부팅 시 다시 시작)
unless-stopped 수동 중지하지 않았다면 재시작
on-failure 에러로 종료됐을 때만 재시작

unless-stopped가 가장 실용적이다. docker stop으로 직접 멈춘 컨테이너는 다시 안 뜨고, 정전 같은 비정상 종료 후에는 자동으로 올라온다.

Docker 서비스 자동 시작

Docker 데몬 자체가 부팅 시 시작되어야 한다:

sudo systemctl enable docker
sudo systemctl is-enabled docker
# enabled 가 나오면 정상

서비스 시작 순서

DB가 먼저 뜨고 앱이 나중에 떠야 하는데, Docker restart policy만으로는 순서를 보장할 수 없다. depends_on을 쓰면 compose up 할 때는 순서를 지키지만, 재시작할 때는 보장이 안 된다.

앱 쪽에서 DB 연결 실패 시 재시도 로직을 넣는 게 더 확실하다:

// DB 연결 재시도 예시
async function connectWithRetry(maxRetries = 10) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      await db.connect();
      console.log('DB connected');
      return;
    } catch (err) {
      console.log(`DB connection failed, retry in 5s... (${i + 1}/${maxRetries})`);
      await new Promise(r => setTimeout(r, 5000));
    }
  }
  throw new Error('DB connection failed after retries');
}

부팅 후 알림 보내기

서버가 자동으로 켜졌는지 확인하려면 부팅 시 알림을 보내게 해두면 편하다. systemd 서비스를 하나 만든다:

sudo nano /etc/systemd/system/boot-notify.service
[Unit]
Description=Boot notification
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/boot-notify.sh

[Install]
WantedBy=multi-user.target

알림 스크립트:

#!/bin/bash
# /usr/local/bin/boot-notify.sh

sleep 30  # 네트워크 안정화 대기

HOSTNAME=$(hostname)
BOOT_TIME=$(uptime -s)
DOCKER_STATUS=$(docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null || echo "Docker not running")

# Slack webhook으로 알림
curl -s -X POST "https://hooks.slack.com/services/YOUR_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d "{\"text\": \"🖥️ 서버 부팅됨\\n호스트: ${HOSTNAME}\\n시간: ${BOOT_TIME}\\n\\n컨테이너 상태:\\n${DOCKER_STATUS}\"}"
sudo chmod +x /usr/local/bin/boot-notify.sh
sudo systemctl enable boot-notify.service

UPS 연동 (선택)

예산이 있다면 UPS(무정전 전원장치)를 붙이는 것도 좋다. apcupsdnut 같은 소프트웨어로 UPS 상태를 모니터링하고, 배터리가 얼마 안 남았을 때 안전하게 셧다운할 수 있다:

sudo apt install apcupsd

UPS가 정전을 감지하면 일정 시간 후 자동으로 shutdown -h now를 실행해서 데이터 손실을 방지한다. 전원 복구 후에는 BIOS 설정에 의해 다시 부팅된다.

이렇게 세팅하면 정전 → 전원 복구 → 자동 부팅 → Docker 서비스 자동 시작 → 알림까지 전부 자동이다. 주말에 정전이 와도 월요일 아침에 안심하고 출근할 수 있다.