From 63bf26916c84453fcd69e5d09c72f3dbe59e0f03 Mon Sep 17 00:00:00 2001 From: "DESKTOP-TKLFCPR\\ython" Date: Sat, 30 May 2026 08:32:17 +0900 Subject: [PATCH] =?UTF-8?q?feat(zioinfo-web):=20Maven=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=20=EA=B0=90=EC=A7=80/=EC=84=A4=EC=B9=98=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=ED=8A=B8=EC=97=85=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [start.sh (Linux/Mac)] - mvnw(Wrapper) 우선 사용 → 시스템 Maven → 자동 설치 순서 - Maven 없으면: apt/dnf/yum 패키지 관리자 → 수동 tar.gz 설치 - 모드: dev (핫리로드) | prod (빌드+실행) | build (빌드만) | spring-only [start.ps1 (Windows)] - mvnw.cmd → 시스템 mvn → Chocolatey → 수동 zip 설치 - Start-Job으로 Spring Boot 백그라운드 실행 + npm run dev 병렬 [.mvn/wrapper/maven-wrapper.properties] - Maven 3.9.6 Wrapper 설정 (첫 실행 시 자동 다운로드) [setup_ubuntu.sh] - INSTALL_MAVEN=true/false 옵션 추가 (기본 true) - 이미 설치된 경우 건너뜀 사용법: bash workspace/zioinfo-web/start.sh dev # 개발 bash workspace/zioinfo-web/start.sh prod # 운영 Co-Authored-By: Claude Sonnet 4.6 --- setup/setup_ubuntu.sh | 17 +- .../.mvn/wrapper/maven-wrapper.properties | 2 + workspace/zioinfo-web/start.ps1 | 177 ++++++++++++++++ workspace/zioinfo-web/start.sh | 194 ++++++++++++++++++ 4 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 workspace/zioinfo-web/backend/.mvn/wrapper/maven-wrapper.properties create mode 100644 workspace/zioinfo-web/start.ps1 create mode 100644 workspace/zioinfo-web/start.sh diff --git a/setup/setup_ubuntu.sh b/setup/setup_ubuntu.sh index 0d89515e..2e70aac6 100644 --- a/setup/setup_ubuntu.sh +++ b/setup/setup_ubuntu.sh @@ -327,7 +327,22 @@ ok "Nginx 설정 완료" # ── 9. 방화벽 ──────────────────────────────────────────── echo "" -echo "[9/14] Scouter APM 서버 설치..." +echo "[9/14] Maven 설치 (Java 웹 빌드용)..." +# INSTALL_MAVEN=false 로 건너뛸 수 있음 (mvnw Wrapper 사용 시 불필요) +INSTALL_MAVEN="${INSTALL_MAVEN:-true}" +if [[ "$INSTALL_MAVEN" == "true" ]]; then + if command -v mvn &>/dev/null; then + info "Maven 이미 설치됨: $(mvn --version 2>/dev/null | head -1)" + else + apt-get install -y -qq maven 2>/dev/null \ + && ok "Maven 설치 완료 (apt)" \ + || warn "apt Maven 설치 실패 — start.sh 실행 시 자동 처리됨" + fi +else + info "Maven 설치 건너뜀 (INSTALL_MAVEN=false) — mvnw Wrapper 사용" +fi + +echo "[10/14] Scouter APM 서버 설치..." INSTALL_SCOUTER="${INSTALL_SCOUTER:-true}" if [[ "$INSTALL_SCOUTER" == "true" ]]; then SCOUTER_VER="${SCOUTER_VER:-2.20.0}" diff --git a/workspace/zioinfo-web/backend/.mvn/wrapper/maven-wrapper.properties b/workspace/zioinfo-web/backend/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..e70e7bc8 --- /dev/null +++ b/workspace/zioinfo-web/backend/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/workspace/zioinfo-web/start.ps1 b/workspace/zioinfo-web/start.ps1 new file mode 100644 index 00000000..e05e09b0 --- /dev/null +++ b/workspace/zioinfo-web/start.ps1 @@ -0,0 +1,177 @@ +# ============================================================= +# (주)지오정보기술 홈페이지 스타트업 스크립트 — Windows +# ============================================================= +# 사용법: .\start.ps1 [dev|prod|build] +# ============================================================= + +param([string]$Mode = "dev") + +$ErrorActionPreference = "Stop" +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$BackendDir = "$ScriptDir\backend" +$FrontendDir = "$ScriptDir\frontend" + +function Write-OK { param($msg) Write-Host "[OK] $msg" -ForegroundColor Green } +function Write-Warn { param($msg) Write-Host "[WARN] $msg" -ForegroundColor Yellow } +function Write-Fail { param($msg) Write-Host "[FAIL] $msg" -ForegroundColor Red; exit 1 } +function Write-Info { param($msg) Write-Host " $msg" } + +Write-Host "==================================================" +Write-Host " (주)지오정보기술 홈페이지 시작 — Windows" +Write-Host " 모드: $Mode" +Write-Host "==================================================" + +# ── 1. Java 확인 ────────────────────────────────────────────── +if (-not (Get-Command java -ErrorAction SilentlyContinue)) { + Write-Fail "Java가 설치되지 않았습니다. setup_windows.ps1을 먼저 실행하세요." +} +$javaVer = & java -version 2>&1 | Select-Object -First 1 +Write-OK "Java 감지: $javaVer" + +# ── 2. Maven 감지 및 설치 ──────────────────────────────────── +function Get-MavenCommand { + # mvnw.cmd (Wrapper) 우선 확인 + $mvnw = "$BackendDir\mvnw.cmd" + if (Test-Path $mvnw) { + Write-OK "Maven Wrapper(mvnw.cmd) 사용 — 별도 Maven 설치 불필요" + return $mvnw + } + + # 시스템 Maven 확인 + $mvnCmd = Get-Command mvn -ErrorAction SilentlyContinue + if ($mvnCmd) { + $ver = & mvn --version 2>&1 | Select-Object -First 1 + Write-OK "시스템 Maven 감지: $ver" + return "mvn" + } + + # Maven 없음 → 자동 설치 + Write-Warn "Maven이 설치되지 않았습니다. 자동 설치를 진행합니다..." + Install-Maven + return "mvn" +} + +function Install-Maven { + # Chocolatey로 설치 시도 + if (Get-Command choco -ErrorAction SilentlyContinue) { + Write-Info "Chocolatey로 Maven 설치 중..." + choco install maven -y --no-progress 2>&1 | Out-Null + $mp = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + $up = [System.Environment]::GetEnvironmentVariable("Path", "User") + $env:Path = "$mp;$up" + if (Get-Command mvn -ErrorAction SilentlyContinue) { + Write-OK "Maven 설치 완료 (Chocolatey)" + return + } + } + + # 수동 설치 + $MavenVer = if ($env:MAVEN_VER) { $env:MAVEN_VER } else { "3.9.6" } + $MavenUrl = "https://archive.apache.org/dist/maven/maven-3/$MavenVer/binaries/apache-maven-$MavenVer-bin.zip" + $MavenHome = "C:\tools\maven" + + Write-Info "Maven $MavenVer 수동 설치 중..." + try { + Invoke-WebRequest $MavenUrl -OutFile "$env:TEMP\maven.zip" -UseBasicParsing -TimeoutSec 120 + Expand-Archive "$env:TEMP\maven.zip" -DestinationPath "C:\tools" -Force + if (Test-Path "C:\tools\apache-maven-$MavenVer") { + if (Test-Path $MavenHome) { Remove-Item $MavenHome -Recurse -Force } + Rename-Item "C:\tools\apache-maven-$MavenVer" $MavenHome + } + [System.Environment]::SetEnvironmentVariable("MAVEN_HOME", $MavenHome, "Machine") + $currentPath = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + [System.Environment]::SetEnvironmentVariable("Path", "$currentPath;$MavenHome\bin", "Machine") + $env:MAVEN_HOME = $MavenHome + $env:Path = "$env:Path;$MavenHome\bin" + Write-OK "Maven $MavenVer 수동 설치 완료: $MavenHome" + } catch { + Write-Fail "Maven 설치 실패: $_ — 수동으로 https://maven.apache.org/download.cgi 에서 설치하세요." + } +} + +$MvnCmd = Get-MavenCommand + +# ── 3. Node.js/npm 확인 ────────────────────────────────────── +$HasNpm = $false +if (Get-Command npm -ErrorAction SilentlyContinue) { + $npmVer = npm --version + Write-OK "npm $npmVer 감지" + $HasNpm = $true +} else { + Write-Warn "npm 없음 — 프론트엔드는 빌드 없이 실행됩니다." +} + +# ── 4. 실행 ─────────────────────────────────────────────────── +switch ($Mode) { + + "dev" { + Write-Host "" + Write-Info "=== 개발 모드 시작 ===" + Write-Info "백엔드: http://localhost:8080" + if ($HasNpm) { Write-Info "프론트: http://localhost:3000" } + + # 프론트엔드 의존성 설치 + if ($HasNpm -and -not (Test-Path "$FrontendDir\node_modules")) { + Push-Location $FrontendDir + npm install + Pop-Location + } + + # 백엔드 시작 + New-Item -ItemType Directory -Force "$BackendDir\data" | Out-Null + Push-Location $BackendDir + $springJob = Start-Job -ScriptBlock { param($dir,$mvn) cd $dir; & $mvn spring-boot:run } -ArgumentList $BackendDir, $MvnCmd + Pop-Location + + # 프론트엔드 시작 (npm 있을 때) + if ($HasNpm) { + Push-Location $FrontendDir + Start-Process npm -ArgumentList "run dev" -NoNewWindow + Pop-Location + } + + Write-OK "서비스 시작 완료" + Write-Host "종료: Ctrl+C" + Wait-Job $springJob + } + + "prod" { + Write-Host "" + Write-Info "=== 운영 모드 ===" + if ($HasNpm) { + Push-Location $FrontendDir + if (-not (Test-Path "node_modules")) { npm install } + npm run build + Write-OK "React 빌드 완료" + Pop-Location + } + New-Item -ItemType Directory -Force "$BackendDir\data" | Out-Null + Push-Location $BackendDir + & $MvnCmd clean package "-DskipTests" -q + $jar = Get-ChildItem target -Filter "*.jar" | Where-Object { $_.Name -notmatch "sources" } | Select-Object -First 1 + Write-OK "패키징 완료: $($jar.Name)" + java -jar $jar.FullName + Pop-Location + } + + "build" { + if ($HasNpm) { + Push-Location $FrontendDir + if (-not (Test-Path "node_modules")) { npm install } + npm run build + Write-OK "React 빌드 완료" + Pop-Location + } + Push-Location $BackendDir + & $MvnCmd clean package "-DskipTests" -q + $jar = Get-ChildItem target -Filter "*.jar" | Where-Object { $_.Name -notmatch "sources" } | Select-Object -First 1 + Write-OK "빌드 완료: $BackendDir\$($jar.Name)" + Write-Info "실행: java -jar $BackendDir\target\$($jar.Name)" + Pop-Location + } + + default { + Write-Host "사용법: .\start.ps1 [dev|prod|build]" + exit 1 + } +} diff --git a/workspace/zioinfo-web/start.sh b/workspace/zioinfo-web/start.sh new file mode 100644 index 00000000..e13215d6 --- /dev/null +++ b/workspace/zioinfo-web/start.sh @@ -0,0 +1,194 @@ +#!/bin/bash +# ============================================================= +# (주)지오정보기술 홈페이지 스타트업 스크립트 +# ============================================================= +# 사용법: bash start.sh [dev|prod|build] +# dev : 개발 모드 (React 핫리로드 + Spring Boot) +# prod : 운영 모드 (빌드 후 단일 JAR 실행) +# build : 빌드만 (서버 시작 안 함) +# ============================================================= + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BACKEND_DIR="$SCRIPT_DIR/backend" +FRONTEND_DIR="$SCRIPT_DIR/frontend" +MODE="${1:-dev}" + +GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' +ok() { echo -e "${GREEN}[OK]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +fail() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; } +info() { echo -e " $*"; } + +echo "==================================================" +echo " (주)지오정보기술 홈페이지 시작" +echo " 모드: $MODE" +echo "==================================================" + +# ── 1. Java 확인 ────────────────────────────────────────────── +if ! command -v java &>/dev/null; then + fail "Java가 설치되지 않았습니다. setup_ubuntu.sh 또는 setup_windows.ps1을 먼저 실행하세요." +fi +JAVA_VER=$(java -version 2>&1 | head -1 | awk -F'"' '{print $2}' | cut -d'.' -f1) +ok "Java $JAVA_VER 감지" + +# ── 2. Maven 감지 및 설치 ──────────────────────────────────── +ensure_maven() { + # mvnw (Wrapper) 우선 확인 + if [[ -f "$BACKEND_DIR/mvnw" ]]; then + chmod +x "$BACKEND_DIR/mvnw" + ok "Maven Wrapper(mvnw) 사용 — 별도 Maven 설치 불필요" + MVN="$BACKEND_DIR/mvnw" + return + fi + + # 시스템 Maven 확인 + if command -v mvn &>/dev/null; then + MVN_VER=$(mvn --version 2>/dev/null | head -1 | awk '{print $3}') + ok "시스템 Maven $MVN_VER 감지" + MVN="mvn" + return + fi + + # Maven 없음 → 자동 설치 + warn "Maven이 설치되지 않았습니다. 자동 설치를 진행합니다..." + install_maven + MVN="mvn" +} + +install_maven() { + MAVEN_VER="${MAVEN_VER:-3.9.6}" + MAVEN_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_VER}/binaries/apache-maven-${MAVEN_VER}-bin.tar.gz" + MAVEN_HOME="/opt/maven" + + # OS 감지하여 패키지 관리자로 우선 시도 + if command -v apt-get &>/dev/null; then + info "apt로 Maven 설치 시도..." + apt-get install -y -qq maven 2>/dev/null && { + ok "Maven 설치 완료 (apt)" + return + } + elif command -v dnf &>/dev/null; then + dnf install -y maven 2>/dev/null && { ok "Maven 설치 완료 (dnf)"; return; } + elif command -v yum &>/dev/null; then + yum install -y maven 2>/dev/null && { ok "Maven 설치 완료 (yum)"; return; } + fi + + # 패키지 관리자 실패 → 수동 설치 + info "Maven ${MAVEN_VER} 수동 설치 중..." + MIRROR="${MAVEN_MIRROR:-$MAVEN_URL}" + wget -q "$MIRROR" -O /tmp/maven.tar.gz \ + || fail "Maven 다운로드 실패. MAVEN_MIRROR 환경변수를 내부 미러로 설정하세요." + + mkdir -p "$MAVEN_HOME" + tar -xzf /tmp/maven.tar.gz -C "$MAVEN_HOME" --strip-components=1 + rm -f /tmp/maven.tar.gz + + # PATH 등록 + cat > /etc/profile.d/maven.sh << MVNEOF +export MAVEN_HOME=$MAVEN_HOME +export PATH=\$MAVEN_HOME/bin:\$PATH +MVNEOF + export MAVEN_HOME="$MAVEN_HOME" + export PATH="$MAVEN_HOME/bin:$PATH" + ok "Maven ${MAVEN_VER} 수동 설치 완료: $MAVEN_HOME" +} + +ensure_maven + +# ── 3. Node.js / npm 확인 (dev 모드) ───────────────────────── +if [[ "$MODE" == "dev" ]]; then + if ! command -v npm &>/dev/null; then + warn "npm이 없습니다. 프론트엔드는 빌드 없이 실행됩니다." + info "npm 설치: https://nodejs.org 또는 nvm 사용" + MODE="spring-only" + else + NPM_VER=$(npm --version) + ok "npm $NPM_VER 감지" + fi +fi + +# ── 4. 실행 ─────────────────────────────────────────────────── +case "$MODE" in + + dev) + echo "" + info "=== 개발 모드 시작 ===" + info "백엔드: http://localhost:8080" + info "프론트: http://localhost:3000" + echo "" + + # 프론트엔드 의존성 설치 + if [[ ! -d "$FRONTEND_DIR/node_modules" ]]; then + info "npm install 실행 중..." + cd "$FRONTEND_DIR" && npm install + fi + + # 백엔드 백그라운드 실행 + cd "$BACKEND_DIR" + mkdir -p data + info "Spring Boot 시작 중..." + $MVN spring-boot:run & + SPRING_PID=$! + + # 프론트엔드 포그라운드 실행 + cd "$FRONTEND_DIR" + npm run dev & + VITE_PID=$! + + # 종료 핸들러 + trap "kill $SPRING_PID $VITE_PID 2>/dev/null; exit" INT TERM + wait $SPRING_PID $VITE_PID + ;; + + spring-only) + echo "" + info "=== Spring Boot만 실행 (npm 없음) ===" + cd "$BACKEND_DIR" + mkdir -p data + $MVN spring-boot:run + ;; + + prod) + echo "" + info "=== 운영 모드 빌드 후 실행 ===" + # React 빌드 + if command -v npm &>/dev/null; then + cd "$FRONTEND_DIR" + [[ ! -d node_modules ]] && npm install + npm run build + ok "React 빌드 완료 → backend/src/main/resources/static/" + else + warn "npm 없음 — 기존 빌드 결과물 사용" + fi + # Spring Boot 패키징 + cd "$BACKEND_DIR" + mkdir -p data + $MVN clean package -DskipTests -q + ok "Spring Boot 패키징 완료" + JAR=$(find target -name "*.jar" ! -name "*sources*" | head -1) + info "실행: java -jar $JAR" + java -jar "$JAR" + ;; + + build) + echo "" + info "=== 빌드만 실행 ===" + if command -v npm &>/dev/null; then + cd "$FRONTEND_DIR" + [[ ! -d node_modules ]] && npm install + npm run build + ok "React 빌드 완료" + fi + cd "$BACKEND_DIR" + $MVN clean package -DskipTests -q + JAR=$(find target -name "*.jar" ! -name "*sources*" | head -1) + ok "빌드 완료: $JAR" + info "실행 명령: java -jar $BACKEND_DIR/$JAR" + ;; + + *) + echo "사용법: bash start.sh [dev|prod|build|spring-only]" + exit 1 + ;; +esac