Coti Lab
kuro editor
업데이트
4분

Docker Compose로 홈서버 스택 구성하는 법

Docker Compose 홈서버 스택 구성

셀프호스팅 서비스를 하나둘 늘려가다 보면 서비스가 5개, 10개를 넘는 순간 “이 서비스는 어떻게 설치했더라?”를 기억하지 못하는 상황이 와요. Docker Compose는 이 문제를 해결하는 표준적인 방법으로, 각 서비스의 설정을 하나의 YAML 파일로 코드화해두면 서버를 재설치하거나 다른 하드웨어로 옮길 때도 명령어 한 줄로 동일한 환경을 재현할 수 있어요. 그렇다면 Docker Compose로 홈서버 스택을 구성하는 법을 실제로 어떻게 시작하면 될까요?

왜 개별 docker run 대신 Compose인가

docker run 명령으로 컨테이너를 하나씩 실행하는 것도 가능하지만, 옵션이 많아질수록(포트 매핑, 볼륨, 환경변수, 네트워크 설정) 명령어가 길어지고 관리가 어려워져요. Docker Compose는 이 모든 설정을 파일로 선언해두고, docker compose up -d 한 번으로 전체 스택을 실행해요. 무엇보다 이 YAML 파일 자체를 Git으로 버전 관리할 수 있다는 점이 큰 장점이에요.

홈서버에서 흔히 쓰는 디렉터리 구조

서비스별로 폴더를 분리해 각자의 docker-compose.yml.env를 따로 두는 구조가 홈랩 커뮤니티에서 가장 흔히 쓰여요.

homelab/
├── nextcloud/
│   ├── docker-compose.yml
│   └── .env
├── jellyfin/
│   ├── docker-compose.yml
│   └── .env
├── pihole/
│   └── docker-compose.yml
└── proxy/
    └── docker-compose.yml

서비스마다 별도의 폴더와 Compose 파일을 두면, 한 서비스를 업데이트하거나 재시작할 때 다른 서비스에 영향을 주지 않고 독립적으로 관리할 수 있어요. 위 예시의 Pi-hole처럼 이미 별도로 다룬 서비스도 같은 방식으로 이 스택에 그대로 편입시킬 수 있어요.

네트워크 설계: 리버스 프록시와 내부 네트워크

여러 서비스를 외부에 노출하려면 각 서비스마다 다른 포트를 열어두는 것보다, 하나의 리버스 프록시(Nginx Proxy Manager, Traefik 등)가 80/443 포트만 열고 내부적으로 각 서비스의 컨테이너로 트래픽을 전달하는 구조가 안전하고 관리하기 쉬워요. 이를 위해 Docker의 커스텀 네트워크를 활용해, 프록시 컨테이너와 각 서비스 컨테이너가 같은 내부 네트워크에 속하도록 구성해요.

networks:
  proxy_net:
    external: true

각 서비스의 Compose 파일에서 이 외부 네트워크를 참조하도록 설정하면, 프록시가 컨테이너 이름으로 각 서비스에 접근할 수 있어요.

환경변수와 비밀 정보 관리

비밀번호나 API 키를 Compose 파일에 직접 하드코딩하는 대신, .env 파일에 분리해서 관리하는 게 기본이에요. .env 파일은 반드시 .gitignore에 추가해 실수로 저장소에 커밋되지 않도록 해야 해요. 여러 서비스에서 공통으로 쓰는 환경변수는 최상위 .env 파일 하나로 관리하고 각 Compose 파일에서 참조하는 방식으로 중복을 줄일 수 있어요.

업데이트 전략

docker compose pull && docker compose up -d 명령으로 최신 이미지를 받아 컨테이너를 재생성할 수 있어요. 다만 프로덕션처럼 다루어야 하는 서비스(비밀번호 관리자, 파일 저장소 등)는 업데이트 전 반드시 데이터 백업을 먼저 수행하고, 가능하다면 Watchtower 같은 자동 업데이트 도구보다는 변경 사항을 확인한 뒤 수동으로 업데이트하는 게 안전해요.

리소스 제한 설정하기

여러 컨테이너를 하나의 서버에서 동시에 운영하면, 특정 서비스가 리소스를 독점해 다른 서비스에 영향을 줄 수 있어요. Compose 파일의 deploy.resources 설정으로 각 컨테이너의 CPU/메모리 사용량 상한을 지정해두면, 하나의 서비스가 폭주하더라도 전체 시스템이 함께 다운되는 걸 방지할 수 있어요.

deploy:
  resources:
    limits:
      cpus: '1.0'
      memory: 512M

결론

Docker Compose는 셀프호스팅 홈서버를 “그때그때 명령어로 설치한 것들의 모음”에서 “코드로 관리되는 재현 가능한 인프라”로 바꿔주는 핵심 도구예요. 서비스가 늘어날수록 이 구조화의 가치는 기하급수적으로 커지기 때문에, 처음 홈서버를 구축할 때부터 Compose 기반으로 습관을 들이는 걸 강력히 추천해요. 컨테이너가 많아져 명령줄로 관리하기 번거로워졌다면 Portainer 같은 웹 GUI를 앞단에 두는 것도 좋은 다음 단계예요.

자주 묻는 질문

Q1. docker run 대신 꼭 Docker Compose를 써야 하나요?

필수는 아니지만, 옵션이 많아질수록 명령어가 길어져 관리가 어려워지므로 설정을 YAML 파일로 코드화하고 Git으로 버전 관리할 수 있는 Compose가 실질적으로 훨씬 편해요.

Q2. 서비스마다 폴더를 따로 두는 이유가 뭔가요?

한 서비스를 업데이트하거나 재시작할 때 다른 서비스에 영향을 주지 않고 독립적으로 관리하기 위해서예요.

Q3. 비밀번호나 API 키는 Compose 파일에 바로 적어도 되나요?

안 돼요. `.env` 파일로 분리하고 `.gitignore`에 추가해 저장소에 실수로 커밋되지 않도록 해야 해요.

Q4. Watchtower로 자동 업데이트를 걸어두는 게 안전한가요?

비밀번호 관리자나 파일 저장소처럼 데이터가 중요한 서비스는 자동 업데이트보다 변경 사항을 확인한 뒤 수동으로 업데이트하고, 업데이트 전 반드시 데이터를 백업하는 게 안전해요.

Q5. 컨테이너 하나가 리소스를 독점하면 어떻게 막나요?

Compose 파일의 `deploy.resources`로 각 컨테이너의 CPU/메모리 사용량 상한을 지정해두면, 특정 서비스가 폭주해도 전체 시스템이 함께 다운되는 것을 막을 수 있어요.

k
kuro editor 자료 조사하고 분석하고 글을 읽기 쉽게 작성합니다
프로필

댓글

첫 번째 댓글을 남겨보세요!