📊 시스템 구성 개요
이 대시보드는 2대의 Synology NAS를 활용하여 웹 서버, 자동화 서버, 개인 노트 동기화 시스템을 구축하는 전체 과정을 안내합니다. 아래 다이어그램은 최종적으로 구성될 네트워크의 흐름을 보여주며, 각 구성 요소의 역할과 상호작용을 한눈에 파악할 수 있도록 돕습니다.
네트워크 토폴로지
NAS1 (192.168.45.10)
Web/N8N/CouchDB
NAS2 (192.168.45.11)
Photos
클라이언트
Mac Studio, iPad 등
작업 분포도
전체 설정 과정은 크게 네트워크, 보안, 서비스, 클라이언트 설정으로 나뉩니다. 아래 차트는 각 영역이 전체 작업에서 차지하는 비중을 보여줍니다. 보안 및 서비스 설정이 가장 핵심적인 부분임을 알 수 있습니다.
🖥️ 서버 설정
1.1. NAS 고정 IP 할당
SKT 공유기(`192.168.45.1`)의 DHCP 예약 기능을 통해 각 NAS에 고정 IP를 할당합니다.
- NAS1 IP: 192.168.45.10
- NAS2 IP: 192.168.45.11
1.2. DDNS 설정
각 NAS의 DSM `제어판 > 외부 액세스 > DDNS`에서 아래 주소들을 등록합니다.
- NAS1 DDNS: suyaleo1.synology.me (서브도메인 관리용)
- NAS2 DDNS: suyaleo2.synology.me
2.1. Let's Encrypt 통합 인증서 발급 (NAS1에서)
NAS1의 `제어판 > 보안 > 인증서`에서 새 인증서를 발급받습니다. 하나의 인증서로 모든 서비스 도메인을 관리하여 편의성을 높입니다.
- 도메인 이름: `suyaleo1.synology.me`
- 주체 대체 이름(SAN): `suyaleo1.synology.me`, `n8n.suyaleo1.synology.me`, `www.suyaleo1.synology.me`, `couchdb.suyaleo1.synology.me`, `suyaleo2.synology.me`, `photo.suyaleo2.synology.me`
발급된 인증서는 NAS1의 기본 인증서로 설정하고, NAS2로 내보내기/가져오기하여 NAS2의 기본 인증서로도 설정합니다.
2.2. 공유기 포트 포워딩 (NAT)
SKT 공유기(`192.168.45.1`)에 아래 규칙을 설정합니다. **SMB(445) 등 위험한 포트는 외부 노출을 금지합니다.**
| 외부 포트 | 내부 IP | 내부 포트 | 설명 |
|---|---|---|---|
| 80 (TCP) | 192.168.45.10 | 80 | Let's Encrypt 인증용 |
| 443 (TCP) | 192.168.45.10 | 443 | NAS1 웹/리버스 프록시 |
| 50002 (TCP) | 192.168.45.10 | 5001 | NAS1 DSM |
| 50052 (TCP) | 192.168.45.10 | 5006 | NAS1 WebDAV |
| 50004 (TCP) | 192.168.45.11 | 5001 | NAS2 DSM |
| 4431 (TCP) | 192.168.45.11 | 443 | NAS2 Photos |
| 50054 (TCP) | 192.168.45.11 | 5006 | NAS2 WebDAV |
2.3. NAS 방화벽 설정
각 NAS의 `제어판 > 보안 > 방화벽`에서 위 포트 포워딩 규칙에 해당하는 내부 포트들을 외부에서 접근 가능하도록 허용합니다.
3.1. Web Station (웹사이트)
Blocs로 제작한 정적 웹사이트를 운영합니다. Web Station의 `웹 포털`에서 `이름 기반` 가상 호스트를 생성하고, 문서 루트를 Blocs 파일이 업로드된 폴더(예: `/web/www_mywebsite`)로 지정합니다.
3.2. Docker - N8N (자동화 서버)
NAS1의 `로그인 포털 > 고급 > 리버스 프록시`에서 N8N으로의 요청을 내부 포트로 전달하도록 설정합니다.
- 원본: `HTTPS`, `n8n.suyaleo1.synology.me`, Port `443`
- 대상: `HTTP`, `192.168.45.10`, Port `5678`
3.3. Docker - CouchDB (Obsidian LiveSync용)
`docker-compose.yml`을 사용하여 안정적인 `couchdb:3.2.2` 버전으로 배포합니다. 프로젝트 경로는 `/volume1/docker/obsidian_livesync`로 지정합니다.
version: "3.9"
services:
couchdb:
image: couchdb:3.2.2
container_name: obsidian-livesync
environment:
- COUCHDB_USER=suya******
- COUCHDB_PASSWORD=********
- COUCHDB_NODE_NAME=couchdb@127.0.0.1
volumes:
- /volume1/docker/obsidian_livesync/data:/opt/couchdb/data
- /volume1/docker/obsidian_livesync/config/local.ini:/opt/couchdb/etc/local.ini
ports:
- 5984:5984
restart: unless-stopped
CouchDB 접속은 N8N과 마찬가지로 리버스 프록시를 통해 HTTPS로 제공됩니다.
- 원본: `HTTPS`, `couchdb.suyaleo1.synology.me`, Port `443`
- 대상: `HTTP`, `192.168.45.10`, Port `5984`
4.1. Synology Photos
NAS2의 `패키지 센터`에서 Synology Photos를 설치하고 설정합니다. 외부 접속은 포트 포워딩(`4431 -> 192.168.45.11:443`)을 통해 이루어집니다.
💻 클라이언트 설정: Obsidian LiveSync
메인 디바이스(Mac Studio)에서 먼저 설정을 완료하고 데이터를 서버로 올린 후, 다른 서브 디바이스들은 서버로부터 데이터를 받아오는 방식으로 설정합니다. 모든 기기에서 플러그인 설정값은 동일해야 합니다.
- DB URL: `https://couchdb.suyaleo1.synology.me`
- Database Name: `obsidian_vault`
- DB Username: `*******`
- DB Password: `********`
- End-to-End Encryption (E2EE): **활성화 (필수)**
- DB encryption key: **자신만의 강력한 Passphrase 입력 (모든 기기 동일)**
- Synchronization preset: `live sync`
- Sync hidden files: **활성화 (필수)**
- 메인 디바이스(Mac Studio): 기존 Vault 내용을 새 로컬 Vault로 복사한 후, `Force Full Sync` 또는 노트 수정을 통해 서버로 업로드합니다.
- 서브 디바이스(iPad, 휴대폰 등): 플러그인 설정 완료 후, **`1) This is a new client - sync everything from the remote server`** 옵션을 선택하여 서버로부터 데이터를 다운로드합니다.
- 중요: 서브 디바이스에서 동기화 후, `설정 > 커뮤니티 플러그인`에서 동기화된 플러그인들을 **수동으로 활성화**해야 합니다.
⚙️ 문제 해결 (Troubleshooting)
원인: CouchDB가 내부적으로 자신의 호스트 이름을 제대로 인식하지 못하거나, 이미지 버전 버그.
해결책:
- `docker-compose.yml`의 `environment` 섹션에 `- COUCHDB_NODE_NAME=couchdb@127.0.0.1` 추가.
- `docker-compose.yml`의 `image`를 안정적인 버전(예: `couchdb:3.2.2`)으로 명시.
- `local.ini`의 `[couchdb]` 섹션에 `bind_address = 0.0.0.0` 추가.
원인: 접속하려는 도메인 이름이 Let's Encrypt 인증서의 '주체 대체 이름(SAN)' 목록에 포함되지 않음.
해결책:
- NAS1의 인증서에 모든 서비스 도메인(예: `n8n.suyaleo1.synology.me`, `couchdb...` 등)을 SAN에 추가하고 인증서를 갱신합니다.
- 갱신된 인증서를 NAS2에도 내보내기/가져오기하여 적용합니다.
원인: `401`은 사용자 이름/비밀번호 불일치. CORS 오류는 서버가 요청을 허용하지 않음.
해결책:
- `401` 해결: Obsidian 플러그인에 입력한 DB 사용자 이름/비밀번호가 `docker-compose.yml`과 정확히 일치하는지 재확인.
- CORS 해결: `local.ini`의 `[cors]` 섹션 `origins` 목록에 `https://couchdb.suyaleo1.synology.me`를 추가하고 CouchDB 컨테이너 재시작.
원인: Mac Studio 로컬 `.obsidian` 폴더 권한 문제, 또는 서브 디바이스에서 플러그인 수동 활성화 누락.
해결책:
- Mac Studio의 로컬 Vault 내 `.obsidian` 폴더에 `읽기 및 쓰기` 권한 부여 및 **'하위 항목에 적용'** 실행.
- 서브 디바이스에서 동기화 후, `설정 > 커뮤니티 플러그인`에서 동기화된 플러그인들을 **수동으로 활성화**.