Files
web-page-backend/docs/superpowers/plans/2026-05-18-plan-b-base-redis-wsl2.md
gahusb a1a37ead9e docs(plan): Plan-B-Base — NAS Redis + Windows WSL2/Docker/Tailscale/SMB
분산 아키텍처 base 인프라 셋업. 8 task:
- Task 1-2: NAS docker-compose redis 서비스 추가 + 검증
- Task 3-5: Windows AI WSL2 + Docker Engine + Tailscale 설치
- Task 6-7: NAS SMB 자격증명·마운트 (/etc/fstab 자동화)
- Task 8: 통합 검증 (redis PING, /mnt/nas 양방향 R/W, docker hello-world)

SP-2 작업은 박재오 Windows AI 머신 192.168.45.59에서 직접 실행 필요.
Claude는 SP-1만 직접 처리, SP-2는 명령어·검증 가이드 제공.

후속 Plan-B-Insta/Music/Video/Infra의 prerequisite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 22:07:43 +09:00

636 lines
21 KiB
Markdown

# Plan-B-Base — NAS Redis 컨테이너 + Windows WSL2/Docker/Tailscale/SMB Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 분산 아키텍처 base 인프라 셋업 — NAS에 24/7 Redis 컨테이너 신설 + Windows AI 머신에 WSL2 + Docker Engine + Tailscale + NAS SMB 마운트 구성. 후속 Plan-B-Insta/Music/Video/Infra 트랙의 prerequisite.
**Architecture:** SP-1 (NAS Redis) = docker-compose service 추가 + deployer auto-rebuild. SP-2 (Windows) = 박재오 머신 192.168.45.59에서 직접 셋업 (WSL2 Ubuntu 22.04 + Docker Engine + Tailscale + cifs-utils로 NAS SMB 마운트). 두 SP가 모두 끝나야 후속 트랙의 worker가 NAS ↔ Windows 양방향 통신 가능.
**Tech Stack:** Redis 7-alpine, WSL2, Ubuntu 22.04, Docker Engine 24+, Tailscale, cifs-utils (SMB 3.0). PowerShell (관리자) + bash (WSL2 내부).
**Spec:** `web-backend/docs/superpowers/specs/2026-05-18-nas-windows-distributed-architecture-design.md` §4 SP-1·SP-2, §10 SP-1·SP-2 상세
---
## 사전 확인 사항
- **박재오 자격증명 필요**: NAS SMB 마운트용 user/password (Synology DSM 사용자, SMB 권한 보유)
- **Windows AI 머신 직접 접근 필요**: WSL2 설치는 관리자 PowerShell + 재부팅 1회. Claude는 별도 머신이라 명령 직접 실행 불가 — **Task 4~7은 박재오가 콘솔에서 직접 수행**. 명령어와 검증 방법 명시.
- **NAS deployer 사용자**: Gitea webhook으로 docker compose up -d 자동 실행. 새 redis 서비스도 추가 시 자동 startup.
## File Structure
### SP-1 — NAS 측 (Modify)
| 파일 | 변경 | 책임 |
|------|------|------|
| `web-backend/docker-compose.yml` | `redis:` 서비스 블록 추가 | 컨테이너 정의 (image, volume, healthcheck) |
### SP-2 — Windows 측 (Create, 박재오 머신 로컬)
| 파일/위치 | 변경 | 책임 |
|----------|------|------|
| (Windows AI) WSL2 Ubuntu-22.04 | install | Linux 런타임 |
| WSL2 `/etc/apt/keyrings/docker.gpg` | install | Docker Engine apt key |
| WSL2 `/etc/apt/sources.list.d/docker.list` | install | Docker Engine apt source |
| (Windows AI) Tailscale | install + auth | 사설망 100.x.x.x |
| WSL2 `/etc/nas-smb-credentials` (신규) | NAS user/password | SMB 자격증명 (chmod 600) |
| WSL2 `/etc/fstab` (수정) | SMB 마운트 항목 추가 | 부팅 시 자동 마운트 |
| WSL2 `/mnt/nas` | mkdir | 마운트 포인트 |
---
## Task 1: NAS docker-compose.yml에 redis 서비스 추가
**Files:**
- Modify: `C:/Users/jaeoh/Desktop/workspace/web-backend/docker-compose.yml`
- [ ] **Step 1: 현재 docker-compose.yml 끝부분 확인 (deployer 위치)**
Run: `tail -20 C:/Users/jaeoh/Desktop/workspace/web-backend/docker-compose.yml`
Expected: `deployer` 서비스가 마지막. line ~277-293 영역.
- [ ] **Step 2: redis 서비스 블록 추가**
`C:/Users/jaeoh/Desktop/workspace/web-backend/docker-compose.yml` 파일 **끝**에 (deployer 서비스 다음, volumes 블록 있다면 그 전에) 다음 블록 추가. 들여쓰기는 다른 서비스(`lotto:`, `stock:` 등)와 동일하게 services 아래 2칸 들여쓰기:
```yaml
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- ${RUNTIME_PATH}/redis-data:/data
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 60s
timeout: 5s
retries: 3
networks:
- default
```
**주의:**
- 파일 끝에 추가하되, 만약 `networks:` / `volumes:` top-level 블록이 services 다음에 있다면 그 블록들 **앞에** 삽입
- 첫 줄에 빈 줄 1개 두기 (deployer와 분리)
- `${RUNTIME_PATH}` 환경변수는 다른 서비스에서도 사용 중. 자동 적용됨
- [ ] **Step 3: yaml 문법 검증**
Run:
```bash
python -c "import yaml; yaml.safe_load(open('C:/Users/jaeoh/Desktop/workspace/web-backend/docker-compose.yml'))" && echo "yaml OK"
```
Expected: `yaml OK`
만약 실패하면 indent 또는 trailing space 확인.
- [ ] **Step 4: redis 서비스가 services dict에 들어갔는지 확인**
Run:
```bash
python -c "import yaml; d=yaml.safe_load(open('C:/Users/jaeoh/Desktop/workspace/web-backend/docker-compose.yml')); print(sorted(d['services'].keys()))"
```
Expected: 리스트에 `'redis'` 포함. 다른 서비스(`lotto`, `stock`, `music-lab`, `insta-lab`, `realestate-lab`, `agent-office`, `personal`, `packs-lab`, `travel-proxy`, `frontend`, `deployer`)도 모두 그대로.
- [ ] **Step 5: 커밋**
```bash
cd C:/Users/jaeoh/Desktop/workspace/web-backend
git add docker-compose.yml
git commit -m "$(cat <<'EOF'
feat(infra): add redis container as 24/7 queue + cache base (SP-1)
redis:7-alpine, 256MB maxmemory, AOF appendonly ON, allkeys-lru.
docker volume ${RUNTIME_PATH}/redis-data로 영속화.
Plan-B 후속 트랙(insta-render/music-render/video-render Windows
워커)의 BLPOP 큐 + NAS↔Windows pub/sub의 base.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```
- [ ] **Step 6: push (Gitea webhook → NAS deployer 자동 적용)**
```bash
cd C:/Users/jaeoh/Desktop/workspace/web-backend
git push origin main
```
자격증명 prompt 시 입력. 1회 실패 시 1회 재시도 패턴.
Expected: push 성공. NAS deployer가 webhook 수신 → `git pull``docker compose up -d redis` 자동 실행.
---
## Task 2: NAS Redis 컨테이너 헬스 확인
**Files:** 없음 (NAS 검증)
- [ ] **Step 1: deployer 완료까지 대기 (통상 30초~2분)**
Run (Windows 로컬에서):
```bash
for i in 1 2 3 4 5 6 7 8 9 10; do
code=$(curl -s -o /dev/null -w "%{http_code}" https://gahusb.synology.me/api/stock/news -m 5)
echo "[try $i] HTTP $code"
if [ "$code" = "200" ]; then break; fi
sleep 15
done
```
Expected: HTTP 200 응답 — NAS 컨테이너 안정 상태. redis 컨테이너는 별도 endpoint 없으나 deployer가 build 완료했음을 시사.
- [ ] **Step 2: NAS에서 redis 컨테이너 확인 (박재오 SSH)**
NAS bash:
```bash
ssh -p 22 박재오@gahusb.synology.me
cd /volume1/docker/webpage
docker compose ps redis
```
또는 한 번에:
```bash
ssh -p 22 박재오@gahusb.synology.me "cd /volume1/docker/webpage && docker compose ps redis && docker exec redis redis-cli PING"
```
Expected:
- `docker compose ps redis``redis ... healthy` 또는 `Up X seconds (health: starting)` 후 곧 healthy
- `redis-cli PING``PONG`
만약 `docker compose ps`에 redis가 안 보이면:
```bash
cd /volume1/docker/webpage && docker compose up -d redis
```
수동 실행해서 startup 확인.
- [ ] **Step 3: redis-data 볼륨 생성 확인 (Z: drive로)**
Run (Windows):
```powershell
Test-Path "Z:\webpage\redis-data"
```
또는 NAS bash:
```bash
ls -la /volume1/docker/webpage/redis-data/
```
Expected: 디렉토리 존재. 그 안에 `appendonlydir/` 또는 `dump.rdb` 등의 redis 데이터 파일.
- [ ] **Step 4: AOF append-only 작동 확인 (선택, 데이터 영속성 검증)**
```bash
ssh -p 22 박재오@gahusb.synology.me 'docker exec redis redis-cli SET test_key "hello"'
ssh -p 22 박재오@gahusb.synology.me 'docker exec redis redis-cli RESTART' # 또는 docker restart
# 잠시 대기
ssh -p 22 박재오@gahusb.synology.me 'docker exec redis redis-cli GET test_key'
```
Expected: `"hello"` — 재시작 후에도 값 유지 (AOF 영속화 작동).
테스트 후 정리: `docker exec redis redis-cli DEL test_key`
---
## Task 3: Windows AI에 WSL2 + Ubuntu 22.04 설치
**Files:** 없음 (Windows AI 머신 192.168.45.59에서 박재오 직접 실행)
**전제:** Windows 10 build 19041+ 또는 Windows 11. 박재오 9800X3D 머신 충족.
- [ ] **Step 1: 관리자 PowerShell 실행**
박재오 Windows AI 머신에서 시작 메뉴 → "PowerShell" 우클릭 → "관리자 권한으로 실행".
- [ ] **Step 2: WSL2 + Ubuntu 22.04 설치**
```powershell
wsl --install -d Ubuntu-22.04
```
Expected: 다운로드 progress + "Ubuntu-22.04 has been installed". **재부팅 필요할 수 있음.**
- [ ] **Step 3: 재부팅 (필요 시)**
설치 완료 메시지에 "재시작이 필요합니다"가 보이면 재부팅. 자동 재부팅 안 됨.
- [ ] **Step 4: Ubuntu 초기 설정 (재부팅 후 자동 실행 또는 시작 메뉴에서 "Ubuntu" 클릭)**
새 콘솔이 열리고 다음 입력 요청됨:
- 새 UNIX username: `jaeoh` 또는 박재오 선호 username (이후 모든 sudo에 사용)
- 비밀번호: 박재오가 정하는 값. 잘 기억할 것.
Expected: `jaeoh@<hostname>:~$` 프롬프트 표시 → WSL2 진입 성공.
- [ ] **Step 5: WSL 버전 확인**
WSL2 내부에서 PowerShell로 잠시 돌아와서:
```powershell
wsl -l -v
```
Expected:
```
NAME STATE VERSION
* Ubuntu-22.04 Running 2
```
VERSION=2 확인. 만약 1이면:
```powershell
wsl --set-version Ubuntu-22.04 2
```
- [ ] **Step 6: WSL2 안 진입 (이후 작업)**
```powershell
wsl -d Ubuntu-22.04
```
이후 Task 4~7은 모두 WSL2 안 bash에서 실행.
---
## Task 4: WSL2 안 Docker Engine 설치 (Docker Desktop 사용 X)
**Files:** (WSL2 내부) `/etc/apt/keyrings/docker.gpg`, `/etc/apt/sources.list.d/docker.list`
**위치:** WSL2 Ubuntu-22.04 bash 프롬프트.
- [ ] **Step 1: 패키지 인덱스 + 기본 의존성 설치**
```bash
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
```
Expected: 에러 없이 완료.
- [ ] **Step 2: Docker apt key 등록**
```bash
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
```
Expected: 에러 없이 완료. `/etc/apt/keyrings/docker.gpg` 파일 생성.
- [ ] **Step 3: Docker repository 추가**
```bash
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
```
Expected: `Hit:N https://download.docker.com/linux/ubuntu jammy InRelease` 라인 보임.
- [ ] **Step 4: Docker Engine + Compose 설치**
```bash
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
Expected: 설치 완료. 용량 ~400MB.
- [ ] **Step 5: 현재 사용자를 docker 그룹에 추가**
```bash
sudo usermod -aG docker $USER
```
Expected: 출력 없음 (정상). **새 셸 열어야 적용됨.**
- [ ] **Step 6: Docker 서비스 시작 + 자동 시작 설정**
```bash
sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker | head -5
```
Expected: `Active: active (running)`.
만약 `systemctl: command not found` 또는 systemd 미지원 시:
```bash
sudo service docker start
```
WSL2 systemd 활성화는 `/etc/wsl.conf``[boot]\nsystemd=true` 추가 후 PowerShell에서 `wsl --shutdown` 후 재진입. (Ubuntu-22.04는 보통 기본 활성)
- [ ] **Step 7: docker 명령 동작 확인**
새 셸로 (PowerShell에서 다시 `wsl -d Ubuntu-22.04` 또는 현재 셸 종료 후 재진입):
```bash
docker version
docker run --rm hello-world
```
Expected:
- `docker version`: Client + Server 둘 다 표시 (Server에 Engine version)
- `hello-world`: "Hello from Docker!" 출력
---
## Task 5: WSL2 안 Tailscale 설치 + 가입
**Files:** Tailscale은 systemd service 등록 (별도 path 신경 안 써도 됨)
- [ ] **Step 1: Tailscale 설치**
WSL2 bash:
```bash
curl -fsSL https://tailscale.com/install.sh | sh
```
Expected: 패키지 install 후 "Installation complete!" 출력.
- [ ] **Step 2: Tailscale 가입 (브라우저 OAuth)**
```bash
sudo tailscale up
```
Expected: `To authenticate, visit: https://login.tailscale.com/a/...` URL 표시.
브라우저에서 그 URL 열기 → Google/Microsoft/GitHub 등으로 로그인 → 박재오 Tailscale 네트워크에 가입 (기존 계정 없으면 생성).
- [ ] **Step 3: 가입 완료 확인**
```bash
tailscale status
```
Expected:
- 첫 줄에 Windows AI 머신의 100.x.x.x IP 표시
- (이미 가입된) NAS도 같은 네트워크에 있다면 NAS의 100.x.x.x IP도 표시
- [ ] **Step 4: NAS와 Tailscale ping (양방향 사설망 확인)**
NAS의 Tailscale IP를 `tailscale status` 출력에서 찾아 (예: `100.64.0.10`):
```bash
tailscale ping 100.64.0.10
```
Expected: `pong from <NAS hostname>` (직접 LAN 또는 DERP 중계). 만약 NAS가 Tailscale 미가입이면 별도로 NAS DSM Tailscale 패키지 셋업 필요 — 이는 박재오 결정 사항이라 plan 외.
> **참고:** Tailscale은 spec §3 sense의 사설망 layer 보조. LAN(192.168.45.0/24) 안에서만 작업한다면 Tailscale 없이도 작동. 외부 출장 등에서 NAS↔Windows 통신을 위해 권장.
---
## Task 6: WSL2 안 NAS SMB 자격증명 파일 + 마운트 포인트 준비
**Files:** `/etc/nas-smb-credentials`, `/mnt/nas`
- [ ] **Step 1: cifs-utils 설치 (SMB 마운트 패키지)**
```bash
sudo apt install -y cifs-utils
```
Expected: 설치 완료.
- [ ] **Step 2: SMB 자격증명 파일 생성**
박재오 NAS 계정의 username과 password를 사용. 파일 위치는 system-wide `/etc/`.
```bash
sudo bash -c 'cat > /etc/nas-smb-credentials <<EOF
username=박재오NAS사용자명
password=박재오NAS비밀번호
domain=
EOF'
```
**위 명령 실행 전 `박재오NAS사용자명` / `박재오NAS비밀번호`를 실제 값으로 교체.** Synology DSM Control Panel → User & Group 에서 SMB 접근 권한 있는 계정 사용. 비밀번호에 특수문자 있을 시 escape 필요 (특히 `!`, `$`, `\`).
- [ ] **Step 3: 자격증명 파일 권한 보호**
```bash
sudo chmod 600 /etc/nas-smb-credentials
sudo chown root:root /etc/nas-smb-credentials
```
Expected: 출력 없음.
```bash
ls -la /etc/nas-smb-credentials
```
Expected: `-rw------- 1 root root ... /etc/nas-smb-credentials`
- [ ] **Step 4: 마운트 포인트 생성**
```bash
sudo mkdir -p /mnt/nas
```
---
## Task 7: NAS SMB 마운트 (수동 마운트 + fstab 자동화)
**Files:** `/etc/fstab` (수정)
- [ ] **Step 1: 수동 마운트 시도 (자격증명·경로 검증)**
```bash
sudo mount -t cifs //gahusb.synology.me/docker /mnt/nas \
-o credentials=/etc/nas-smb-credentials,vers=3.0,uid=1000,gid=1000,_netdev
```
Expected: 출력 없음 (성공). 만약 `mount error(13)` (permission) → 자격증명 오류. `mount error(2)` (no such file) → share name `docker` 확인.
> **share name 변형:** 박재오 NAS는 메모리(`feedback_nas_deploy_paths.md`)에 따르면 SMB 매핑이 `/volume1/docker/`를 share `docker`로 노출. 만약 다른 share name(예: `webpage`)이라면 그것으로 교체.
- [ ] **Step 2: 마운트 결과 확인**
```bash
ls /mnt/nas/
```
Expected: `webpage/` 디렉토리 + 다른 share 내 디렉토리 보임.
```bash
ls /mnt/nas/webpage/data/
```
Expected: `insta/`, `music/` 등 후속 트랙에서 사용할 디렉토리. 없으면 후속 트랙에서 생성됨.
- [ ] **Step 3: 마운트 해제 후 fstab으로 자동화**
```bash
sudo umount /mnt/nas
```
Expected: 출력 없음.
`/etc/fstab` 끝에 다음 라인 추가:
```bash
sudo bash -c 'cat >> /etc/fstab <<EOF
# NAS Synology SMB mount for web-ai-services workers (2026-05-18)
//gahusb.synology.me/docker /mnt/nas cifs credentials=/etc/nas-smb-credentials,vers=3.0,uid=1000,gid=1000,_netdev,nofail 0 0
EOF'
```
`nofail` 옵션은 부팅 시 NAS 미접속이어도 boot 진행 (production 안전).
- [ ] **Step 4: fstab 적용 + 검증**
```bash
sudo mount -a
ls /mnt/nas/webpage/data/ 2>&1 | head -5
mount | grep cifs
```
Expected:
- `mount -a` 출력 없음 (성공)
- `ls /mnt/nas/webpage/data/` 디렉토리 내용 표시
- `mount | grep cifs` 라인에 마운트 정보 보임
- [ ] **Step 5: WSL2 재시작 시 자동 마운트 확인**
PowerShell에서 (관리자 권한 불필요):
```powershell
wsl --shutdown
wsl -d Ubuntu-22.04
```
WSL2 다시 진입 후:
```bash
ls /mnt/nas/webpage/data/
```
Expected: 정상 디렉토리 목록. 자동 마운트 성공.
만약 마운트 안 됨:
- `dmesg | grep cifs` 확인
- `nofail` 때문에 boot은 통과했으나 마운트 실패 가능. 수동 `sudo mount -a` 후 동작 확인 → fstab syntax 재검토
---
## Task 8: 통합 검증 — base 인프라 동작 확인
**Files:** 없음 (검증)
- [ ] **Step 1: NAS Redis 외부 ping (Windows 로컬에서)**
```powershell
# Windows AI 또는 박재오 PC에서
Test-NetConnection -ComputerName 192.168.45.54 -Port 6379
```
Expected: `TcpTestSucceeded : True`
> 외부 6379 노출은 LAN 한정. 가능하면 NAS firewall (DSM Control Panel)에서 6379 LAN-only allowed로 한정 권장. (이번 plan에 포함 안 됨, 별도 사용자 작업)
- [ ] **Step 2: WSL2에서 NAS Redis 접속**
WSL2 bash:
```bash
docker run --rm redis:7-alpine redis-cli -h 192.168.45.54 PING
```
또는 Tailscale 사용 시:
```bash
docker run --rm redis:7-alpine redis-cli -h <NAS_TAILSCALE_IP> PING
```
Expected: `PONG`
- [ ] **Step 3: NAS volume 쓰기 테스트 (Windows→NAS 양방향)**
WSL2 bash:
```bash
echo "Plan-B-Base test $(date)" | sudo tee /mnt/nas/webpage/data/.plan-b-test.txt
cat /mnt/nas/webpage/data/.plan-b-test.txt
sudo rm /mnt/nas/webpage/data/.plan-b-test.txt
```
Expected:
- `tee` 출력에 같은 내용 + 파일 생성됨
- `cat` 으로 확인 성공
- 파일 삭제 성공
`sudo` 필요 시 chmod로 uid 1000 쓰기 권한 확인. 또는 mount option `uid=1000,gid=1000` 적용 후 일반 사용자도 쓰기 가능. 만약 안 되면 NAS DSM에서 SMB user의 write 권한 확인.
- [ ] **Step 4: WSL2 Docker로 hello-world 한 번 더 (재진입 후 상태 확인)**
```bash
docker run --rm hello-world
```
Expected: "Hello from Docker!"
- [ ] **Step 5: 모든 검증 완료 후 보고 — 후속 트랙으로 진입 가능 상태**
다음 plan(Plan-B-Insta 등)이 가정하는 상태:
- ✅ NAS `redis:6379` PING/PONG 성공
- ✅ Windows WSL2 Ubuntu-22.04 작동 + Docker Engine 실행
-`/mnt/nas/webpage/data/` 양방향 read·write 성공
- ✅ Tailscale 가입 (선택, 외부 출장 시 필요)
---
## Self-Review
### Spec 커버리지
| Spec 요구사항 | 구현 Task |
|---------------|-----------|
| §4 SP-1: NAS Redis 컨테이너 | Task 1 (compose 추가) + Task 2 (헬스 검증) |
| §10 SP-1: redis:7-alpine + 256MB + AOF + healthcheck | Task 1 Step 2 |
| §4 SP-2: Windows WSL2 + Docker Engine | Task 3 (WSL2) + Task 4 (Docker) |
| §10 SP-2: Tailscale | Task 5 |
| §10 SP-2: NAS SMB mount `/mnt/nas` | Task 6 (자격증명·포인트) + Task 7 (마운트+fstab) |
| §10 SP-2: 검증 (docker ps, tailscale status, ls /mnt/nas) | Task 8 |
| §6 Redis 키 컨벤션 사용 가능 | Task 2 Step 2 (PING) — 컨벤션 자체는 후속 트랙에서 RPUSH로 시작 |
### Placeholder 스캔
- TBD/TODO 없음 ✓
- 모든 명령어가 그대로 실행 가능한 형태 ✓
- 한 가지 예외: Task 6 Step 2 — `박재오NAS사용자명/박재오NAS비밀번호`는 사용자 자격증명이라 placeholder가 의도된 것. 실행 전 교체 명시 ✓
- Task 5 Step 4 — `<NAS 의 Tailscale IP>``tailscale status` 출력에서 박재오가 보고 입력. 사용자 환경에서만 결정 가능, plan에 명시 ✓
### Type/이름 consistency
- `redis` 서비스명 (Task 1, 2, 8 모두 동일) ✓
- `/mnt/nas` 마운트 포인트 (Task 6, 7, 8 모두 동일) ✓
- `/etc/nas-smb-credentials` 자격증명 파일 (Task 6, 7 동일) ✓
- share name `docker` (Task 7 Step 1, fstab 동일) ✓
- Ubuntu-22.04 (Task 3, 4 동일) ✓
### 위험·주의
| 위험 | 완화 |
|------|------|
| Windows 재부팅 시 WSL2 자동 시작 안 함 | 향후 Plan-B-Infra(SP-9)에서 NSSM으로 자동 시작 |
| WSL2 systemd 미지원 시 docker service 자동 시작 안 함 | Task 4 Step 6의 fallback `sudo service docker start` 또는 `/etc/wsl.conf` 수정 |
| SMB 마운트 자격증명 노출 | `/etc/nas-smb-credentials` chmod 600 + root:root |
| NAS firewall에서 6379 외부 노출 | 권장: LAN(192.168.45.0/24) only allow. 본 plan 외 (DSM 수동) |
| Tailscale 미가입 시 NAS↔Windows 외부 통신 불가 | LAN 내에선 작동. 외부 출장 시 필요할 때만 가입 |
| /mnt/nas 쓰기 권한 부족 | uid=1000 mount option + NAS DSM에서 SMB user의 share write 권한 확인 |
---
## 완료 후 다음 단계
Plan-B-Base 완료 후 spec §14 권장 순서대로:
1. **Plan-B-Insta** — SP-3 (insta-render Windows worker) + SP-4 (NAS insta-lab 분할)
2. **Plan-B-Music** — SP-5 + SP-6
3. **Plan-B-Video** — SP-7 + SP-8
4. **Plan-B-Infra** — SP-9 (NSSM 자동 시작) + SP-10 (task-watcher)
각 후속 plan은 본 plan이 제공한 base 인프라(Redis + WSL2/Docker + /mnt/nas)에 의존.