본문 바로가기
  • AI 시대에 적응하는 현대인을 위한 지식 공간
  • AI를 위한 데이터를 과학으로 역어본다
AI 코딩

Synology NAS Docker Compose 설치에서 운영까지

by 피크나인 2025. 12. 3.

Synology NAS Docker Compose 완벽 가이드 2025

홈 서버와 개인 클라우드 환경에 대한 관심이 높아지면서 Synology NAS에서 Docker를 활용하는 사용자가 빠르게 증가하고 있습니다. 특히 DSM 7.2 버전부터 Container Manager에서 Docker Compose를 공식 지원하기 시작하면서, 여러 컨테이너를 YAML 파일 하나로 손쉽게 관리할 수 있는 시대가 열렸습니다. 이제 복잡한 터미널 명령어 없이도 n8n 워크플로우 자동화, PostgreSQL 데이터베이스, MQTT 브로커 같은 서비스들을 클릭 몇 번으로 배포하고 운영할 수 있습니다.

 

이 가이드에서는 Docker Compose의 기본 개념부터 설치, 실전 컨테이너 구성 예제, 그리고 운영 중 마주칠 수 있는 문제들의 해결책까지 체계적으로 다룹니다. 개발자가 아닌 일반 사용자도 쉽게 따라할 수 있도록 GUI와 터미널 방식을 모두 설명하며, 각 단계마다 실제 작동하는 코드 예제를 제공합니다. 이 글을 끝까지 읽으시면 여러분만의 강력한 홈 서버 인프라를 구축하고 안정적으로 운영하는 데 필요한 모든 지식을 얻으실 수 있습니다.

SEO 키워드 : Synology Docker Compose, 시놀로지 도커 컴포즈, Container Manager 사용법, NAS 컨테이너 관리, n8n 시놀로지 설치, Docker Compose 설정, DSM 7.2 Docker

 

Synology NAS의 Docker기능을 활용하면 단순한 스토리지가 아니라 강력한 홈 서버 인프라를 구축할 수 있습니다.
 

Synology DSM 7.2부터 Docker서비스는 Container Management에서 Docker Compose를 공식 지원하기 시작하였습니다.
Synology DSM 7.2부터 Docker서비스는 Container Management에서 Docker Compose를 공식 지원하기 시작하였습니다.


1. Docker Compose란 무엇인가

Docker Compose의 정의

Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하기 위한 강력한 오케스트레이션 도구입니다.

YAML 형식의 설정 파일 하나로 애플리케이션에 필요한 모든 서비스, 네트워크, 볼륨을 체계적으로 구성할 수 있습니다. 예를 들어, 웹 애플리케이션을 운영하려면 웹 서버, 데이터베이스, 캐시 서버 등 여러 컨테이너가 필요한데, Docker Compose를 사용하면 이러한 복잡한 구성을 단일 파일로 관리하고 한 번의 명령으로 모두 실행할 수 있습니다.

 

Synology NAS 환경에서는 DSM 7.2 버전부터 Container Manager라는 이름으로 Docker Compose를 공식 지원하기 시작했습니다.

이전에는 SSH를 통해 터미널에서만 Docker Compose를 사용할 수 있었지만, 이제는 웹 기반 GUI에서 "프로젝트(Project)" 기능을 통해 손쉽게 Compose 파일을 생성하고 관리할 수 있게 되었습니다.

왜 Docker Compose를 사용해야 하나

기존의 Docker 명령어 방식은 컨테이너 하나를 실행할 때마다 긴 명령어를 입력해야 하는 번거로움이 있었습니다. 포트 매핑, 볼륨 연결, 환경 변수 등을 모두 명령줄에서 지정해야 하므로 실수하기 쉽고, 나중에 같은 설정으로 다시 실행하기도 어려웠습니다. Docker Compose는 이러한 모든 설정을 docker-compose.yml 파일에 저장하므로, 언제든지 같은 환경을 완벽하게 재현할 수 있고 Git 등을 통한 버전 관리도 가능해집니다.

특히 Synology NAS 환경에서는 Container Manager의 프로젝트 기능을 통해 GUI로 Compose 파일을 편집하고 관리할 수 있어 더욱 편리합니다. 다른 NAS로 마이그레이션하거나 Proxmox 같은 가상화 환경으로 이전할 때도, docker-compose.yml 파일과 볼륨 데이터만 복사하면 동일한 환경을 그대로 구축할 수 있다는 점이 큰 장점입니다.

Docker Compose를 통해 여러 컨테이너를 효율적으로 관리하는 Synology NAS 서버 환경
Docker Compose를 통해 여러 컨테이너를 효율적으로 관리하는 Synology NAS 서버 환경


2. Docker Compose의 특장점과 장단점

Docker Compose의 핵심 장점

선언적 인프라 관리(Infrastructure as Code)

모든 설정이 YAML 파일에 명시되어 있어 누구나 동일한 환경을 구축할 수 있습니다. 이는 개발 환경과 운영 환경의 일관성을 보장하며, 설정을 Git 등의 버전 관리 시스템으로 관리할 수 있어 변경 이력 추적이 용이합니다. 팀 협업 시에도 설정 파일만 공유하면 모든 구성원이 동일한 환경에서 작업할 수 있습니다.

 

간편한 서비스 오케스트레이션

docker compose up 명령 하나로 정의된 모든 서비스를 순서대로 실행하고, docker compose down으로 깔끔하게 정리할 수 있습니다. 서비스 간 의존성도 depends_on 옵션으로 쉽게 관리할 수 있어, 데이터베이스가 먼저 시작된 후에 웹 애플리케이션이 실행되도록 순서를 제어할 수 있습니다.

 

네트워크 자동 구성

Docker Compose는 기본적으로 프로젝트별 전용 네트워크를 자동으로 생성합니다. 같은 Compose 파일에 정의된 컨테이너들은 서비스 이름으로 서로 통신할 수 있어, 복잡한 네트워크 설정 없이도 마이크로서비스 아키텍처를 구현할 수 있습니다. 예를 들어 웹 앱에서 데이터베이스에 접속할 때 IP 주소 대신 db라는 서비스 이름을 사용할 수 있습니다.

 

뛰어난 이식성(Portability)

docker-compose.yml 파일과 관련 볼륨 데이터만 있으면 다른 서버로 쉽게 이전할 수 있습니다. Synology NAS에서 QNAP, Proxmox, 또는 클라우드 서버로 옮기더라도 동일한 환경을 그대로 재현할 수 있어, 하드웨어 업그레이드나 서버 이전 시 큰 도움이 됩니다.

고려해야 할 단점

  • 학습 곡선 : YAML 문법과 Docker 개념에 대한 기본적인 이해가 필요합니다. 들여쓰기 오류나 문법 실수가 발생하면 컨테이너가 제대로 실행되지 않을 수 있으며, 오류 메시지가 직관적이지 않은 경우도 있습니다.
  • 단일 호스트 제한 : Docker Compose는 기본적으로 단일 서버에서만 동작합니다. 여러 서버에 걸친 분산 환경이나 고가용성이 필요하다면 Docker Swarm이나 Kubernetes를 고려해야 합니다.
  • 리소스 관리 복잡성 : NAS의 하드웨어 리소스가 제한적인 경우, 여러 컨테이너를 동시에 실행하면 성능 저하가 발생할 수 있습니다. 각 컨테이너의 메모리와 CPU 사용량을 모니터링하고 적절히 제한하는 것이 중요합니다.
  • 디버깅 어려움 : 문제가 발생했을 때 여러 컨테이너 중 어디서 문제가 생겼는지 파악하기 어려울 수 있습니다. 로그를 체계적으로 관리하고 헬스체크를 설정해두는 것이 좋습니다.

기존 방식과의 비교

비교 항목 Docker 명령어 방식 Docker Compose 방식
설정 관리 명령어마다 직접 입력 YAML 파일로 일괄 관리
재현성 스크립트 별도 작성 필요 파일 공유로 즉시 재현
다중 컨테이너 각각 별도 실행/관리 단일 명령으로 통합 관리
업데이트 수동으로 이미지 교체 docker compose pull 후 up
네트워크 수동 설정 필요 자동 구성
버전 관리 어려움 Git으로 손쉽게 관리

 


3. Docker Compose 설치 및 환경설정

사전 준비사항

Synology NAS에서 Docker Compose를 사용하기 위해서는 먼저 몇 가지 조건을 확인해야 합니다. DSM 버전은 7.2 이상이어야 하며, NAS 모델이 Docker를 지원하는지 확인해야 합니다. 일반적으로 Intel 또는 AMD 프로세서를 탑재한 플러스(+) 시리즈 모델에서 Docker를 사용할 수 있으며, ARM 기반의 일부 모델(J 시리즈 등)도 DSM 7.2부터 제한적으로 지원됩니다.

Docker 지원 여부는 Synology 공식 웹사이트의 패키지 호환성 페이지에서 확인할 수 있습니다. 또한 충분한 RAM(최소 4GB 이상 권장)과 저장 공간이 필요하며, 여러 컨테이너를 운영할 계획이라면 8GB 이상의 RAM을 권장합니다.

Container Manager 설치 (GUI 방식)

Step 1 : 패키지 센터에서 Container Manager 설치

DSM에 로그인한 후 패키지 센터를 열고 "Container Manager"를 검색합니다. DSM 7.2 미만 버전에서는 "Docker"라는 이름으로 표시될 수 있습니다. 설치 버튼을 클릭하여 패키지를 설치하면, 자동으로 Docker 엔진과 Docker Compose가 함께 설치됩니다.

 

Step 2 : 기본 폴더 구조 생성

File Station을 열고 docker라는 이름의 공유 폴더를 생성합니다. 이 폴더 안에 각 컨테이너별로 하위 폴더를 만들어 데이터를 관리하는 것이 좋습니다. 폴더 이름은 반드시 소문자로 작성하여 호환성 문제를 예방합니다.

/volume1/docker/
├── n8n/
│   ├── data/
│   ├── db/
│   └── files/
├── postgresql/
│   └── data/
├── mosquitto/
│   ├── config/
│   ├── data/
│   └── log/
└── nginx/
    ├── conf/
    └── html/

 

Step 3 : 프로젝트 생성  |  Docker Compose가 자동으로 실행되는 효과

Container Manager를 실행하고 좌측 메뉴에서 "프로젝트(Project)"를 선택합니다. "생성" 버튼을 클릭하면 프로젝트 이름과 경로를 지정하는 화면이 나타납니다. 프로젝트 이름을 입력하고, 앞서 생성한 docker 폴더 내의 해당 서비스 폴더를 경로로 지정합니다. 소스 항목에서 "compose.yml 생성"을 선택하면 에디터가 열리고 직접 YAML 코드를 작성할 수 있습니다.

SSH 터미널 방식 설치

GUI 대신 터미널을 선호하거나 더 세밀한 제어가 필요한 경우 SSH를 통해 Docker Compose를 사용할 수 있습니다. 먼저 DSM 제어판에서 터미널 및 SNMP 메뉴로 이동하여 SSH 서비스를 활성화합니다.

# SSH 접속 (Windows의 경우 PuTTY 또는 Windows Terminal 사용)
ssh admin@NAS_IP_ADDRESS

# 관리자 권한 획득
sudo -i

# Docker 및 Docker Compose 버전 확인
docker --version
docker compose version

# 프로젝트 디렉토리로 이동
cd /volume1/docker/myproject

# docker-compose.yml 파일 생성
vi docker-compose.yml

# 컨테이너 실행 (백그라운드)
docker compose up -d

# 컨테이너 상태 확인
docker compose ps

# 로그 확인
docker compose logs -f

로그 관리 및 모니터링 설정

효과적인 운영을 위해서는 로그를 체계적으로 관리해야 합니다. Docker Compose에서는 각 서비스별로 로깅 설정을 추가할 수 있으며, 로그 파일 크기와 개수를 제한하여 디스크 공간을 효율적으로 사용할 수 있습니다.

services:
  myservice:
    image: myimage:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"      # 로그 파일 최대 크기
        max-file: "3"        # 보관할 로그 파일 개수

 

Container Manager의 GUI에서도 각 컨테이너의 로그를 실시간으로 확인할 수 있습니다. 컨테이너 목록에서 원하는 컨테이너를 선택하고 "로그" 탭을 클릭하면 최신 로그를 볼 수 있으며, 문제 발생 시 빠르게 원인을 파악하는 데 도움이 됩니다.


4. Docker Compose 프로젝트와 컨테이너의 관계

핵심 개념 : 프로젝트 = 독립적인 컨테이너 세트 생성

Docker Compose는 "이미 실행된 컨테이너를 참조"하는 것이 아니라, compose.yaml에 정의된 대로 새로운 컨테이너를 생성합니다.

/volume1/docker/
├── n8n/                    # ← 데이터 저장용 볼륨 폴더 (컨테이너 X)
│   ├── data/
│   └── db/
├── postgresql/             # ← 데이터 저장용 볼륨 폴더 (컨테이너 X)
│   └── data/
├── project-n8n/            # ← 프로젝트 폴더 (compose.yaml 위치)
│   └── compose.yaml        # 여기서 n8n + postgres 컨테이너 "생성"
└── project-web/            # ← 또 다른 프로젝트 폴더
    └── compose.yaml        # 여기서 nginx + postgres 컨테이너 "생성"

동작 방식 상세 설명

구분 설명
볼륨 폴더 (n8n/, postgresql/) 컨테이너의 데이터를 영구 저장하는 곳. 컨테이너가 아님
프로젝트 폴더 (project-n8n/) compose.yaml이 위치하는 곳. 여기서 docker compose up 실행
컨테이너 compose.yaml 실행 시 새로 생성되는 실행 단위

여러 프로젝트에서 컨테이너 사용 시 시나리오

시나리오 1 : 각 프로젝트가 자체 PostgreSQL을 정의한 경우

1) project-n8n

# project-n8n/compose.yaml
services:
  postgres:
    image: postgres:17
    container_name: n8n-postgres    # 컨테이너 이름 A
    ports:
      - "5432:5432"                 # 포트 5432 사용
    volumes:
      - /volume1/docker/n8n/db:/var/lib/postgresql/data

 

2) project-web

# project-web/compose.yaml
services:
  postgres:
    image: postgres:17
    container_name: web-postgres    # 컨테이너 이름 B (다른 이름)
    ports:
      - "5432:5432"                 # 포트 충돌 발생!
    volumes:
      - /volume1/docker/web/db:/var/lib/postgresql/data
```

**결과**: 두 번째 프로젝트 실행 시 **포트 충돌 오류** 발생

---

### 시나리오 2: 공유 서비스를 별도 프로젝트로 분리 (권장)
```
/volume1/docker/
├── shared-services/              # 공유 서비스 프로젝트
│   └── compose.yaml              # PostgreSQL, Redis 등 공용 서비스
├── project-n8n/
│   └── compose.yaml              # n8n만 정의, DB는 외부 참조
└── project-web/
    └── compose.yaml              # nginx만 정의, DB는 외부 참조

 

Step 1 : 공유 서비스 프로젝트 정의

# shared-services/compose.yaml
services:
  postgres:
    image: postgres:17
    container_name: shared-postgres
    ports:
      - "5432:5432"
    volumes:
      - /volume1/docker/postgresql/data:/var/lib/postgresql/data
    networks:
      - shared-network

networks:
  shared-network:
    name: shared-network
    driver: bridge

 

Step 2 : n8n 프로젝트에서 외부 네트워크 사용

# project-n8n/compose.yaml
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=shared-postgres  # 공유 컨테이너 이름으로 접근
      - DB_POSTGRESDB_PORT=5432
    networks:
      - shared-network

networks:
  shared-network:
    external: true    # ← 이미 존재하는 외부 네트워크 사용

 

Step 3 : 웹 프로젝트도 동일하게 외부 네트워크 사용

# project-web/compose.yaml
services:
  webapp:
    image: mywebapp:latest
    container_name: webapp
    environment:
      - DATABASE_HOST=shared-postgres
    networks:
      - shared-network

networks:
  shared-network:
    external: true

실행 순서와 의존 관계

# 1. 먼저 공유 서비스 실행
cd /volume1/docker/shared-services
docker compose up -d

# 2. 그 다음 개별 프로젝트 실행
cd /volume1/docker/project-n8n
docker compose up -d

cd /volume1/docker/project-web
docker compose up -d
```

---

## 핵심 정리

| 질문 | 답변 |
|-----|------|
| compose.yaml이 컨테이너를 새로 만드나요? | **예**, 매번 정의된 대로 새 컨테이너를 생성합니다 |
| 이미 실행된 컨테이너를 참조할 수 있나요? | **직접 참조는 불가**, 대신 **external network**로 통신 가능 |
| 같은 이미지를 여러 프로젝트에서 쓰면? | 각각 **별도의 컨테이너**가 생성됨 (포트 충돌 주의) |
| 데이터(볼륨)는 공유 가능한가요? | **예**, 같은 볼륨 경로를 지정하면 데이터 공유 가능 (동시 쓰기 주의) |

---

## 권장 폴더 구조 (수정안)
```
/volume1/docker/
│
├── _shared/                      # 공유 서비스 프로젝트
│   ├── compose.yaml              # postgres, redis, mqtt 등
│   └── data/
│       ├── postgres/
│       └── redis/
│
├── n8n/                          # n8n 프로젝트
│   ├── compose.yaml              # n8n만 정의
│   └── data/
│
├── homepage/                     # 대시보드 프로젝트
│   ├── compose.yaml
│   └── config/
│
└── nginx-proxy/                  # 리버스 프록시 프로젝트
    ├── compose.yaml
    └── conf/

이렇게 구성하면 공유 서비스(DB, 캐시 등)는 한 번만 실행하고, 여러 애플리케이션 프로젝트에서 네트워크를 통해 접근하는 깔끔한 구조가 됩니다.

 

5. Docker container manager, Compose와 Portainer의 역할 및 구성방법

Portainer, Docker Compose, 그리고 Docker Container Manager는 모두 도커 환경에서 컨테이너를 관리하는 데 사용되지만, 각각의 역할과 사용 방식에는 차이가 있습니다.

역할 및 차이점

  • Docker Container Manager : 도커 컨테이너를 관리하는 일반적인 도구나 소프트웨어를 의미합니다. Portainer나 Synology NAS의 내장 Container Manager 같은 웹 UI 도구들이 이 범주에 속합니다.
  • Docker Compose : 여러 개의 컨테이너를 하나의 애플리케이션으로 묶어 정의하고 관리할 수 있게 해주는 명령줄(CLI) 도구입니다. docker-compose.yml이라는 YAML 파일을 사용하여 다중 컨테이너 애플리케이션의 구성(네트워크, 볼륨, 환경 설정 등)을 정의합니다. DSM 7.2이상을 사용하는 경우 프로젝트를 생성하는 것이 Docker Compose를 실행하는 것과 동일한 효과를 얻을 수 있습니다. 프로젝트 이름/경로의 경우 docker-compose가 실행될 컨테이너 명과 경로라고 인식하면 되고, docker-compose.yml 파일은 기존의 파일을 직접 업로드 하실 수도 있고 바로 신규로 작성할 수도 있습니다.
  • Portainer : 웹 기반의 GUI(그래픽 사용자 인터페이스) 관리 플랫폼입니다. 도커 CLI 명령어 대신 웹 대시보드에서 컨테이너, 이미지, 볼륨, 네트워크 등을 시각적으로 쉽게 관리할 수 있도록 도와줍니다. Docker Swarm과 같은 클러스터 관리 기능도 제공합니다. 

구성 방법 (설치 및 사용 예시)

1) Docker Compose 구성 방법

  • 설치 : Docker 엔진 설치 시 함께 설치되는 경우가 많지만, 별도 설치가 필요한 경우 공식 문서를 참조합니다.
  • docker-compose.yml 파일 작성 : 애플리케이션의 루트 디렉토리(프로젝트 루트 디렉토리와 동일)에 docker-compose.yml 파일을 작성합니다. 예를 들어, WordPress와 MySQL을 함께 실행하는 구성은 다음과 같습니다.
## yaml
version: '3.8'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80" # "외부포트:컨테이너 내부 포트"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress_db
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: password
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: wordpress_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

 

  • 실행 : 터미널에서 docker-compose.yml 파일이 있는 디렉토리로 이동하여 다음 명령어로 실행합니다. 이 명령어 하나로 정의된 모든 컨테이너와 네트워크, 볼륨이 생성 및 실행됩니다. 
## bash
docker-compose up -d


2) Portainer 구성 방법

Portainer는 일반적인 컨테이너 설치방법과 차이가 있습니다. Portainer의 설치는 Container Manager UI를 통해 설치할 수 없으며, 스크립트를 활용한 별도의 설치방법으로 설치하여야 정상적으로 동작됩니다. 

  • Docker 환경 준비 : 도커가 설치된 리눅스 호스트 또는 NAS 등이 필요합니다. 또한, Portainer를 설치할 폴더를 생성합니다. 
# Portainer 설치 폴더 생성
# 파일매니저 > docker폴더로 이동 > portainer 빈 폴더 생성
/volumn1/docker/portainer

 

  • Portainer 설치 및 실행 : 다음 docker run 명령어를 사용하여 Portainer 컨테이너를 설치하고 실행합니다. 이 명령어는 9443 포트로 웹 인터페이스를 노출하고, /var/run/docker.sock을 마운트하여 호스트의 도커 엔진을 관리할 수 있게 합니다.
# 1회용 실행용 스크립트 생성
# 제어판 > 작업 스케줄러 > 생성 > 예약된 작업 > 사용자 정의 스크립트 

## 작업 편집
# 1) 일반 
#   - 작업 : install Portainer
#   - 사용자 : root
# 2) 스케줄 
#   - 다음 날짜에 실행 > 반복하지 않음 
# 3) 작업 설정 
#   - 실행 상세 정보를 이메일로 보내기 체크 및 이메일 입력
#   - 실행명령 사용자 정의 스크립트에 아래 스크립트 작성

docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v 
/var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
  • 접속 및 설정 : 웹 브라우저에서 https://[호스트 IP 주소]:9000으로 접속하여 초기 관리자 계정을 설정하고, 로컬 도커 환경에 연결하여 사용합니다. 정상적으로 접속이 안되는 경우 Docker 컨테이너의 'portainer'를 재시작 한 후 접속합니다. 새로운 계정 'admin'을 생성하고 재접속하면, 'portainer'를 관리할 수 있는 페이지를 확인 할 수 있습니다.

이러한 도구들을 함께 사용하면 도커 환경을 훨씬 효율적으로 관리할 수 있습니다. 

Docker Portainer가 정상설치 된 후 접속하는 경우 현재의 컨테이너 현황 및 관리가 가능합니다.
Docker Portainer가 정상설치 된 후 접속하는 경우 현재의 컨테이너 현황 및 관리가 가능합니다



3) Portainer와 Container Manager 이해하기

Synology NAS를 사용하신다면, 기본적으로 설치되어 있는 Container Manager (이전 명칭: Docker 패키지)와 직접 설치한 Portainer를 함께 사용하실 수 있습니다. 두 도구는 중복 설치라기보다는, 서로 다른 접근 방식을 제공하는 별개의 관리 인터페이스로 보시는 것이 정확합니다. 결론부터 말씀드리면, 둘 다 같은 도커 엔진(Docker Engine)이라는 하나의 기반 위에서 작동하기 때문에 중복 설치는 아니며, 사용자의 필요에 따라 선택적 또는 보완적으로 사용할 수 있습니다.

 

Container Manager (Synology 기본 앱)

  • 역할 : Synology DSM(운영체제)과 가장 긴밀하게 통합된 공식 관리 도구입니다. DSM 웹 인터페이스 내에서 직관적으로 컨테이너를 시작/중지하고, 기본 설정(포트, 볼륨)을 관리하기 편리합니다.
  • 장점 : NAS 시스템 리소스 모니터링, 자동 업데이트, 사용자 친화적인 기본 설정 마법사가 잘 되어 있습니다.
  • 단점 : 세부적인 도커 설정이나 고급 기능(스택 관리, 이미지 빌드 등)에서는 기능이 제한적일 수 있습니다.

Portainer (별도 설치 앱)

  • 역할 : 도커 생태계 전반에서 표준적으로 사용되는 전문적인 웹 기반 GUI 도구입니다. Synology의 기본 앱보다 훨씬 다양하고 강력한 기능을 제공합니다.
  • 장점 : 이미지 레지스트리 관리, 상세한 로그 및 이벤트 모니터링, Docker Compose (스택) 관리, 사용자 권한 관리 등 고급 기능이 많습니다.
  • 단점 : DSM 기본 UI에서 벗어나 별도의 웹 페이지로 접속해야 합니다.

Portainer와 Container Manager를 동시에 사용하는 경우의 시너지 효과
두 도구는 하나의 도커 엔진 인스턴스를 공유합니다. 즉, Container Manager로 시작한 컨테이너를 Portainer에서 볼 수 있고, 그 반대도 가능합니다. 평소에는 Container Manager의 깔끔한 UI로 가볍게 관리하다가, 복잡한 설정 변경이나 docker-compose.yml 파일 배포가 필요할 때만 Portainer의 'Stacks' 기능을 활용하는 식으로 시너지를 낼 수 있습니다.

 

Docker Compose는 어느 컨테이너관리자와 연관성이 많을까요?
Docker Compose는 웹 기반 GUI 도구인 Container Manager나 Portainer '모두'와 연관될 수 있습니다.

  • CLI 방식 (가장 전통적인 방법) : Synology SSH로 접속하여 터미널에서 직접 docker-compose up 명령어로 실행합니다. 이 경우 특정 GUI 도구와 직접적인 연관은 없습니다.
  • GUI 방식 (Portainer의 'Stacks' 기능) : 가장 연관성이 높습니다. Portainer는 docker-compose.yml 파일을 직접 복사/붙여넣기 하거나 업로드하여 한 번에 배포하고 관리할 수 있는 'Stacks (스택)'라는 전용 메뉴를 제공합니다. Compose 파일을 시각적으로 관리하기에 최적화되어 있습니다.
  • GUI 방식 (Synology Container Manager) : 최근 Synology의 Container Manager도 '프로젝트'라는 이름으로 docker-compose.yml 파일을 지원하기 시작했습니다. 하지만 Portainer의 Stacks 기능보다는 지원 범위나 UI가 다소 제한적일 수 있습니다.

    Docker Compose는 Portainer의 'Stacks' 메뉴와 함께 사용할 때 가장 강력하고 편리한 시너지 효과를 발휘합니다. Synology 사용자들은 주로 Portainer를 설치하여 Compose 파일을 관리하는 경우가 많습니다.

6. 다양한 컨테이너 설정 예제

n8n 워크플로우 자동화 플랫폼

n8n은 오픈소스 워크플로우 자동화 도구로, Zapier나 Make.com과 유사한 기능을 자체 서버에서 운영할 수 있게 해줍니다. PostgreSQL 데이터베이스와 함께 구성하면 안정적인 운영이 가능하며, 워크플로우 데이터가 영구적으로 보존됩니다.

version: '3.8'

services:
  # PostgreSQL 데이터베이스
  n8n-db:
    image: postgres:17
    container_name: n8n-db
    hostname: n8n-db
    restart: unless-stopped
    environment:
      - TZ=Asia/Seoul
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8nuser
      - POSTGRES_PASSWORD=your_secure_password_here
    volumes:
      - /volume1/docker/n8n/db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "n8n", "-U", "n8nuser"]
      timeout: 45s
      interval: 10s
      retries: 10

  # n8n 애플리케이션
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    hostname: n8n
    restart: unless-stopped
    depends_on:
      n8n-db:
        condition: service_healthy
    ports:
      - "5678:5678"
    environment:
      - TZ=Asia/Seoul
      - GENERIC_TIMEZONE=Asia/Seoul
      - N8N_HOST=n8n.yourdomain.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.yourdomain.com
      - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=n8n-db
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8nuser
      - DB_POSTGRESDB_PASSWORD=your_secure_password_here
      - N8N_ENCRYPTION_KEY=your_32_character_encryption_key
    volumes:
      - /volume1/docker/n8n/data:/home/node/.n8n
      - /volume1/docker/n8n/files:/files
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:5678/healthz || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
설정 시 주의사항 :
- N8N_ENCRYPTION_KEY는 최소 32자 이상의 고유한 문자열을 사용해야 합니다. 
- 외부 접속을 위해서는 Synology의 역방향 프록시(Reverse Proxy) 설정이 필요합니다.
- 볼륨 경로는 실제 NAS의 볼륨 번호에 맞게 수정해야 합니다.

 

N8N_ENCRYPTION_KEY 생성 방법

SSH로 Synology NAS에 접속하여 다음 명령어를- 실행하면 안전한 32자리 문자열이 즉시 생성됩니다.

openssl rand -hex 16

이 명령어를 실행하면 a1b2c3d4e5f67890a1b2c3d4e5f67890와 유사한 32자리의 16진수 문자열이 출력됩니다. 이 문자열을 복사해 둡니다.

PostgreSQL 데이터베이스

PostgreSQL은 강력한 오픈소스 관계형 데이터베이스로, 여러 애플리케이션에서 공유하여 사용할 수 있습니다. 독립적인 데이터베이스 서버로 구성하면 다양한 서비스에서 활용할 수 있습니다.

version: '3.8'

services:
  postgresql:
    image: postgres:17
    container_name: postgresql
    hostname: postgresql
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      - TZ=Asia/Seoul
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=your_secure_admin_password
      - POSTGRES_DB=defaultdb
      - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
      - /volume1/docker/postgresql/data:/var/lib/postgresql/data
      - /volume1/docker/postgresql/backups:/backups
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin -d defaultdb"]
      interval: 30s
      timeout: 10s
      retries: 5
    # 리소스 제한 (선택사항)
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 512M

 

백업 스크립트 예시:

#!/bin/bash
# /volume1/docker/postgresql/backup.sh
docker exec postgresql pg_dumpall -U admin > 
/volume1/docker/postgresql/backups/backup_$(date +%Y%m%d_%H%M%S).sql
find /volume1/docker/postgresql/backups -name "*.sql" -mtime +7 -delete

Eclipse Mosquitto MQTT 브로커

Mosquitto는 IoT 환경에서 널리 사용되는 MQTT 메시지 브로커입니다. Home Assistant나 다양한 스마트 홈 기기와 연동하여 사용할 수 있으며, 가볍고 안정적인 메시징 서비스를 제공합니다.

version: '3.8'

services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    hostname: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"    # MQTT 기본 포트
      - "9001:9001"    # WebSocket 포트
    volumes:
      - /volume1/docker/mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
      - /volume1/docker/mosquitto/data:/mosquitto/data
      - /volume1/docker/mosquitto/log:/mosquitto/log
    environment:
      - TZ=Asia/Seoul

 

mosquitto.conf 설정 파일 :

# /volume1/docker/mosquitto/config/mosquitto.conf

# 기본 설정
persistence true
persistence_location /mosquitto/data/

# 로그 설정
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout
log_type all

# 리스너 설정
listener 1883
listener 9001
protocol websockets

# 인증 설정 (보안을 위해 권장)
allow_anonymous false
password_file /mosquitto/config/mosquitto.passwd

 

사용자 비밀번호 설정 :

# 컨테이너 실행 후 비밀번호 파일 생성
docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/mosquitto.passwd username

Nginx 웹 서버

Nginx는 고성능 웹 서버이자 리버스 프록시 서버로, 정적 웹사이트 호스팅이나 다른 서비스의 프록시 역할을 수행할 수 있습니다.

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    hostname: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /volume1/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
      - /volume1/docker/nginx/conf.d:/etc/nginx/conf.d:ro
      - /volume1/docker/nginx/html:/usr/share/nginx/html:ro
      - /volume1/docker/nginx/ssl:/etc/nginx/ssl:ro
      - /volume1/docker/nginx/logs:/var/log/nginx
    environment:
      - TZ=Asia/Seoul
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 10s
      retries: 3

통합 스택 예제 : 웹 애플리케이션 + DB + 캐시

여러 서비스를 함께 구성하는 실전 예제입니다. WordPress와 같은 CMS를 MariaDB, Redis 캐시와 함께 운영하는 구성을 보여줍니다.

version: '3.8'

services:
  # MariaDB 데이터베이스
  mariadb:
    image: mariadb:11
    container_name: wp-mariadb
    restart: unless-stopped
    environment:
      - TZ=Asia/Seoul
      - MYSQL_ROOT_PASSWORD=root_password_here
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wpuser
      - MYSQL_PASSWORD=wp_password_here
    volumes:
      - /volume1/docker/wordpress/db:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 30s
      timeout: 10s
      retries: 5

  # Redis 캐시
  redis:
    image: redis:alpine
    container_name: wp-redis
    restart: unless-stopped
    command: redis-server --appendonly yes
    volumes:
      - /volume1/docker/wordpress/redis:/data

  # WordPress
  wordpress:
    image: wordpress:latest
    container_name: wordpress
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
      redis:
        condition: service_started
    ports:
      - "8080:80"
    environment:
      - TZ=Asia/Seoul
      - WORDPRESS_DB_HOST=mariadb
      - WORDPRESS_DB_USER=wpuser
      - WORDPRESS_DB_PASSWORD=wp_password_here
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - /volume1/docker/wordpress/html:/var/www/html

networks:
  default:
    name: wordpress-network

7. 서비스 관리 및 확장성

컨테이너 업데이트 방법

Docker Compose를 사용하면 컨테이너 업데이트가 매우 간단해집니다. 최신 이미지를 다운로드하고 컨테이너를 재생성하는 과정을 몇 가지 명령어로 처리할 수 있습니다. 데이터는 볼륨에 저장되어 있으므로 업데이트 후에도 설정과 데이터가 그대로 유지됩니다.

 

GUI 방식 (Container Manager)

  1. Container Manager를 열고 해당 프로젝트를 선택합니다.
  2. "이미지" 탭에서 사용 중인 이미지를 선택합니다.
  3. 우클릭 후 "업데이트" 또는 "Pull"을 선택합니다.
  4. 프로젝트 탭으로 돌아가 "중지" 후 "시작"을 클릭합니다.

터미널 방식

# 프로젝트 디렉토리로 이동
cd /volume1/docker/myproject

# 최신 이미지 다운로드
docker compose pull

# 변경된 이미지로 컨테이너 재생성 (다운타임 최소화)
docker compose up -d

# 사용하지 않는 이미지 정리
docker image prune -f

자동 재시작 정책 설정

서비스의 안정성을 위해 적절한 재시작 정책을 설정하는 것이 중요합니다. Docker Compose에서는 restart 옵션을 통해 컨테이너가 중단되었을 때의 동작을 지정할 수 있습니다.

services:
  myservice:
    image: myimage:latest
    restart: unless-stopped  # 권장: 수동 중지 전까지 항상 재시작
    # 다른 옵션들:
    # restart: always       # 항상 재시작 (수동 중지해도 NAS 재부팅 시 시작)
    # restart: on-failure   # 오류로 종료된 경우만 재시작
    # restart: no           # 재시작 안 함 (기본값)

리소스 제한 및 모니터링

NAS의 리소스를 효율적으로 사용하기 위해 각 컨테이너의 CPU와 메모리 사용량을 제한할 수 있습니다. 이는 하나의 컨테이너가 과도한 리소스를 사용하여 다른 서비스에 영향을 주는 것을 방지합니다.

services:
  resource-heavy-app:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: '2.0'        # 최대 2개 CPU 코어 사용
          memory: 4G         # 최대 4GB 메모리 사용
        reservations:
          cpus: '0.5'        # 최소 0.5 CPU 코어 보장
          memory: 512M       # 최소 512MB 메모리 보장

 

모니터링 명령어

# 실시간 리소스 사용량 확인
docker stats

# 특정 컨테이너만 확인
docker stats container_name

# 프로젝트 내 모든 컨테이너 상태 확인
docker compose ps

스케일링과 로드 밸런싱

Docker Compose는 기본적인 수평 확장(스케일링) 기능을 제공합니다. 동일한 서비스의 인스턴스를 여러 개 실행하여 부하를 분산시킬 수 있습니다. 단, 포트 충돌을 피하기 위해 호스트 포트 매핑을 제거하거나 동적 포트를 사용해야 합니다.

services:
  web:
    image: nginx:alpine
    # ports를 생략하거나 컨테이너 포트만 지정
    expose:
      - "80"
    deploy:
      replicas: 3  # 3개의 인스턴스 실행
# 런타임에 스케일 조정
docker compose up -d --scale web=5

백업 및 복원 전략

안정적인 운영을 위해서는 체계적인 백업 전략이 필수입니다. Docker Compose 환경에서는 설정 파일과 볼륨 데이터를 별도로 백업해야 합니다.

 

백업해야 할 항목

  1. docker-compose.yml 파일과 .env 파일
  2. 각 서비스의 볼륨 데이터 (/volume1/docker/ 하위 폴더들)
  3. SSL 인증서 및 설정 파일

자동 백업 스크립트 예시

#!/bin/bash
# /volume1/scripts/docker-backup.sh

BACKUP_DIR="/volume1/backups/docker"
DATE=$(date +%Y%m%d_%H%M%S)

# 백업 디렉토리 생성
mkdir -p $BACKUP_DIR

# 실행 중인 컨테이너 목록 저장
docker ps --format "{{.Names}}" > $BACKUP_DIR/running_containers_$DATE.txt

# Docker 폴더 전체 백업 (압축)
tar -czvf $BACKUP_DIR/docker_backup_$DATE.tar.gz /volume1/docker/

# 30일 이상 된 백업 삭제
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete

echo "백업 완료: $BACKUP_DIR/docker_backup_$DATE.tar.gz"

 

DSM 작업 스케줄러에서 이 스크립트를 매일 또는 매주 실행하도록 설정하면 자동으로 백업이 수행됩니다.


8. 트러블슈팅 가이드

자주 발생하는 오류와 해결 방법

문제 1 : "포트가 이미 사용 중입니다" 오류

Error: Bind for 0.0.0.0:80 failed: port is already allocated

이 오류는 지정한 포트가 다른 서비스에서 이미 사용 중일 때 발생합니다. Synology NAS에서는 Web Station이나 다른 패키지가 80, 443 포트를 사용할 수 있습니다.

 

해결 방법 : 

# 포트 사용 현황 확인
sudo netstat -tlnp | grep :80

# 다른 포트로 변경하여 설정
ports:
  - "8080:80"   # 호스트 8080 포트를 컨테이너 80 포트에 매핑

 

문제 2: "권한 거부(Permission denied)" 오류

볼륨 마운트 시 컨테이너 내부에서 파일 쓰기 권한이 없을 때 발생합니다. 이는 컨테이너 사용자와 호스트 파일 소유자가 다르기 때문입니다.

 

해결 방법 :

# 볼륨 폴더 소유자 확인
ls -la /volume1/docker/myapp/

# PUID, PGID 확인 (SSH에서)
id $(whoami)

# docker-compose.yml에 환경 변수 추가
environment:
  - PUID=1026    # 실제 사용자 ID로 변경
  - PGID=100     # 실제 그룹 ID로 변경

# 또는 폴더 권한 직접 변경
sudo chown -R 1000:1000 /volume1/docker/myapp/

 

문제 3: "환경 변수에 true/false 사용 불가" 오류

ERROR: The Compose file './docker-compose.yml' is invalid because:
services.CONTAINER.environment.VAR contains true which is an invalid type

일부 NAS 환경에서 Boolean 값을 문자열이나 숫자로 변환해야 할 때가 있습니다.

 

해결 방법 :

# 변경 전
environment:
  - ENABLE_FEATURE=true
  - DISABLE_LOGS=false

# 변경 후
environment:
  - ENABLE_FEATURE=1      # true 대신 1
  - DISABLE_LOGS=0        # false 대신 0
  # 또는 따옴표로 감싸기
  - ENABLE_FEATURE="true"

문제 4: 데이터베이스 버전 호환성 문제

자동 업데이트 시 PostgreSQL이나 MariaDB의 메이저 버전이 올라가면 데이터 호환성 문제가 발생할 수 있습니다.

The data directory was initialized by PostgreSQL version 16,
which is not compatible with this version 17

 

해결 방법 :

# 버전 태그 고정으로 예방
services:
  db:
    image: postgres:16      # :latest 대신 특정 버전 지정
    # image: postgres:17    # 업그레이드 시 데이터 마이그레이션 필요

 

마이그레이션이 필요한 경우 :

# 기존 데이터 백업
docker exec postgres pg_dumpall -U admin > backup.sql

# 새 버전으로 컨테이너 교체 후 복원
docker exec -i postgres psql -U admin < backup.sql

네트워크 관련 문제

문제 : 컨테이너 간 통신 불가

같은 Compose 파일 내의 컨테이너끼리 서비스 이름으로 통신이 안 될 때가 있습니다.

 

해결 방법 :

# 명시적 네트워크 정의
services:
  app:
    networks:
      - app-network
  db:
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

 

문제 : DSM 방화벽이 Docker 트래픽 차단

Synology DSM 방화벽 설정이 Docker 컨테이너의 네트워크 트래픽을 차단할 수 있습니다.

 

해결 방법 :

# 커스텀 서브넷 지정
networks:
  custom-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16

# DSM 방화벽에서 172.30.0.0/16 대역 허용 규칙 추가

로그를 통한 디버깅

문제 해결의 첫 단계는 항상 로그 확인입니다. Docker Compose는 여러 가지 방법으로 로그를 확인할 수 있습니다.

# 모든 서비스 로그 확인
docker compose logs

# 특정 서비스 로그만 확인
docker compose logs n8n

# 실시간 로그 스트리밍
docker compose logs -f

# 최근 100줄만 확인
docker compose logs --tail=100

# 타임스탬프와 함께 확인
docker compose logs -t

# 특정 시간 이후 로그만 확인
docker compose logs --since="2024-01-01T00:00:00"

컨테이너 상태 점검 체크리스트

문제가 발생했을 때 순서대로 확인해야 할 항목들입니다.

  1. 컨테이너 상태 확인: docker compose ps - 모든 서비스가 "Up" 상태인지 확인
  2. 로그 확인: docker compose logs [서비스명] - 오류 메시지 확인
  3. 리소스 사용량 확인: docker stats - 메모리/CPU 부족 여부 확인
  4. 네트워크 확인: docker network ls - 네트워크 생성 여부 확인
  5. 볼륨 확인: docker volume ls - 볼륨 마운트 상태 확인
  6. 포트 확인: netstat -tlnp | grep [포트번호] - 포트 충돌 확인
  7. 디스크 공간 확인: df -h - 저장 공간 부족 여부 확인

Docker 정리 명령어

시간이 지나면 사용하지 않는 이미지, 컨테이너, 볼륨이 쌓여 디스크 공간을 차지할 수 있습니다. 정기적인 정리가 필요합니다.

# 중지된 컨테이너 삭제
docker container prune -f

# 사용하지 않는 이미지 삭제
docker image prune -f

# 태그 없는 이미지까지 모두 삭제
docker image prune -a -f

# 사용하지 않는 볼륨 삭제 (주의: 데이터 손실 가능)
docker volume prune -f

# 사용하지 않는 네트워크 삭제
docker network prune -f

# 모든 미사용 리소스 한 번에 정리
docker system prune -a -f

# 현재 디스크 사용량 확인
docker system df

마무리

Synology NAS에서 Docker Compose를 활용하면 복잡한 서비스 구성도 체계적으로 관리할 수 있습니다. DSM 7.2의 Container Manager는 GUI를 통한 편리한 관리 기능을 제공하면서도, SSH 터미널을 통한 세밀한 제어도 가능하여 초보자부터 고급 사용자까지 모두 만족시킬 수 있습니다.

 

이 가이드에서 다룬 n8n, PostgreSQL, MQTT 등의 예제를 기반으로 자신만의 홈 서버 환경을 구축해 보시기 바랍니다. 처음에는 간단한 서비스부터 시작하여 점차 복잡한 구성으로 확장해 나가는 것을 권장합니다. 문제가 발생하면 트러블슈팅 섹션을 참고하여 체계적으로 해결해 나가시면 됩니다.

 

Docker Compose의 가장 큰 장점은 설정의 재현성과 이식성입니다. 한 번 잘 구성해 두면 시스템 장애나 하드웨어 교체 시에도 빠르게 환경을 복구할 수 있습니다. 정기적인 백업과 함께 docker-compose.yml 파일을 Git으로 관리하면 더욱 안정적인 운영이 가능합니다.


참고 자료 및 추가 학습 리소스