리눅스 서버 재기동 (Reboot) 후 도커 서비스 순차 자동실행 설정

작성일2026년 5월
버전Docker Compose v2.x / systemd 최신
타입🐳 인프라 마스터
난이도중급 ~ 전문가
Docker Autostart systemd 서비스 순차 가동 자동화 의존성 해결 트러블슈팅 홈랩 운영
리눅스 서버 재기동(Reboot) 후 “어라? 분명 모든 서비스에 restart: always 정책을 넣어뒀는데 왜 도커가 하나도 안 떴지?” 하며 당황한 경험이 있으실 겁니다. 특히 고성능 로컬 AI 모델(Ollama, ComfyUI)이나 다양한 자동화 스택(n8n, Dify), 데이터베이스와 블로그를 복합적으로 self-hosting하는 환경에서는 시스템 부팅 시 컨테이너가 누락되는 일이 빈번하게 발생합니다. 본 가이드에서는 이 현상의 근본적인 아키텍처적 원인을 분석하고, 의존성 꼬임 없이 가장 안전하고 세련되게 스택들을 순차 가동하는 마스터 솔루션을 공유합니다.
SECTION01

restart: always 설정이 무력화되는 3가지 근본 원인

Docker에서 제공하는 restart: always 또는 unless-stopped 정책은 매우 훌륭하지만, 리눅스 서버 재기동 시 하이퍼바이저나 베어메탈 서버가 **완전히 꺼졌다 켜지는 시점(Cold Boot)**에는 제 역할을 하지 못하는 경우가 많습니다. 크게 3가지 병목 포인트가 존재합니다.

1. 외부 대통합 선언 네트워크(external)의 타이밍 격차

여러 docker-compose 스택이 서로 API 통신이나 리포지토리를 물기 위해 외부 공통 브릿지 망(예: ai-common-net)을 external: true로 선언해 사용하는 경우가 많습니다. 시스템 재기동 시 Docker 데몬은 깨어났지만 이 공통 가상 망이 아직 생성/준비되지 않은 찰나의 순간에 컨테이너가 기동을 시도하면, “network not found” 에러를 뱉으며 즉시 영구 정지(Dead) 상태로 빠집니다.

2. GPU 커널 모듈(NVIDIA Driver) 로딩의 레이턴시

Ollama, ComfyUI 등 RTX 그래픽카드를 사용하는 엔지니어링 스택은 runtime: nvidia 설정을 지니고 있습니다. 시스템이 부팅될 때 리눅스 커널이 NVIDIA 드라이버 및 UVM 모듈을 완전히 로드하는 속도보다, Docker 데몬이 컨테이너를 올리는 속도가 미세하게 더 빠릅니다. 런타임 장치가 없는 상태에서 컨테이너 구동 명령이 전달되면 정책과 무관하게 터져버립니다.

3. 스토리지 볼륨 볼륨 마운트(NFS/ZFS/RAID) 지연

대용량 데이터를 저장하기 위해 별도의 드라이브 어레이나 /mnt/data 하위 마운트 포인트를 구성한 경우, 파일 시스템이 마운트(mount) 완료되기 전에 도커가 선행 구동되면 설정 파일이나 데이터 볼륨 경로를 찾지 못해 컨테이너 진입점(Entrypoint) 단계에서 실행이 차단됩니다.

SECTION02

치명적인 안티패턴 — 하면 안 되는 두 가지 실수

이 문제를 해결하려고 시도할 때, 시스템 엔지니어들이 가장 자주 저지르는 두 가지 치명적인 실수가 있습니다.

⚠️ 흔히 저지르는 치명적 실수 (Anti-Patterns)
  • 다중 systemd 유닛 쪼개기 및 복잡한 의존성(Requires=) 연결: 네트워크 생성용 서비스, DB 가동용 서비스 등을 여러 개로 파편화하여 상호 의존성을 걸어두는 방식입니다. 만약 네트워크가 이미 존재하거나 사소한 에러 코드가 리턴되면, systemd는 연쇄적으로 하위 서비스를 차단하여 Job failed with result 'dependency' 라는 먹통 상태를 유발합니다.
  • 도커 컴포즈 파일 내 depends_on에만 의존하기: depends_on은 단일 스택 내부의 구동 순서만 제어할 뿐, 서로 분리된 다중 스택(인프라 스택, 크롤러 스택, 웹 블로그 스택 등) 사이의 하드웨어 타이밍이나 기동 타이밍은 절대 보장해 주지 못합니다.
SECTION03

마스터 솔루션 — 단 하나의 셸 스크립트로 통합 제어

가장 깔끔하고 견고한 아키텍처는 **”Docker 데몬이 확실하게 문을 연 직후(After=docker.service), 단 하나의 마스터 제어 스크립트가 순차적으로 타이밍 대기를 주도하며 모든 스택을 일깨우는 방식”**입니다. 복잡한 의존성 꼬임을 원천 차단합니다.

📋 가상 인프라 경로 시나리오

우선순위 스택명 실제 물리 경로 목적 및 가동 전략
1순위 Core Infra (기본 데이터) /mnt/data Postgres DB, Ollama, CouchDB 등 기초 인프라 선행 안착 (30초 대기)
2순위 Automation (자동화 스택) /mnt/data/automation/firecrawl 데이터 덤프 및 스크래핑 엔진 활성화 (15초 대기)
3순위 AI Agents (에이전트 스택) /mnt/data/ai/dify 기초 인프라의 Vector DB 및 LLM 엔진을 빌려 타임아웃 없이 연동
4순위 Web (서비스 스택) /mnt/data/web/wordpress 최종 사용자단 블로그 가동 및 리버스 프록시 진입점 개방 완료

🛠️ 실전 순차 가동 통합 마스터 스크립트 작성

아래 경로에 스크립트 파일을 생성하고 완벽한 시퀀스 제어 명령을 주입합니다.

/mnt/data/system/scripts/docker-autostart.sh
bash
#!/bin/bash
echo "=== [Docker Stack Sequential Autostart] Engine Initiated ==="

# [핵심] 외부 공통 네트워크 유실 방지를 위한 선행 생성 (이미 존재 시 에러 무시 처리)
/usr/bin/docker network create ai-common-net 2>/dev/null

# Step 1. 최우선 순위 핵심 인프라 및 엔진 스택 가동
echo "▶ [1/4] 기본 데이터 및 핵심 AI 인프라 가동..."
cd /mnt/data
/usr/bin/docker compose up -d

# GPU 드라이버 커널 안착 및 DB 커넥션 수립을 위한 넉넉한 유예 시간 부여
echo "🕒 인프라 안전성 확보 및 하드웨어 포트 매핑 대기 중 (30s)..."
sleep 30

# Step 2. 크롤링 자동화 엔진 가동
echo "▶ [2/4] Firecrawl 스크래핑 인프라 가동..."
cd /mnt/data/automation/firecrawl
/usr/bin/docker compose up -d
sleep 15

# Step 3. 상위 오케스트레이션 플랫폼 가동 (앞서 가동된 DB와 LLM 결속)
echo "▶ [3/4] Dify AI 에이전트 플랫폼 가동..."
cd /mnt/data/ai/dify
/usr/bin/docker compose up -d
sleep 15

# Step 4. 최종 퍼블릭 웹 서비스 구동
echo "▶ [4/4] WordPress 블로그 스택 가동..."
cd /mnt/data/web/wordpress
/usr/bin/docker compose up -d

echo "=== [Docker Stack Sequential Autostart] All Systems Nominal ==="
💡
알면 유익한 리눅스 퍼미션 팁

스크립트를 다 짠 후에는 리눅스 커널이 이 파일을 실행 파일로 인지할 수 있도록 권한을 변경해 주어야 합니다. 터미널에서 sudo chmod +x /mnt/data/system/scripts/docker-autostart.sh 명령을 반드시 실행하세요.

SECTION04

systemd 전용 백그라운드 서비스 유닛 등록 및 검증

이제 작성한 징검다리 셸 스크립트를 OS 데몬 스케줄러(systemd)에 등록하여, 서버가 부팅될 때 단 한 번 깔끔하게 트리거되도록 묶어줍니다.

/etc/systemd/system/docker-stacks-autostart.service
ini
[Unit]
Description=Docker Stacks Sequential Autostart Service
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/mnt/data/system/scripts/docker-autostart.sh
RemainAfterExit=yes
TimeoutStartSec=10min

[Install]
WantedBy=multi-user.target

🔄 데몬 활성화 및 서비스 운영 명령어

유닛 설정을 마쳤다면 아래 시퀀스를 입력해 시스템 스케줄러에 영구 등록합니다.

bash
# 1. 새롭게 추가된 systemd 구성 설정 리로드
sudo systemctl daemon-reload

# 2. 서버 부팅 시 자동 시작되도록 플래그 활성화
sudo systemctl enable docker-stacks-autostart.service

# 3. 서버를 안 끄고 이 자리에서 즉시 전체 시퀀스 정상 작동 여부 수동 테스트
sudo systemctl start docker-stacks-autostart.service

✅ 정상 가동 확인 체크포인트

  • 서비스 상태 조회(status) 시 enabled 확인: sudo systemctl status docker-stacks-autostart.service를 입력했을 때 loaded (...; enabled; ...) 상태인지 확인합니다.
  • i
    실시간 인프라 부팅 로그 추적: 서버를 재기동하거나 재시작 명령을 내린 직후, sudo journalctl -u docker-stacks-autostart.service -f 명령을 통해 지정한 타임아웃 간격(30초, 15초)을 두고 스택들이 순차적으로 우아하게 살아나는지 관측합니다.
🚀
결론 및 무중단 운영 팁

환경 설정 파일(.env)을 크게 고쳤거나 구조를 다 뜯어고친 뒤 전체 스택을 완전히 클린 리프레시하고 싶다면, 귀찮게 폴더마다 찾아다닐 필요 없이 sudo systemctl stop docker-stacks-autostart.service를 치면 안전하게 역순으로 모든 컨테이너가 내려갑니다. 다시 켜고 싶을 때는 start를 주면 다시 이쁘게 순서대로 일어납니다. 정교하게 다듬어진 자동화 스크립트 하나로 더 안전하고 완벽한 홈랩 서버 인프라를 유지하세요!

Leave a reply

Please enter your comment!
Please enter your name here