
가끔 생각나면 적는 시리즈 입니다
버그 잡다가 지쳐서 기분 전환겸 글을 적어 봅니다
이전 시리즈에서 준비 하고 시작 까지의 내용을 적었는데
이번 글에서는 실제 개발 과정에서 어떤 일?이 벌어지는지에 대해 적어보겠습니다

지금 만들고 있는 Dock나비 화면 입니다
처음 공개 했을 때랑 조금 달라진 모습을 볼 수 있습니다
처음에 구상을 할 때는 아이디어 하나만 가지고 시작을 했습니다
사용자들이 각자 도커 컨테이너를 만들 수 있는 서비스를 만들어 보면 어떨까?
어떻게 보면 오라클 클라우드 처럼 서버를 대여해주는 것과 비슷하다고 볼 수 있겠죠
그래서 뼈대를 세워 봅니다
Dock나비 기획서 초안
# Dock나비 (DockNabi) 기획서
> 🦋 **차세대 Docker 컨테이너 관리 플랫폼**
## 0. 브랜드 아이덴티티
### 이름의 의미
| 해석 | 의미 | 브랜드 연결 |
|------|------|------------|
| **Dock + 나비** | 도커 + 나비 | 컨테이너가 나비처럼 가볍게 |
| **Dock Navy** | 도크 해군 | 컨테이너 함대를 지휘 |
| **Dock Navi** | 도커 네비게이션 | Docker 세계를 안내 |
### 핵심 가치
- **가벼움**: 나비처럼 가볼ubcfc한 컨테이너 관리
- **변화**: Compose 파일이 실행 서비스로 변신 (metamorphosis)
- **자유**: 각 사용자에게 날개를 제공
- **함대**: 체계적인 컨테이너 관리
---
## 1. 프로젝트 개요
### 1.1 문제 정의
현재 Docker 관리 도구들(Synology Container Manager, Portainer, Dockge)의 한계:
| 문제 | 설명 |
|------|------|
| **공유 관리 환경** | 모든 관리자가 동일한 공간에서 작업, 다른 사용자의 컨테이너 수정/삭제 가능 |
| **권한 분리 부재** | root 권한 필요, 세분화된 권한 관리 불가 |
| **도구 간 불일치** | Portainer 스택 ↔ Container Manager 프로젝트 간 동기화 안됨 |
| **설정 복잡성** | Compose 파일 작성, 포트 충돌 확인, 폴더 생성 등 수동 작업 필요 |
### 1.2 솔루션 비전
**"개인화된 Docker 환경 + 원클릭 배포 + 커뮤니티 공유"**
```
┌─────────────────────────────────────────────────────────────┐
│ 🦋 Dock나비 (DockNabi) │
├─────────────────────────────────────────────────────────────┤
│ 👤 사용자 A │ 👤 사용자 B │ 👤 사용자 C │
│ ├─ Jellyfin │ ├─ Plex │ ├─ Home Assistant │
│ ├─ Immich │ ├─ Nextcloud │ └─ Frigate │
│ └─ Paperless │ └─ Vaultwarden│ │
├─────────────────────────────────────────────────────────────┤
│ 🛡️ 슈퍼 관리자 제어 영역 │
│ • 사용자 권한 관리 • 리소스 할당 • NPM 요청 승인 │
└─────────────────────────────────────────────────────────────┘
```
---
## 2. 시스템 아키텍처
### 2.1 전체 구조
```mermaid
graph TB
subgraph "Frontend"
UI[Web UI - React/Vue]
end
subgraph "Backend"
API[REST API Server]
Auth[인증/인가 모듈]
Quota[리소스 쿼터 관리]
Share[프리셋 공유 서비스]
end
subgraph "Infrastructure"
Docker[Docker Engine API]
NPM[NPM API]
DB[(Database)]
FS[File System]
end
UI --> API
API --> Auth
API --> Quota
API --> Share
API --> Docker
API --> NPM
API --> DB
API --> FS
```
### 2.2 컴포넌트 설명
| 컴포넌트 | 역할 |
|----------|------|
| **Web UI** | 사용자/관리자 대시보드, 스택 관리, 설정 UI |
| **REST API** | 모든 기능의 백엔드 로직 처리 |
| **인증/인가** | JWT 기반 로그인, 역할 기반 접근 제어(RBAC) |
| **쿼터 관리** | 사용자별 리소스 사용량 추적 및 제한 |
| **공유 서비스** | 프리셋 공유, 템플릿 관리 |
| **Docker API** | 컨테이너 CRUD, 이미지 관리 |
| **NPM API** | 역방향 프록시 자동 등록 (선택적) |
---
## 3. 주요 기능
### 3.1 사용자 관리 시스템
```
┌─────────────────────────────────────────┐
│ 역할 계층 구조 │
├─────────────────────────────────────────┤
│ 🔑 슈퍼 관리자 (Super Admin) │
│ └─ 모든 권한 + 사용자/리소스 관리 │
│ │
│ 👔 관리자 (Admin) │
│ └─ 자신의 컨테이너 관리 + 일부 설정 │
│ │
│ 👤 일반 사용자 (User) │
│ └─ 허용된 범위 내 컨테이너 생성/관리 │
│ │
│ 👁️ 뷰어 (Viewer) │
│ └─ 읽기 전용 (상태 확인만) │
└─────────────────────────────────────────┘
```
**권한 매트릭스:**
| 권한 | 슈퍼관리자 | 관리자 | 사용자 | 뷰어 |
|------|:--------:|:-----:|:-----:|:---:|
| 컨테이너 생성 | ✅ | ✅ | ⚙️ | ❌ |
| 컨테이너 수정 | ✅ | ✅ | ⚙️ | ❌ |
| 컨테이너 삭제 | ✅ | ✅ | ⚙️ | ❌ |
| 로그 조회 | ✅ | ✅ | ✅ | ✅ |
| 리소스 할당 | ✅ | ❌ | ❌ | ❌ |
| 사용자 관리 | ✅ | ❌ | ❌ | ❌ |
| NPM 요청 | ✅ | ✅ | ✅ | ❌ |
| NPM 승인 | ✅ | ❌ | ❌ | ❌ |
> ⚙️ = 슈퍼 관리자가 부여한 권한에 따름
---
### 3.2 컨테이너 관리
#### 스택 생성 플로우
```mermaid
sequenceDiagram
participant U as 사용자
participant App as 앱
participant Docker as Docker Engine
U->>App: Compose 파일 업로드
App->>App: 유효성 검사
App->>App: 포트 충돌 검사 & 자동 수정
App->>App: 볼륨 경로 변환 & 폴더 생성
App->>App: 리소스 제한 주입
App->>Docker: docker-compose up
Docker-->>App: 컨테이너 생성 완료
App-->>U: 성공 알림
```
#### 주요 기능
- **Compose 파일 관리**
- 업로드 / 직접 편집 (코드 에디터)
- 문법 검증 및 오류 표시
- 버전 히스토리 (롤백 가능)
- **자동화 기능**
- 🔧 **포트 자동 조정**: 충돌 감지 시 사용 가능한 포트로 자동 변경
- 📁 **폴더 자동 생성**: 볼륨 마운트 경로 자동 생성
- 🏷️ **라벨 자동 추가**: 사용자 식별, 관리 메타데이터
- ⚡ **리소스 제한 주입**: 사용자 쿼터에 맞게 자동 설정
- **컨테이너 제어**
- 시작 / 중지 / 재시작
- 로그 실시간 스트리밍
- 터미널 접속 (exec)
- 리소스 모니터링 (CPU, 메모리, 네트워크)
---
### 3.3 리소스 관리 (쿼터 시스템)
#### 슈퍼 관리자 설정 화면
```
┌─────────────────────────────────────────────────────────────┐
│ 👤 사용자: alice [편집] │
├─────────────────────────────────────────────────────────────┤
│ │
│ CPU 제한 [====░░░░░░] 4코어 / 8코어 │
│ 메모리 제한 [======░░░░] 8GB / 16GB │
│ 이미지 용량 [===░░░░░░░] 10GB / 30GB │
│ 볼륨 용량 [========░░] 100GB / 200GB │
│ 컨테이너 수 [===░░░░░░░] 5개 / 15개 │
│ │
│ 권한: │
│ ☑️ 컨테이너 생성 ☑️ 컨테이너 수정 ☐ 컨테이너 삭제 │
│ ☑️ 이미지 Pull ☐ 볼륨 외부 마운트 ☑️ NPM 요청 │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 구현 방식
> [!CAUTION]
> **리소스 제한은 사용자가 수정할 수 없습니다.**
> 사용자가 Compose 파일에서 `deploy.resources` 섹션을 임의로 수정하더라도, 시스템이 컨테이너 생성 시 슈퍼 관리자가 설정한 값을 강제로 덮어씁니다.
```yaml
# 시스템이 자동으로 주입하는 설정 (사용자 수정 불가)
deploy:
resources:
limits:
cpus: '2.0' # 슈퍼 관리자가 설정한 제한
memory: 2G
reservations:
cpus: '0.25'
memory: 256M
# 사용자의 Compose 파일에서 아래와 같이 작성해도 무시됨
# deploy:
# resources:
# limits:
# cpus: '8.0' # ← 이 값은 적용되지 않음
```
**보안 메커니즘:**
```
사용자 Compose 파일 → 파싱 → deploy.resources 제거 → 쿼터 값 주입 → Docker 실행
```
---
### 3.4 프리셋 공유 시스템
#### 공유 흐름
```mermaid
graph LR
A[스택 완성] --> B{공유 방식}
B -->|공개| C[커뮤니티 게시판]
B -->|비공개| D[공유 링크 생성]
C --> E[다른 사용자]
D --> E
E --> F[환경 자동 변환]
F --> G[원클릭 설치]
```
#### 환경 변수 자동 변환
공유 시 민감 정보 제거 및 플레이스홀더 치환:
```yaml
# 원본 (사용자 A)
volumes:
- /volume1/docker/alice/jellyfin/config:/config
environment:
- PUID=1026
- PGID=100
ports:
- "8096:8096"
# 공유 템플릿 (플레이스홀더)
volumes:
- ${USER_BASE_PATH}/jellyfin/config:/config
environment:
- PUID=${USER_PUID}
- PGID=${USER_PGID}
ports:
- "${AUTO_PORT}:8096"
# 설치 시 (사용자 B)
volumes:
- /volume1/docker/bob/jellyfin/config:/config
environment:
- PUID=1027
- PGID=100
ports:
- "8097:8096" # 8096 충돌로 자동 변경
```
#### GUI 환경 변수 에디터
```
┌─────────────────────────────────────────────────────────────┐
│ 📝 환경 변수 편집 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 변수명 값 필수 │
│ ───────────────────────────────────────────────────────── │
│ PUID [1026 ] ✅ │
│ PGID [100 ] ✅ │
│ TZ [Asia/Seoul ] ⬜ │
│ JELLYFIN_PublishedServerUrl │
│ [http://192.168.1.10:8096] ⬜ │
│ │
│ [+ 변수 추가] │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
### 3.5 NPM (역방향 프록시) 연동
#### 요청-승인 워크플로우
```mermaid
sequenceDiagram
participant U as 사용자
participant App as 앱
participant Admin as 슈퍼관리자
participant NPM as NPM
U->>App: 프록시 요청 (jellyfin.mydomain.com)
App->>App: 요청 저장 (대기중)
App-->>Admin: 알림 (새 NPM 요청)
Admin->>App: 요청 검토 & 승인
App->>NPM: 프록시 호스트 생성 API
NPM-->>App: 생성 완료
App-->>U: 프록시 설정 완료 알림
```
#### 사용자 요청 화면
```
┌─────────────────────────────────────────────────────────────┐
│ 🌐 역방향 프록시 요청 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 대상 컨테이너: [Jellyfin ▼] │
│ 내부 포트: 8096 (자동 감지) │
│ │
│ 요청 도메인: [jellyfin ].mydomain.com │
│ │
│ SSL 인증서: ☑️ Let's Encrypt 자동 발급 │
│ WebSocket 지원: ☑️ 활성화 │
│ │
│ 메모 (관리자에게): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 가족용 미디어 서버입니다. │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [취소] [요청 제출] │
└─────────────────────────────────────────────────────────────┘
```
---
### 3.6 이미지 관리
#### 사용자별 이미지 격리 전략
**옵션 A: 태그 네임스페이스 방식** (권장)
```
# 원본 이미지
lscr.io/linuxserver/jellyfin:latest
# 사용자별 태그
local/jellyfin:latest-alice
local/jellyfin:latest-bob
```
**옵션 B: 공유 이미지 + 버전 고정**
```yaml
# latest 대신 명시적 버전 권장
image: lscr.io/linuxserver/jellyfin:10.8.13
```
#### 이미지 쿼터 관리
```
┌─────────────────────────────────────────────────────────────┐
│ 📦 이미지 관리 - alice (6.2GB / 10GB) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 이미지 크기 마지막 사용 │
│ ───────────────────────────────────────────────────────── │
│ jellyfin:latest-alice 1.2GB 2시간 전 [🗑️] │
│ immich-server:v1.91 890MB 1일 전 [🗑️] │
│ immich-ml:v1.91 3.1GB 1일 전 [🗑️] │
│ postgres:15 412MB 1일 전 [🗑️] │
│ redis:7 138MB 1일 전 [🗑️] │
│ │
│ ⚠️ 용량이 62% 사용되었습니다. 10GB 초과 시 새 이미지 Pull │
│ 불가합니다. │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
### 3.7 편의 기능
#### 폴더 탐색기
```
┌─────────────────────────────────────────────────────────────┐
│ 📁 파일 탐색기 - /volume1/docker/alice │
├─────────────────────────────────────────────────────────────┤
│ │
│ 📁 jellyfin/ │
│ ├── 📁 config/ │
│ ├── 📁 cache/ │
│ └── 📁 media/ → /volume1/video (심볼릭 링크) │
│ 📁 immich/ │
│ ├── 📁 upload/ │
│ ├── 📁 library/ │
│ └── 📄 .env [편집] │
│ 📁 paperless/ │
│ │
│ [📁 새 폴더] [📤 업로드] │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 통합 뷰 (Container Manager + Portainer 통합)
모든 Docker 컨테이너를 소스에 관계없이 통합 표시:
```
┌─────────────────────────────────────────────────────────────┐
│ 🐳 모든 컨테이너 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 상태 이름 이미지 생성 도구 │
│ ───────────────────────────────────────────────────────── │
│ 🟢 jellyfin linuxserver/jelly.. 📦 이 앱 │
│ 🟢 plex plexinc/pms 📦 이 앱 │
│ 🟢 nginx-pm jc21/npm 🅿️ Portainer │
│ 🟢 mariadb mariadb:10 🐋 ContainerMgr │
│ 🔴 photoprism photoprism/photo.. 🐋 ContainerMgr │
│ │
│ 필터: [모두 ▼] [이 앱만] [상태: 실행중 ▼] │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 4. 기술 스택
### 4.1 백엔드 ✅ 확정
| 구분 | 기술 | 선정 이유 |
|------|------|----------|
| 언어 | **Go** | 성능 우수, 단일 바이너리 배포, 낮은 메모리 사용량 |
| 프레임워크 | Fiber 또는 Gin | 경량, 고성능, 미들웨어 풍부 |
| 인증 | JWT + Refresh Token | 표준적, Stateless |
| SSO | OIDC/SAML (Phase 3+) | 향후 확장 예정 |
| DB | SQLite → PostgreSQL | 초기엔 SQLite로 간단하게, 확장 시 PostgreSQL |
| ORM | GORM | 타입 안전, 마이그레이션 지원, Go 생태계 표준 |
### 4.2 프론트엔드
| 구분 | 기술 | 선정 이유 |
|------|------|----------|
| 프레임워크 | **React** + TypeScript | 생태계, 컴포넌트 재사용 |
| 상태관리 | Zustand 또는 Jotai | 가볍고 직관적 |
| UI 라이브러리 | shadcn/ui + Tailwind | 모던 디자인, 커스터마이징 용이 |
| 코드 에디터 | Monaco Editor | VS Code 수준의 편집 경험 |
| **다국어** | i18next | 영어/한국어 기본, 확장 가능 |
### 4.3 다국어 지원 (i18n)
```
/locales
├── en.json # 영어 (기본)
├── ko.json # 한국어
└── [lang].json # 커뮤니티 번역 추가 가능
```
**지원 방식:**
- 영어/한국어 기본 제공
- JSON 기반 번역 파일로 쉽게 언어 추가 가능
- 사용자별 언어 설정 저장
- 브라우저 언어 자동 감지
### 4.4 인프라
| 구분 | 기술 | 비고 |
|------|------|------|
| 컨테이너화 | Docker + Docker Compose | 앱 자체도 컨테이너로 배포 |
| 리버스 프록시 | NPM API 연동 | 기존 NPM 인스턴스 활용 |
| CI/CD | GitHub Actions | 자동 빌드 및 이미지 배포 |
### 4.5 타겟 플랫폼
| 플랫폼 | 지원 수준 | 비고 |
|--------|----------|------|
| **Synology DSM 7.x** | 🥇 1차 목표 | Container Manager 연동, DSM UI 스타일 |
| Ubuntu/Debian | ✅ 지원 | 표준 Docker 환경 |
| 기타 Linux | ✅ 지원 | Docker 설치된 모든 환경 |
| Windows/macOS | ⚠️ 제한적 | Docker Desktop 환경 (테스트용) |
---
## 5. MVP 범위 정의
### Phase 1: 핵심 기능 (MVP)
1. **인증 시스템**
- 로그인/로그아웃
- 슈퍼관리자 + 일반 사용자 역할
2. **컨테이너 관리**
- 스택 생성 (Compose 파일 업로드)
- 포트 충돌 자동 감지 및 수정
- 볼륨 폴더 자동 생성
- 시작/중지/재시작/삭제
- 로그 조회
3. **리소스 제한**
- 사용자별 CPU/메모리 제한 설정
- 컨테이너 수 제한
4. **대시보드**
- 내 컨테이너 목록
- 리소스 사용량 표시
### Phase 2: 공유 및 편의 기능
1. **프리셋 공유**
- 스택 공유 링크 생성
- 환경 변수 자동 변환
- 원클릭 설치
2. **GUI 편집기**
- .env 파일 편집기
- Compose 파일 에디터 (구문 강조)
3. **이미지 관리**
- 이미지 목록 및 용량 표시
- 이미지 삭제
### Phase 3: 고급 기능
1. **NPM 연동**
- 프록시 요청 시스템
- 관리자 승인 워크플로우
2. **커뮤니티 게시판**
- 공개 프리셋 검색
- 평점/댓글
3. **폴더 탐색기**
- 파일 브라우징
- 파일 업로드/다운로드
4. **통합 뷰**
- 외부 생성 컨테이너 표시
- Container Manager/Portainer 라벨 인식
---
## 6. 확정 사항
| 항목 | 결정 |
|------|------|
| **프로젝트 이름** | **Dock나비 (DockNabi)** |
| 기술 스택 | Go (백엔드) + React (프론트엔드) |
| 다국어 | 영어/한국어 기본, 확장 가능 |
| SSO | Phase 3+ 에서 추가 예정 (OIDC/SAML) |
| 타겟 플랫폼 | Synology 우선, 범용 Linux 지원 |
| 리소스 제한 | 시스템 강제 주입 (사용자 수정 불가) |
| **UI/UX** | 세련된 모던 디자인 (다크모드, 글래스모피즘) |
## 7. 다음 단계
> [!NOTE]
> 모든 기본 사항이 확정되었습니다. 개발 준비 단계로 진행합니다.
1. [x] 프로젝트 이름 결정 → **Dock나비**
2. [x] UI/UX 방향 결정 → **세련된 모던 디자인**
3. [ ] 개발 환경 세팅
4. [ ] 프로젝트 초기화
5. [ ] Phase 1 MVP 개발 시작
---
## 부록: 경쟁 제품 비교
| 기능 | Portainer | Dockge | Container Manager | **Dock나비** |
|------|:---------:|:------:|:-----------------:|:---------:|
| 멀티 유저 | CE: ❌ / BE: ✅ | ❌ | ❌ | ✅ |
| 사용자별 격리 | ❌ | ❌ | ❌ | ✅ |
| 리소스 쿼터 | ❌ | ❌ | ❌ | ✅ |
| Compose 지원 | ✅ | ✅ | ✅ | ✅ |
| 포트 자동 조정 | ❌ | ❌ | ❌ | ✅ |
| 폴더 자동 생성 | ❌ | ❌ | ❌ | ✅ |
| 프리셋 공유 | ❌ | ❌ | ❌ | ✅ |
| NPM 연동 | ❌ | ❌ | ❌ | ✅ |
| 다국어 지원 | ✅ | ❌ | ✅ | ✅ |
| SSO 지원 | BE: ✅ | ❌ | ❌ | 🔜 |
| Synology 최적화 | ❌ | ❌ | ✅ | ✅ |
기획서를 보시면 아시겠지만 이런저런 기능들을 구상한대로 수정하고 삭제하고 추가하고 해서 기획서를 만들었습니다
저 부분들이 실제로 구현이 가능한가? 하는 문제는 우선 둘째고 생각나는대로 기획을 합니다
여기서 중요한 건 내가 기획한 내용이 다른 서비스와 비교했을 때 특징이 있는가? 경쟁력이 있는가?
비슷한 서비스가 이미 있는 거 아닌가? 라는 부분을 확인 해봐야겠죠
그 후에 이제 세부적인 구현 가능성을 체크해보고 진행을 하면 됩니다만
저는 처음부터 시놀로지에서 실행이 우선이었는데 이 부분이 문제가 되더라고요
사실 기획서 계획만 깔끔하고 탄탄하게 만들면 개발은 순조로운 편이긴한데
시스템 한계로 지체되는 부분이 많이 생길 수 밖에 없습니다
기획 부분의 사용자별 시스템 자원 쿼터 제한 기능이 있는데
이게 시놀로지에서는 CFS가 제대로 지원이 안되는지 CPU 사용량 제한이 잘 안되더라고요
이렇게 저렇게 방법을 찾아보고 있는데 후순위로 빼두고

우선 시놀로지 모드를 따로 만들어서 개발을 진행 중입니다
# Docknabi 작업 현황
> **마지막 업데이트**: 2025-12-22
---
## 🔴 미완료 작업
### A. 스택 편집 제한 기능 (2025-12-22) ✅
- [x] 스택 편집 시 이름 수정 불가 (폴더=이름이므로)
- [x] 컨테이너 있는 스택 편집창 읽기 전용 표시
- [x] 읽기 전용 모드 안내 메시지 추가
### A-2. 유저폴더 경로 통합 (2025-12-22) ✅
- [x] CreateStack 폴더 자동 생성에 `_users/{username}` 경로 적용
- [x] handleGetStack Path 반환에 유저폴더 경로 적용
- [x] handleDeleteStack 폴더 삭제에 유저폴더 경로 적용
### A-3. 사용자 권한 문제 수정 (2025-12-22) ✅
- [x] handleDeleteStack 스택 소유권 검증 추가 (본인 스택만 삭제 가능)
- [x] handleCleanupStack 소유권 검증 추가 (본인 스택만 정리 가능)
- [x] handleListFiles 사용자 폴더 자동 생성 추가
- [x] Files.tsx 경로 체계 통일 (`/_users/{username}` 형식 사용)
### A-4. 폴더 경로 변경 후 문제 수정 (2025-12-22) ✅
- [x] 스택 중지 시 컨테이너 삭제 문제 (down → stop 변경)
- [x] 스택 세부정보 오류 - 근본 원인 수정 (`FindByUserID(uuid.Nil)` → `FindByName(projectName)`)
- [x] 스택 소스 CM 표시 문제 (`docknabi.managed` 라벨 우선 확인)
- [x] 쿼터 우회 문제 (handleUpdateStack에서 스택 소유자 쿼터 적용)
- [x] 스택 편집 버튼 라우트 수정 (`/stacks/name/:name` → `/stacks/edit/:name`)
- [x] 세부정보 Compose 탭에서 `ComposeProcessed` 우선 표시 (쿼터 적용된 값)
### B. 멀티셀렉트 기능 개선
- [ ] 파일탐색기 멀티셀렉트 동작 안함
- [ ] Shift 클릭으로 범위 선택 미지원 (모든 페이지)
### B. 세부정보 표시
- [ ] 네트워크 - 사용중인 컨테이너 표시 안됨
- [ ] 네트워크 - 세부정보 확인 기능 없음
- [ ] 이미지 - 세부정보 표시 안됨
- [ ] 볼륨 - 세부정보 표시 안됨
### C. 파일 탐색기
- [ ] 파일 업로드 기능 미구현
- [ ] 드래그앤드롭 업로드 미지원
### D. 컴포즈 중복 자동 수정 (2025-12-23 추가)
> 프리셋에서 컴포즈를 가져오거나 새 스택 생성 시, 중복 요소 자동 수정 필요
- [x] `container_name` 충돌 자동 수정 (프로젝트명 접미사 추가)
- [x] 편집 모드 업데이트 버그 수정 (stackName 기반 접근 시 DB ID 누락 문제)
- [ ] 네트워크 이름 충돌 검사 및 수정
- [ ] 볼륨 이름 충돌 검사 및 수정
- [ ] 라벨 자동 정리 (기존 라벨 제거 후 새 라벨 주입)
### E. 프록시 요청 관리 (2025-12-23 추가)
> 슈퍼 애드민이 승인된 프록시 요청을 확인할 수 없는 문제
- [ ] 슈퍼 애드민: 모든 승인된 프록시 요청 목록 표시
- [ ] 슈퍼 애드민: 승인된 프록시 요청 수정/삭제 가능
- [ ] 일반 사용자: 본인 프록시 요청만 표시 (현재 상태 유지)
### F. 프리셋 권한 관리 (2025-12-23 추가)
> 일반 사용자도 모든 프리셋을 수정/삭제할 수 있는 문제
- [ ] 프리셋 생성/등록 권한 사용자별 설정 추가 (CanCreatePreset)
- [ ] 슈퍼 애드민: 모든 프리셋 수정/삭제 가능
- [ ] 일반 사용자: 본인이 등록/생성한 프리셋만 수정/삭제 가능
- [ ] 프리셋 생성/편집 시 카테고리 선택 UI 추가
### G. 사용자 권한 시스템 개선 (2025-12-23 추가)
> 현재 권한 설정이 무엇을 수정/삭제/생성할 수 있는지 명확하지 않음
- [ ] 권한 항목 세분화: 생성 권한 → 스택 생성, 프리셋 생성, 컨테이너 생성 등
- [ ] 권한 항목 세분화: 수정 권한 → 스택 수정, 프리셋 수정, 컨테이너 수정 등
- [ ] 권한 항목 세분화: 삭제 권한 → 스택 삭제, 프리셋 삭제, 컨테이너 삭제 등
- [ ] 권한 설정 UI 개선 (체크박스 그룹화, 설명 추가)
- [ ] 권한 적용 범위 명확화 (자신의 리소스 vs 모든 리소스)
### H. 사용자 그룹 관리 (2025-12-23 추가)
> 사용자 그룹별 기본 권한 관리 및 가입 시 기본 그룹 설정 필요
- [ ] 사용자 그룹 CRUD (생성/조회/수정/삭제)
- [ ] 그룹별 기본 권한 템플릿 설정
- [ ] 가입 시 기본 그룹 설정 (설정 페이지에서 관리)
- [ ] 그룹 변경 시 권한 자동 적용 옵션
- [ ] 그룹 관리 UI (관리자 설정 페이지)
---
## ✅ 완료됨
### 네이티브 알림 → 모달 변환 (2025-12-22) ✅
- [x] AlertDialog, PromptDialog 컴포넌트 생성
- [x] 모든 페이지 변환 완료 (Stacks, StackDetail, Volumes, Networks, Containers, Images, ContainerDetail, Files, Presets, admin/Users)
### 멀티셀렉트 (2025-12-22) ✅
- [x] 스택 멀티셀렉트 (카드뷰 체크박스)
- [x] 네트워크 멀티셀렉트 (테이블 체크박스 컬럼)
- [x] 볼륨 멀티셀렉트 (selectMode 토글)
- [x] 일괄 삭제 안전장치 (3개 이상 시 텍스트 확인)
- [x] 전체 선택/해제 버튼
### 모달/알림 (2025-12-22) ✅
- [x] 스택 삭제 시 ConfirmDialog 사용
- [x] 스택 삭제 시 폴더 삭제 옵션 체크박스
### 스택 이름/폴더 충돌 해결 (2025-12-22) ✅
- [x] 스택 이름 중복 검사 (ExistsByNameAndUserID, ExistsByName)
- [x] 유저 폴더 분리 (`_users/{username}/{stackName}` 구조)
### 네비게이션 (2025-12-22) ✅
- [x] 대시보드 볼륨 카드 → 볼륨 탭 이동
### 빌드 에러 수정 (2025-12-22) ✅
- [x] ConfirmDialog import 경로 수정
- [x] ConfirmDialog onCancel → onClose 수정
### 백그라운드 통계 캐싱 시스템 (2025-12-22) ✅
- [x] SystemStats, ContainerStats 모델 생성
- [x] StatsCollector 서비스 구현
- [x] 볼륨 용량 캐싱 (10분 간격)
- [x] 컨테이너 CPU/RAM 수집 (5분 간격)
### 이전 작업들 ✅
- [x] 사용자 이미지 쿼터 시스템
- [x] 알림 시스템
- [x] 권한 기반 UI
- [x] NPM 프록시 통합
- [x] 로그인 유지 기능
그 외에도 직접 테스트나 사용중에 문제가 되는 UX/UI 또는 필요한 기능이나 동작 방식을 변경하거나
새로운 방식으로 설계하는등 상황에 맞게 수정을 계속 해야합니다

한가지 예를 들어보자면 유저 폴더 구조를 /docker/사용자명 으로 처음 설정을 했는데
사용을 해보니까 사용자명과 관리자가 만드는 스택의 이름이 겹치면 문제가 되더라고요
관리자는 docker/스택명 으로 실행이 되기 때문인데요
그래서 사용자 폴더를 docker/_user/사용자명으로 변경을 했죠
결국 모든 경로 관련 코드를 수정해야 했습니다
기존에 동작하던 것들이 안되기 시작했고 다시 처음부터 테스트를 하면서 수정을 해야했죠
개별 사용자의 용량 측정 방식을 새로 설계해야했고
메모리 제한은 전체 메모리 제한을 할 방법이 없기 때문에 컨테이너별 캡 방식으로 수정하고
컨테이너 제한으로 컨트롤 하는 쪽으로 방향을 수정하고
이미지 풀 용량 제한은 디비에 기록하는 방식으로 구현 합니다
처음 기획할 때 제대로 설계 했다면 이런 일은 없었을텐데 시간과 토큰을 낭비했습니다
그래도 이제 다음에는 같은 실수를 덜 하지 않을까 싶습니다
바이브 코딩 뿐만 아니라 모든 코딩은 디버깅의 반복입니다
코드를 수정하고 테스트하고 버그를 잡고 코드를 수정하고 반복…
그러다가 더 나은 방법이나 포기하고 덜어내야 하는 부분이 생기면
많은 부분을 뒤엎기도 해야하고요
이런 지난한 과정 속에서도 중요한 건 처음에 세웠던 목표나 차별점을
최대한 유지하기 위한 방향으로 가야한다는 점인 거 같습니다
이런저런 제한이나 어려움 때문에 덜어내기만 하다보면 결국 별 특색 없고
다른 서비스와 차이가 없는 결과가 나오기 때문이죠
그런 결과가 나온다면 결국 프로젝트 포기에 대해 고민할 수 밖에 없겠죠
저 같은 경우 처음 기획은 그냥 간단한 사용자별 도커 생성 서비스로 시작해서
점점 규모가 커지고 있는데 컨테이너 매니저, 포테이너, 도케이지 같은 서비스가 있는데
굳이 대체할 필요가 있을까?
그냥 기존 서비스에 + 해서 사용할 수 있는 서비스를 만드는 게 낫지않나?
이런 생각이 들 때가 있더라고요
AI가 있지만 그래도 1인 개발이다보니 규모가 커지면 시간이 걸릴 수 밖에 없더라고요
한가지 기능 마무리하면 몇가지 문제나 추가할 기능들이 생각나고 또 마무리하면
또 추가하고 계속 반복인데 어쨌든 계속 진행하다보면 언젠가 마무리는 될겁니다…
마무리가 되고 완성됐을 때의 그 기분 때문에 계속 하게 되는 거 같네요
매번 느끼는 거지만 계획을 얼마나 디테일하게 세우느냐에 따라 과정이 편해지는 거 같습니다
물론 너무 크게 계획을 세워도 문제가 될 수 있다는 딜레마가 있긴 하지만 이건 경험을 쌓아가면서
밸런스를 조절해야 할 거 같습니다
갑자기 글을 적다보니 두서 없이 글을 쓴 거 같네요
이제 다시 버그 잡으러 가봐야겠습니다
바이브 코딩 하시는 분들 힘내시길 바랍니다