diff --git a/MODULES.md b/MODULES.md index aaa08dd..1b70dc4 100644 --- a/MODULES.md +++ b/MODULES.md @@ -230,6 +230,31 @@ $env:DB_USER $env:DB_NAME ``` +### Docker 빌드 오류 ("image already exists") +```powershell +# WSL2 Ubuntu 환경에서 발생하는 오류 해결: + +# 방법 1: BuildKit 비활성화 (권장) +$env:DOCKER_BUILDKIT=0 +docker compose build + +# 방법 2: 캐시 무시하고 빌드 +docker compose build --no-cache + +# 방법 3: 이전 이미지 삭제 +docker rmi reg.firstgarden.co.kr/fgtools:latest +docker compose build + +# 방법 4: BuildKit 캐시 정리 +docker buildx prune -a + +# 방법 5: 완전 초기화 후 빌드 +docker compose down +docker rmi reg.firstgarden.co.kr/fgtools:latest +docker buildx prune -a +docker compose build +``` + ## 추가 정보 - [전체 프로젝트 구조](README.md) diff --git a/README.md b/README.md index d691cee..9d7b2bb 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,103 @@ docker compose push docker compose build && docker compose push ``` +### 9. 빌드 오류 해결 + +#### 오류: "image already exists" +```bash +# 증상 +# > [weather-api] exporting to image: +# [+] build 0/1 +# target weather-api: failed to solve: image "reg.firstgarden.co.kr/fgtools:latest": already exists + +# 해결 방법 1: BuildKit 비활성화 (권장) +DOCKER_BUILDKIT=0 docker compose build + +# 해결 방법 2: 캐시 무시하고 빌드 +docker compose build --no-cache + +# 해결 방법 3: 이전 이미지 삭제 후 빌드 +docker rmi reg.firstgarden.co.kr/fgtools:latest +docker compose build + +# 해결 방법 4: 완전 초기화 +docker compose down +docker rmi reg.firstgarden.co.kr/fgtools:latest +docker buildx prune -a +docker compose build + +# 해결 방법 5: 빌드 스크립트 사용 (권장) +# Linux/macOS +chmod +x scripts/build.sh +./scripts/build.sh clean # 또는 ./scripts/build.sh force + +# Windows PowerShell +.\scripts\build.ps1 -Clean # 또는 .\scripts\build.ps1 -Force +``` + +#### 빌드 스크립트 사용 + +자동화된 빌드 스크립트를 제공합니다: + +**Linux/macOS:** +```bash +chmod +x scripts/build.sh + +# 기본 빌드 (BuildKit 비활성화) +./scripts/build.sh + +# 캐시 무시하고 빌드 +./scripts/build.sh clean + +# 완전 초기화 후 빌드 +./scripts/build.sh force + +# 빌드 및 사설 레지스트리에 푸시 +./scripts/build.sh push +``` + +**Windows PowerShell:** +```powershell +# 첫 실행 시 실행 정책 설정 +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +# 기본 빌드 +.\scripts\build.ps1 + +# 캐시 무시하고 빌드 +.\scripts\build.ps1 -Clean + +# 완전 초기화 후 빌드 +.\scripts\build.ps1 -Force + +# 빌드 및 푸시 +.\scripts\build.ps1 -Push +``` + +#### WSL2 Ubuntu에서 권장 방법 +```bash +# WSL2 우분투에서 BuildKit 문제가 자주 발생합니다. +# 다음 방법들을 순서대로 시도하세요: + +# 1단계: BuildKit 비활성화로 빌드 +DOCKER_BUILDKIT=0 docker compose build + +# 실패하면: +# 2단계: 캐시 무시하고 빌드 +DOCKER_BUILDKIT=0 docker compose build --no-cache + +# 여전히 실패하면: +# 3단계: 완전 초기화 +docker compose down +docker rmi reg.firstgarden.co.kr/fgtools:latest +docker buildx prune -a +DOCKER_BUILDKIT=0 docker compose build + +# 또는 제공된 빌드 스크립트 사용: +chmod +x scripts/build.sh +./scripts/build.sh force +``` + ## 📖 API 문서 ### Dashboard API (포트 5000) diff --git a/docker-compose.yml b/docker-compose.yml index cbbc8fe..b48a42a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,11 @@ # 실행: docker compose up -d # 중지: docker compose down # 로그: docker compose logs -f +# +# 빌드 오류 시 (image already exists): +# - docker compose build --no-cache +# - docker rmi reg.firstgarden.co.kr/fgtools:latest +# - DOCKER_BUILDKIT=0 docker compose build (WSL2에서 권장) # ################################################################### x-common: &common diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..087ac9b --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,165 @@ +# Scripts 가이드 + +프로젝트의 각종 자동화 스크립트를 제공합니다. + +## 빌드 스크립트 + +### build.sh (Linux/macOS) + +Docker 이미지 빌드를 자동화하는 Bash 스크립트입니다. WSL2 Ubuntu에서 발생하는 "image already exists" 오류를 해결합니다. + +#### 설치 + +```bash +# 실행 권한 부여 +chmod +x scripts/build.sh +``` + +#### 사용법 + +```bash +# 기본 빌드 (BuildKit 비활성화) +./scripts/build.sh + +# 캐시 무시하고 빌드 +./scripts/build.sh clean + +# 완전 초기화 후 빌드 (강력함) +./scripts/build.sh force + +# 빌드 및 사설 레지스트리에 푸시 +./scripts/build.sh push + +# 도움말 +./scripts/build.sh help +``` + +#### 옵션 설명 + +| 옵션 | 설명 | 사용 시점 | +|------|------|----------| +| (기본값) | BuildKit 비활성화로 빌드 | 일반적인 빌드 | +| `clean` | 캐시를 무시하고 빌드 | 의존성 변경 후 | +| `force` | 완전 초기화 후 빌드 | "image already exists" 오류 발생 | +| `push` | 빌드 및 사설 레지스트리 푸시 | 배포 시 | + +### build.ps1 (Windows PowerShell) + +PowerShell로 작성된 Windows용 빌드 스크립트입니다. + +#### 설치 + +```powershell +# 실행 정책 변경 (처음 한 번만) +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +# 또는 현재 세션에서만 실행 허용 +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process +``` + +#### 사용법 + +```powershell +# 기본 빌드 +.\scripts\build.ps1 + +# 캐시 무시하고 빌드 +.\scripts\build.ps1 -Clean + +# 완전 초기화 후 빌드 +.\scripts\build.ps1 -Force + +# 빌드 및 푸시 +.\scripts\build.ps1 -Push + +# 도움말 +.\scripts\build.ps1 -Help +``` + +## 빌드 오류 해결 흐름도 + +``` +docker compose build 실행 + ↓ +"image already exists" 오류 발생? + ↓ YES +./scripts/build.sh clean (또는 build.ps1 -Clean) + ↓ +성공? + ↓ NO +./scripts/build.sh force (또는 build.ps1 -Force) + ↓ +성공? + ↓ NO +docker system prune -a +docker compose build +``` + +## 트러블슈팅 + +### WSL2 Ubuntu 특정 팁 + +WSL2의 Docker 환경에서 BuildKit 캐시 문제가 자주 발생합니다: + +```bash +# 1. BuildKit 비활성화 +export DOCKER_BUILDKIT=0 +./scripts/build.sh + +# 2. 또는 스크립트에서 자동으로 처리됨 +./scripts/build.sh clean + +# 3. 최후의 수단: 시스템 정리 +docker system prune -a --volumes +./scripts/build.sh force +``` + +### Docker Desktop 설정 확인 + +Windows/macOS에서 Docker Desktop을 사용하는 경우: + +1. Docker Desktop 설정 열기 +2. "Resources" → "WSL integration" 확인 +3. "Docker Engine" → "BuildKit" 활성화 확인 +4. 필요시 다시 시작 + +### PowerShell 실행 정책 오류 + +``` +File cannot be loaded because running scripts is disabled on this system. +``` + +해결: +```powershell +# 영구적 변경 +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +# 현재 세션에서만 +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process + +# 또는 -NoProfile 옵션으로 실행 +powershell -NoProfile -ExecutionPolicy Bypass -File "scripts\build.ps1" +``` + +## 향후 추가 스크립트 (계획) + +- `test.sh` - 모든 모듈 테스트 실행 +- `deploy.sh` - 배포 자동화 +- `cleanup.sh` - Docker 리소스 정리 +- `setup.sh` - 개발 환경 초기화 + +## 지원 환경 + +| OS | Shell | 상태 | +|----|-------|------| +| Linux | bash | ✓ 지원 | +| macOS | bash | ✓ 지원 | +| WSL2 Ubuntu | bash | ✓ 지원 (권장) | +| Windows | PowerShell | ✓ 지원 | +| Windows | CMD | ✗ 미지원 | + +## 참고 + +- 모든 스크립트는 프로젝트 루트 디렉토리에서 실행해야 합니다. +- 스크립트는 Docker 및 Docker Compose가 설치되어 있어야 합니다. +- WSL2에서 실행할 때는 WSL2 배포판 내에서 실행하세요. diff --git a/scripts/build.ps1 b/scripts/build.ps1 new file mode 100644 index 0000000..be07e31 --- /dev/null +++ b/scripts/build.ps1 @@ -0,0 +1,162 @@ +# ################################################################### +# build.ps1 - FGTools Docker 이미지 빌드 스크립트 (PowerShell) +# ################################################################### +# 용도: Windows/WSL2에서 docker-compose build 오류 해결 +# +# 사용법: +# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +# .\scripts\build.ps1 # 기본 빌드 +# .\scripts\build.ps1 -Clean # 캐시 무시하고 빌드 +# .\scripts\build.ps1 -Force # 완전 초기화 후 빌드 +# .\scripts\build.ps1 -Push # 빌드 및 푸시 +# ################################################################### + +param( + [switch]$Clean = $false, + [switch]$Force = $false, + [switch]$Push = $false, + [switch]$Help = $false +) + +# 설정 +$REGISTRY = "reg.firstgarden.co.kr" +$IMAGE_NAME = "fgtools:latest" +$FULL_IMAGE = "$REGISTRY/$IMAGE_NAME" + +# 함수: 메시지 출력 +function Write-Log { + param([string]$Message) + Write-Host "[FGTools Build] $Message" -ForegroundColor Green +} + +function Write-Error-Custom { + param([string]$Message) + Write-Host "[FGTools Build ERROR] $Message" -ForegroundColor Red +} + +function Write-Warn { + param([string]$Message) + Write-Host "[FGTools Build WARN] $Message" -ForegroundColor Yellow +} + +# 함수: 기본 빌드 +function Build-Normal { + Write-Log "도커 이미지 빌드 시작 (일반 모드)..." + $env:DOCKER_BUILDKIT = 0 + docker compose build + if ($LASTEXITCODE -eq 0) { + Write-Log "✓ 빌드 완료: $FULL_IMAGE" + } else { + Write-Error-Custom "빌드 실패" + exit 1 + } +} + +# 함수: 캐시 무시 빌드 +function Build-Clean { + Write-Log "도커 이미지 빌드 시작 (캐시 무시)..." + docker compose build --no-cache + if ($LASTEXITCODE -eq 0) { + Write-Log "✓ 빌드 완료: $FULL_IMAGE" + } else { + Write-Error-Custom "빌드 실패" + exit 1 + } +} + +# 함수: 강제 초기화 후 빌드 +function Build-Force { + Write-Log "완전 초기화 모드 시작..." + + Write-Warn "서비스 중지 중..." + docker compose down 2>$null + + Write-Warn "이전 이미지 삭제 중..." + docker rmi $FULL_IMAGE 2>$null + + Write-Warn "BuildKit 캐시 정리 중..." + docker buildx prune -a --force 2>$null + + Write-Log "도커 이미지 빌드 시작..." + $env:DOCKER_BUILDKIT = 0 + docker compose build + + if ($LASTEXITCODE -eq 0) { + Write-Log "✓ 빌드 완료: $FULL_IMAGE" + } else { + Write-Error-Custom "빌드 실패" + exit 1 + } +} + +# 함수: 빌드 및 푸시 +function Build-And-Push { + Write-Log "도커 이미지 빌드 및 푸시 시작..." + + $env:DOCKER_BUILDKIT = 0 + docker compose build + + if ($LASTEXITCODE -ne 0) { + Write-Error-Custom "빌드 실패" + exit 1 + } + + Write-Log "이미지 푸시 중..." + docker compose push + + if ($LASTEXITCODE -eq 0) { + Write-Log "✓ 빌드 및 푸시 완료: $FULL_IMAGE" + } else { + Write-Error-Custom "푸시 실패" + exit 1 + } +} + +# 함수: 사용법 출력 +function Show-Usage { + $usage = @" +FGTools Docker 이미지 빌드 스크립트 + +사용법: + .\scripts\build.ps1 # 기본 빌드 + .\scripts\build.ps1 -Clean # 캐시 무시하고 빌드 + .\scripts\build.ps1 -Force # 완전 초기화 후 빌드 + .\scripts\build.ps1 -Push # 빌드 및 푸시 + .\scripts\build.ps1 -Help # 이 메시지 출력 + +옵션: + -Clean 캐시를 무시하고 빌드 + -Force 완전 초기화 후 빌드 (강력함) + -Push 빌드 및 사설 레지스트리에 푸시 + -Help 도움말 출력 + +트러블슈팅: + WSL2에서 "image already exists" 오류 발생 시: + 1. 먼저 clean 모드 시도: .\scripts\build.ps1 -Clean + 2. 실패 시 force 모드 시도: .\scripts\build.ps1 -Force + 3. 계속 실패하면: docker system prune -a + +참고: + 처음 실행 시 실행 정책 변경 필요: + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +"@ + Write-Host $usage +} + +# 메인 로직 +if ($Help) { + Show-Usage + exit 0 +} + +if ($Force) { + Build-Force +} elseif ($Clean) { + Build-Clean +} elseif ($Push) { + Build-And-Push +} else { + Build-Normal +} + +Write-Log "완료!" diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000..43db8b7 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,137 @@ +#!/bin/bash +# ################################################################### +# build.sh - FGTools Docker 이미지 빌드 스크립트 +# ################################################################### +# 용도: WSL2 Ubuntu에서 docker-compose build 오류 해결 +# +# 사용법: +# chmod +x scripts/build.sh +# ./scripts/build.sh # 기본 빌드 +# ./scripts/build.sh clean # 캐시 무시하고 빌드 +# ./scripts/build.sh force # 완전 초기화 후 빌드 +# ./scripts/build.sh push # 빌드 및 푸시 +# ################################################################### + +set -e + +REGISTRY="reg.firstgarden.co.kr" +IMAGE_NAME="fgtools:latest" +FULL_IMAGE="$REGISTRY/$IMAGE_NAME" + +# 색상 정의 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 함수: 메시지 출력 +log() { + echo -e "${GREEN}[FGTools Build]${NC} $1" +} + +error() { + echo -e "${RED}[FGTools Build ERROR]${NC} $1" +} + +warn() { + echo -e "${YELLOW}[FGTools Build WARN]${NC} $1" +} + +# 함수: 기본 빌드 +build_normal() { + log "도커 이미지 빌드 시작 (일반 모드)..." + export DOCKER_BUILDKIT=0 + docker compose build + log "✓ 빌드 완료: $FULL_IMAGE" +} + +# 함수: 캐시 무시 빌드 +build_clean() { + log "도커 이미지 빌드 시작 (캐시 무시)..." + docker compose build --no-cache + log "✓ 빌드 완료: $FULL_IMAGE" +} + +# 함수: 강제 초기화 후 빌드 +build_force() { + log "완전 초기화 모드 시작..." + + warn "서비스 중지 중..." + docker compose down || true + + warn "이전 이미지 삭제 중..." + docker rmi "$FULL_IMAGE" || true + + warn "BuildKit 캐시 정리 중..." + docker buildx prune -a --force || true + + log "도커 이미지 빌드 시작..." + export DOCKER_BUILDKIT=0 + docker compose build + + log "✓ 빌드 완료: $FULL_IMAGE" +} + +# 함수: 빌드 및 푸시 +build_and_push() { + log "도커 이미지 빌드 및 푸시 시작..." + + export DOCKER_BUILDKIT=0 + docker compose build + + log "이미지 푸시 중..." + docker compose push + + log "✓ 빌드 및 푸시 완료: $FULL_IMAGE" +} + +# 함수: 사용법 출력 +usage() { + cat << EOF +사용법: ./scripts/build.sh [옵션] + +옵션: + (기본값) 일반 빌드 (BuildKit 비활성화) + clean 캐시를 무시하고 빌드 + force 완전 초기화 후 빌드 (강력함) + push 빌드 및 사설 레지스트리에 푸시 + +예시: + ./scripts/build.sh # 기본 빌드 + ./scripts/build.sh clean # 캐시 제거 후 빌드 + ./scripts/build.sh force # 완전 초기화 + ./scripts/build.sh push # 빌드 및 푸시 + +트러블슈팅: + WSL2에서 "image already exists" 오류 발생 시: + 1. 먼저 clean 모드 시도: ./scripts/build.sh clean + 2. 실패 시 force 모드 시도: ./scripts/build.sh force + 3. 계속 실패하면: docker system prune -a +EOF +} + +# 메인 로직 +case "${1:-default}" in + default) + build_normal + ;; + clean) + build_clean + ;; + force) + build_force + ;; + push) + build_and_push + ;; + help|--help|-h) + usage + ;; + *) + error "알 수 없는 옵션: $1" + usage + exit 1 + ;; +esac + +log "완료!"