grafana | logger=migrator t=2025-10-11T03:28:15.873597899Z level=info msg="Unlocking database"
grafana | Error: ✗ migration failed (id = create user table): disk I/O error: permission denied
services:
prometheus:
image: prom/prometheus
container_name: prometheus
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/volume:/prometheus
ports:
- 9090:9090
command:
- '--config.file=/etc/prometheus/prometheus.yml'
restart: always
networks:
- promnet
grafana:
image: grafana/grafana
container_name: grafana
ports:
- 3000:3000
volumes:
- ./grafana/volume:/var/lib/grafana # 변경 전
user: root
restart: always
networks:
- promnet
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
networks:
promnet:
driver: bridge
services:
prometheus:
image: prom/prometheus
container_name: prometheus
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/volume:/prometheus
ports:
- 9090:9090
command:
- '--config.file=/etc/prometheus/prometheus.yml'
restart: always
networks:
- promnet
grafana:
image: grafana/grafana
container_name: grafana
ports:
- 3000:3000
volumes:
- grafana-data:/var/lib/grafana # 변경된 부분
restart: always
networks:
- promnet
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
networks:
promnet:
driver: bridge
volumes: # 추가된 부분
prometheus-data:
grafana-data:
volumes:
- ./grafana/volume:/var/lib/grafana # 호스트 경로 마운트
Windows에서 발생하는 문제:
1. 파일 시스템 차이
- Windows는 NTFS/FAT32 파일 시스템 사용
- Linux 컨테이너는 ext4 같은 Linux 파일 시스템 기대
- SQLite는 파일 잠금(file locking)에 민감한데, Windows 파일 시스템이 Linux 스타일의 파일 잠금을 제대로 지원하지 못함
- 권한 시스템 불일치
- Linux: UID/GID 기반 권한 (예: 472:472)
- Windows: ACL(Access Control List) 기반
- Docker Desktop이 이를 변환하는 과정에서 권한 문제 발생
- I/O 작업 처리 방식
- Windows 파일 시스템을 통한 I/O는 Docker Desktop의 변환 레이어를 거침
- SQLite의 fsync() 같은 저수준 디스크 동기화 작업이 제대로 작동하지 않음
- 결과: "disk I/O error: permission denied"
volumes:
- grafana-data:/var/lib/grafana # Named volume
volumes:
grafana-data: # Docker가 관리하는 볼륨
왜 이게 작동하는가:
1. 순수 Linux 환경
- Named volume은 Docker Desktop 내부의 Linux VM에 저장됨
- Windows 파일 시스템을 거치지 않고 순수 Linux 환경에서 동작
- 위치: \wsl$\docker-desktop-data\data\docker\volumes\
- 파일 시스템 일치
- 이전: Windows NTFS → Docker 변환 레이어 → Linux Container
- 현재: Linux VM 내부 → Linux Container (직접 연결)
- 권한 문제 없음
- Docker가 볼륨을 생성할 때 올바른 권한으로 자동 설정
- Linux 컨테이너가 Linux 파일 시스템에 직접 접근
- SQLite 호환성
- SQLite의 파일 잠금이 제대로 작동
- fsync() 같은 동기화 작업이 정상 실행
- 트랜잭션 안정성 보장
❌ 호스트 경로 마운트 (실패)
┌─────────────────────────────────────────┐
│ Windows Host (NTFS) │
│ ./grafana/volume │
│ ↓ │
│ [Docker Desktop 변환 레이어] │
│ ↓ (권한/파일시스템 변환 문제) │
│ Linux Container │
│ Grafana + SQLite │
│ ↓ │
│ 💥 disk I/O error │
└─────────────────────────────────────────┘
✅ Named Volume (성공)
┌─────────────────────────────────────────┐
│ Docker Desktop Linux VM │
│ /var/lib/docker/volumes/grafana-data │
│ ↓ (직접 연결, 변환 없음) │
│ Linux Container │
│ Grafana + SQLite │
│ ↓ │
│ ✓ 정상 동작 │
└─────────────────────────────────────────┘
Windows에서 Docker를 사용할 때는 데이터베이스나 I/O가 많은 애플리케이션의 경우 반드시 Named Volume을 사용해야 한다. 호스트 경로 마운트는 설정 파일처럼 읽기가 주된 파일에만 사용하는 것이 좋다.
현재 설정에서도 Prometheus의 ./prometheus/config는 호스트 경로를 사용하는데, 이건 설정 파일(읽기 전용)이라 문제가 없다!