codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›infra

단일 서버 운영의 자리

2026-04-28 게시· 2026-05-18 갱신·0회 조회

단일 서버 운영의 자리

서비스가 시작 단계라면 한 대의 VPS 에 docker compose 로 모든 것을 띄우는 구성이 종종 가장 합리적입니다. 운영 인지 부하가 작고 비용이 예측 가능. 이 모델이 어디까지 가능한지 · 언제 한계에 닿는지 · k8s 를 비롯한 다음 단계의 자리.

1. 단일 서버 + Compose 의 일반적 구성

  • 한 대의 리눅스 호스트 (Ubuntu · Debian · Rocky 등).
  • Caddy 또는 nginx 가 80 / 443 에서 종단.
  • 애플리케이션 · DB · Redis · 큐가 같은 호스트의 컨테이너로 공존.
  • 로그 · 메트릭은 호스트 또는 한정된 외부 서비스로.
  • 정기 백업이 별도 디스크 또는 오브젝트 스토리지로.

수직 확장 (스펙 큰 머신) 으로 상당 거리까지 갈 수 있습니다. 적절히 만들어진 단일 서버가 하루 수백만 요청을 다루는 사례가 종종 보고 (작업 성격에 크게 좌우).

2. 수직 확장 vs 수평 확장

  • 수직 (scale up) — 더 큰 단일 머신. 단순. 한계는 머신 스펙 · 실패 도메인 단일.
  • 수평 (scale out) — 여러 머신으로 분산. 가용성 · 확장성. 비용은 운영 복잡도.

수직 확장은 코드 변경이 거의 없음. 수평 확장은 상태 공유 · 세션 · 캐시 · DB 라우팅 · 로깅 집계 같은 결정이 줄줄이 따라옴.

3. 운영 도구

  • compose.yaml — 서비스 정의 + restart: unless-stopped.
  • systemd — Compose 자체를 부팅 시 자동 시작 (docker-compose@.service 같은 unit).
  • 로그 회전 — Docker 로그 드라이버 옵션 또는 logrotate.
  • 백업 — pg_dump / pg_basebackup 의 cron + 오브젝트 스토리지 업로드.
  • 모니터링 — Prometheus + Grafana 컨테이너, 또는 외부 SaaS (uptime · APM).

4. 가용성의 기본

자동 재시작 — compose restart: unless-stopped, systemd 의 Restart=always.

헬스체크 — 컨테이너 healthcheck + 외부 상태 모니터.

이 둘만으로 단순 장애의 대부분은 자동 회복. 호스트 자체가 죽는 경우는 별개의 이야기.

5. 다른 길

도구 첫 등장 메모
Docker Swarm 2014–2015 Docker 가 만든 오케스트레이터. 비교적 단순. 활발한 발전은 둔화.
Nomad (HashiCorp) 2015 단일 바이너리. 컨테이너 외 작업도 다룸. 운영 복잡도 중간.
Kubernetes 2014 (Google) → CNCF 1.0 (2015) 사실상의 컨테이너 오케스트레이션 표준. 거대한 생태계.
Nomad + Consul + Vault — 분산 시스템 빌딩 블록의 다른 조합.

k8s 는 강력하지만 인지 부하가 크다는 평이 일반적. 작은 팀이 k8s 를 직접 운영하면 본업보다 클러스터 유지에 시간이 더 들 수 있음. 매니지드 (EKS / GKE / AKS) 가 그 부담을 줄이지만 여전히 학습 · 운영 비용.

6. k8s 가 과한 자리

다음은 단일 호스트로 충분한 경우가 많음:

  • 팀 규모가 작고 (수 명) 서비스 수가 적음 (< 10).
  • 트래픽이 한 호스트로 처리 가능.
  • 무중단 배포의 엄격함이 비즈니스 임계가 아님.
  • 운영 인력의 시간이 제한.

반대로 다음이 누적되면 단일 호스트는 한계:

  • 단일 실패 지점이 사업 위험.
  • 트래픽이 여러 머신으로 나뉘어야 함.
  • 여러 팀이 독립 배포를 원함.
  • 다중 리전 · 지연 민감 사용자.

7. 부팅 자동화 예

# /etc/systemd/system/myapp.service
[Unit]
Description=My App via Docker Compose
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target

8. 백업 잡 (PostgreSQL 예)

# /etc/cron.daily/db-backup
#!/usr/bin/env bash
set -euo pipefail
TS=$(date +%Y%m%d-%H%M)
docker exec db pg_dump -U postgres app | gzip > /backup/db-$TS.sql.gz
find /backup -name 'db-*.sql.gz' -mtime +14 -delete
# 오프사이트 업로드
rclone copy /backup remote:backup/

데이터 손실 위험을 가장 잘 줄이는 것은 백업 자체가 아니라 복원 리허설. 테스트 호스트에 복원해 보는 절차를 정기적으로 돌리는 편이 안전.

9. 단일 호스트 무중단 배포

  1. 새 컨테이너를 다른 포트로 띄움.
  2. 헬스체크가 통과하면 프록시 (Caddy / nginx) 의 업스트림을 새 포트로 전환.
  3. 구 컨테이너 종료.

Caddy 의 동적 설정 또는 traefik 의 라벨 기반 디스커버리가 이 흐름을 돕습니다.

10. 자주 걸리는 자리

단일 디스크의 SPOF — RAID · 정기 백업 · 오프사이트 복사가 없다면 디스크 한 번에 모든 것이 사라질 수 있음.

호스트 OS 업데이트 시 다운타임 — 커널 업데이트 등은 재부팅 필요. 사전 공지 또는 별도 호스트로 임시 이전.

메모리 한도 — 컨테이너가 늘어나면 OOM 이 잦아짐. 컨테이너별 mem_limit · DB 의 shared_buffers 튜닝.

로그 · 메트릭의 디스크 점유 — 로그 회전 · Prometheus retention 설정을 빠뜨리면 디스크가 차서 서비스가 멈춤.

운영 호스트에서의 즉흥 변경 — 서버에 직접 SSH 로 들어가 패키지를 깐 뒤 그 사실을 잊음. 변경은 가능한 한 코드 (Compose · Ansible) 에 남김.

하고픈 말

단일 서버 + Compose 는 작은 팀의 가장 합리적인 출발점입니다. 코드의 95% 를 비즈니스 로직에 쓸 수 있고, k8s 학습 곡선과 인프라 운영 부담에서 자유. 한계가 보이기 시작하면 그때 수평 확장의 한 단계만 (DB 분리 → 매니지드 k8s) 신중하게 올라갈 만한 자리.

Next

  • local-https-mkcert
  • cloud-emulator-stack

Compose 운영 가이드 · Restart policies (Docker) · Kubernetes 공식 · Nomad 공식 · PostgreSQL 백업 문서 를 참고합니다.

infra 카테고리의 다른 글

카테고리 전체 보기 →
  • 클라우드 에뮬레이터 스택 — 4번째 환경의 설계
  • 로컬 HTTPS — mkcert 와 자체 CA
  • 루프백 바인딩과 SSH 터널
  • Caddy 와 nginx — 비교의 자리
  • Docker Compose 패턴
  • Docker 기초