Merge pull request '사용자 프로필 수정 기능 및 스크립트, 도커 파일 정리' (#7) from userProfile into dev
Reviewed-on: http://39.117.244.52:3000/kjs/ERP-node/pulls/7
This commit is contained in:
commit
f921396539
|
|
@ -245,3 +245,31 @@ cache/
|
|||
.vscode/settings.json
|
||||
.idea/workspace.xml
|
||||
*.user
|
||||
|
||||
# ===== Gradle 관련 파일들 (레거시 Java 프로젝트) =====
|
||||
# Gradle 캐시 및 빌드 파일들
|
||||
.gradle/
|
||||
*/.gradle/
|
||||
gradle/
|
||||
gradlew
|
||||
gradlew.bat
|
||||
gradle.properties
|
||||
build/
|
||||
*/build/
|
||||
|
||||
# Gradle Wrapper
|
||||
gradle-wrapper.jar
|
||||
gradle-wrapper.properties
|
||||
|
||||
# IntelliJ IDEA 관련 (Gradle 프로젝트)
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
out/
|
||||
|
||||
# Eclipse 관련 (Gradle 프로젝트)
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,386 @@
|
|||
# 🐳 Docker 가이드 - PLM 솔루션 (ERP-node)
|
||||
|
||||
이 문서는 PLM 솔루션의 Docker 환경 설정 및 사용법을 설명합니다.
|
||||
|
||||
## 📋 개요
|
||||
|
||||
**기술 스택:**
|
||||
|
||||
- **백엔드**: Node.js + TypeScript + Prisma + PostgreSQL
|
||||
- **프론트엔드**: Next.js + TypeScript + Tailwind CSS
|
||||
- **컨테이너**: Docker + Docker Compose
|
||||
|
||||
**환경:**
|
||||
|
||||
- **개발**: Mac (볼륨 마운트 + Hot Reload)
|
||||
- **운영**: Linux 서버 (최적화된 프로덕션 빌드)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 개발 환경 (Mac)
|
||||
|
||||
### 빠른 시작
|
||||
|
||||
```bash
|
||||
# 전체 서비스 시작 (병렬 빌드 - 가장 빠름!)
|
||||
./scripts/dev/start-all-parallel.sh
|
||||
```
|
||||
|
||||
### 개별 서비스 시작
|
||||
|
||||
```bash
|
||||
# 백엔드만 시작
|
||||
./scripts/dev/start-backend.sh
|
||||
|
||||
# 프론트엔드만 시작
|
||||
./scripts/dev/start-frontend.sh
|
||||
```
|
||||
|
||||
### 개발용 Docker Compose 파일들
|
||||
|
||||
- **`docker/dev/docker-compose.backend.mac.yml`** - Mac 개발용 백엔드
|
||||
|
||||
- 볼륨 마운트: `./backend-node:/app` (Hot Reload)
|
||||
- Dockerfile: `docker/dev/backend.Dockerfile`
|
||||
- 포트: `8080`
|
||||
|
||||
- **`docker/dev/docker-compose.frontend.mac.yml`** - Mac 개발용 프론트엔드
|
||||
- 볼륨 마운트: `./frontend:/app` (Hot Reload)
|
||||
- Dockerfile: `docker/dev/frontend.Dockerfile`
|
||||
- 포트: `3000`
|
||||
|
||||
### 개발 환경 특징
|
||||
|
||||
- ✅ **Hot Reload**: 코드 변경 시 자동 반영
|
||||
- ✅ **볼륨 마운트**: 실시간 개발
|
||||
- ✅ **디버그 모드**: 상세 로그 출력
|
||||
- ✅ **빠른 재시작**: Docker 재빌드 불필요
|
||||
|
||||
### 🔥 Hot Reload 상세 가이드
|
||||
|
||||
#### ✅ **바로 반영되는 것들 (즉시 Hot Reload)**
|
||||
|
||||
**백엔드 (Node.js + TypeScript):**
|
||||
|
||||
```bash
|
||||
backend-node/src/controllers/*.ts # API 컨트롤러 수정
|
||||
backend-node/src/services/*.ts # 비즈니스 로직 수정
|
||||
backend-node/src/routes/*.ts # 라우터 설정 수정
|
||||
backend-node/src/middleware/*.ts # 미들웨어 수정
|
||||
backend-node/src/utils/*.ts # 유틸리티 함수 수정
|
||||
backend-node/src/types/*.ts # 타입 정의 수정
|
||||
backend-node/src/config/*.ts # 애플리케이션 설정
|
||||
```
|
||||
|
||||
→ **반영 시간**: 1-2초 (nodemon 자동 재시작)
|
||||
|
||||
**프론트엔드 (Next.js + TypeScript):**
|
||||
|
||||
```bash
|
||||
frontend/components/**/*.tsx # React 컴포넌트 수정
|
||||
frontend/app/**/*.tsx # 페이지 컴포넌트 수정
|
||||
frontend/lib/**/*.ts # 유틸리티 함수 수정
|
||||
frontend/hooks/*.ts # 커스텀 훅 수정
|
||||
frontend/types/*.ts # 타입 정의 수정
|
||||
frontend/constants/*.ts # 상수 정의 수정
|
||||
CSS/SCSS 파일 수정 # 스타일 변경
|
||||
```
|
||||
|
||||
→ **반영 시간**: 즉시 (Fast Refresh)
|
||||
|
||||
#### ❌ **Docker 재시작이 필요한 것들**
|
||||
|
||||
**의존성 변경:**
|
||||
|
||||
```bash
|
||||
package.json 수정 # 새 패키지 추가/제거
|
||||
npm install / npm uninstall # 패키지 설치/제거
|
||||
package-lock.json 변경 # 의존성 잠금 파일
|
||||
```
|
||||
|
||||
**Prisma 관련:**
|
||||
|
||||
```bash
|
||||
backend-node/prisma/schema.prisma # DB 스키마 변경
|
||||
npx prisma migrate # 마이그레이션 실행
|
||||
npx prisma generate # 클라이언트 재생성
|
||||
```
|
||||
|
||||
**설정 파일:**
|
||||
|
||||
```bash
|
||||
next.config.mjs # Next.js 설정
|
||||
tsconfig.json # TypeScript 설정
|
||||
tailwind.config.js # Tailwind CSS 설정
|
||||
.env / .env.local # 환경 변수
|
||||
eslint.config.mjs # ESLint 설정
|
||||
```
|
||||
|
||||
**Docker 관련:**
|
||||
|
||||
```bash
|
||||
Dockerfile / Dockerfile.dev # 도커 파일 수정
|
||||
docker-compose.*.yml # Docker Compose 설정
|
||||
.dockerignore # Docker 무시 파일
|
||||
```
|
||||
|
||||
#### 🔄 **재시작 방법**
|
||||
|
||||
**특정 서비스만 재시작:**
|
||||
|
||||
```bash
|
||||
# 백엔드만 재시작
|
||||
docker-compose -f docker-compose.backend.mac.yml restart backend
|
||||
|
||||
# 프론트엔드만 재시작
|
||||
docker-compose -f docker-compose.frontend.mac.yml restart frontend
|
||||
```
|
||||
|
||||
**전체 재빌드:**
|
||||
|
||||
```bash
|
||||
# 의존성 변경 시 (rebuild 필요)
|
||||
docker-compose -f docker-compose.backend.mac.yml up --build -d
|
||||
docker-compose -f docker-compose.frontend.mac.yml up --build -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 운영 환경 (Linux)
|
||||
|
||||
### 운영 서버 배포
|
||||
|
||||
```bash
|
||||
# Linux 서버에서 실행
|
||||
./scripts/prod/start-all-linux.sh
|
||||
```
|
||||
|
||||
### 개별 서비스 시작 (운영용)
|
||||
|
||||
```bash
|
||||
# 직접 Docker Compose 사용
|
||||
docker-compose -f docker/prod/docker-compose.backend.prod.yml up -d
|
||||
docker-compose -f docker/prod/docker-compose.frontend.prod.yml up -d
|
||||
```
|
||||
|
||||
### 운영용 Docker Compose 파일들
|
||||
|
||||
- **`docker/prod/docker-compose.backend.prod.yml`** - 운영용 백엔드
|
||||
|
||||
- Dockerfile: `docker/prod/backend.Dockerfile` (프로덕션 최적화)
|
||||
- 포트: `8080`
|
||||
- 환경: `NODE_ENV=production`
|
||||
|
||||
- **`docker/prod/docker-compose.frontend.prod.yml`** - 운영용 프론트엔드
|
||||
- Dockerfile: `docker/prod/frontend.Dockerfile` (프로덕션 최적화)
|
||||
- 포트: `3000`
|
||||
- 환경: 최적화된 빌드
|
||||
|
||||
### 운영 환경 특징
|
||||
|
||||
- ✅ **최적화된 빌드**: 프로덕션용 이미지
|
||||
- ✅ **보안 강화**: 운영 환경 설정
|
||||
- ✅ **성능 최적화**: 이미지 크기 최소화
|
||||
- ✅ **안정성**: 프로덕션 모드
|
||||
|
||||
---
|
||||
|
||||
## 📁 프로젝트 구조
|
||||
|
||||
```
|
||||
ERP-node/
|
||||
├── 🔧 개발용 (Mac)
|
||||
│ ├── start-all-parallel.sh # 병렬 시작 (추천)
|
||||
│ ├── start-backend.sh # 백엔드만
|
||||
│ ├── start-frontend.sh # 프론트엔드만
|
||||
│ ├── docker-compose.backend.mac.yml # Mac 개발용 백엔드
|
||||
│ └── docker-compose.frontend.mac.yml# Mac 개발용 프론트엔드
|
||||
│
|
||||
├── 🚀 운영용 (Linux)
|
||||
│ ├── start-all-separated-linux.sh # Linux 운영용
|
||||
│ ├── start-backend-linux.sh # 백엔드만 (Linux)
|
||||
│ ├── start-frontend-linux.sh # 프론트엔드만 (Linux)
|
||||
│ ├── docker-compose.backend.prod.yml# 운영용 백엔드
|
||||
│ └── docker-compose.frontend.prod.yml# 운영용 프론트엔드
|
||||
│
|
||||
├── 📁 백엔드
|
||||
│ ├── backend-node/
|
||||
│ │ ├── Dockerfile # 프로덕션용
|
||||
│ │ └── Dockerfile.dev # 개발용
|
||||
│ └── src/, prisma/, package.json...
|
||||
│
|
||||
├── 📁 프론트엔드
|
||||
│ ├── frontend/
|
||||
│ │ ├── Dockerfile # 프로덕션용
|
||||
│ │ └── Dockerfile.dev # 개발용
|
||||
│ └── app/, components/, hooks/...
|
||||
│
|
||||
└── 🗂️ 기타
|
||||
├── db/00-create-roles.sh # DB 초기화
|
||||
└── README.md, DOCKER.md...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🌐 접속 정보
|
||||
|
||||
### 개발 환경
|
||||
|
||||
- **프론트엔드**: http://localhost:3000
|
||||
- **백엔드 API**: http://localhost:8080
|
||||
- **전체 앱**: http://localhost:9771 (프록시 설정 시)
|
||||
|
||||
### 운영 환경
|
||||
|
||||
- **서버 IP에 따라 다름** (Linux 서버 설정 확인)
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 주요 명령어
|
||||
|
||||
### Docker 컨테이너 관리
|
||||
|
||||
```bash
|
||||
# 실행 중인 컨테이너 확인
|
||||
docker ps
|
||||
|
||||
# 모든 컨테이너 중지
|
||||
docker stop $(docker ps -q)
|
||||
|
||||
# 사용하지 않는 컨테이너/이미지 정리
|
||||
docker system prune -f
|
||||
```
|
||||
|
||||
### 로그 확인
|
||||
|
||||
```bash
|
||||
# 백엔드 로그
|
||||
docker logs pms-backend-mac -f # 개발용
|
||||
docker logs pms-backend-prod -f # 운영용
|
||||
|
||||
# 프론트엔드 로그
|
||||
docker logs pms-frontend-mac -f # 개발용
|
||||
docker logs pms-frontend-prod -f # 운영용
|
||||
```
|
||||
|
||||
### 컨테이너 내부 접속
|
||||
|
||||
```bash
|
||||
# 백엔드 컨테이너 접속
|
||||
docker exec -it pms-backend-mac bash # 개발용
|
||||
docker exec -it pms-backend-prod bash # 운영용
|
||||
|
||||
# 프론트엔드 컨테이너 접속
|
||||
docker exec -it pms-frontend-mac sh # 개발용
|
||||
docker exec -it pms-frontend-prod sh # 운영용
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 트러블슈팅
|
||||
|
||||
### 자주 발생하는 문제들
|
||||
|
||||
#### 1. 포트 충돌
|
||||
|
||||
```bash
|
||||
# 포트 사용 중인 프로세스 확인
|
||||
lsof -i :8080
|
||||
lsof -i :3000
|
||||
|
||||
# 프로세스 종료
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
#### 2. Docker 빌드 오류
|
||||
|
||||
```bash
|
||||
# Docker 캐시 클리어 후 재빌드
|
||||
docker builder prune -f
|
||||
./start-all-parallel.sh
|
||||
```
|
||||
|
||||
#### 3. 볼륨 마운트 문제 (개발환경)
|
||||
|
||||
```bash
|
||||
# Docker Desktop 설정에서 파일 공유 확인
|
||||
# Docker Desktop > Settings > Resources > File Sharing
|
||||
```
|
||||
|
||||
#### 4. 데이터베이스 연결 오류
|
||||
|
||||
```bash
|
||||
# 데이터베이스 초기화
|
||||
./db/00-create-roles.sh
|
||||
|
||||
# PostgreSQL 연결 확인
|
||||
docker exec -it <db-container> psql -U postgres
|
||||
```
|
||||
|
||||
### Warning 메시지들 (무시해도 됨)
|
||||
|
||||
```
|
||||
WARN: the attribute `version` is obsolete
|
||||
Network Error (일시적)
|
||||
```
|
||||
|
||||
이런 메시지들은 Docker Compose 버전 차이로 발생하며, 기능에는 영향 없습니다.
|
||||
|
||||
---
|
||||
|
||||
## 📈 성능 최적화
|
||||
|
||||
### 개발 환경 최적화
|
||||
|
||||
- ✅ **병렬 빌드**: `start-all-parallel.sh` 사용
|
||||
- ✅ **Docker 캐시**: `--no-cache` 제거됨
|
||||
- ✅ **npm 최적화**: `--prefer-offline --no-audit` 적용
|
||||
|
||||
### 운영 환경 최적화
|
||||
|
||||
- ✅ **멀티 스테이지 빌드**: Dockerfile 최적화
|
||||
- ✅ **이미지 크기 최소화**: Alpine Linux 기반
|
||||
- ✅ **의존성 캐시**: 레이어 캐싱 활용
|
||||
|
||||
---
|
||||
|
||||
## 🔄 업데이트 가이드
|
||||
|
||||
### 개발 환경 업데이트
|
||||
|
||||
```bash
|
||||
# 코드 변경 시 (Hot Reload 자동 반영)
|
||||
# 별도 작업 불필요
|
||||
|
||||
# 의존성 변경 시
|
||||
docker-compose -f docker-compose.backend.mac.yml up --build -d
|
||||
```
|
||||
|
||||
### 운영 환경 업데이트
|
||||
|
||||
```bash
|
||||
# 새로운 버전 배포
|
||||
./start-all-separated-linux.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 지원
|
||||
|
||||
**문제 발생 시:**
|
||||
|
||||
1. 이 문서의 트러블슈팅 섹션 확인
|
||||
2. Docker 로그 확인 (`docker logs <container-name>`)
|
||||
3. 개발팀에 문의
|
||||
|
||||
**프로젝트 관련:**
|
||||
|
||||
- Node.js 백엔드: `backend-node/` 디렉토리
|
||||
- Next.js 프론트엔드: `frontend/` 디렉토리
|
||||
- 데이터베이스: PostgreSQL (JNDI 설정)
|
||||
|
||||
---
|
||||
|
||||
**버전**: 1.0.0
|
||||
**마지막 업데이트**: 2024년 12월 28일
|
||||
**작성자**: PLM 개발팀
|
||||
321
DOCKER_SETUP.md
321
DOCKER_SETUP.md
|
|
@ -1,321 +0,0 @@
|
|||
# PLM WACE Docker 설정 가이드
|
||||
|
||||
## 개요
|
||||
이 문서는 PLM WACE 애플리케이션을 Docker로 실행하는 방법을 설명합니다.
|
||||
|
||||
## 시스템 요구사항
|
||||
|
||||
### 리눅스 환경
|
||||
- Ubuntu 18.04 이상 또는 CentOS 7 이상
|
||||
- Docker 20.10 이상
|
||||
- Docker Compose 1.29 이상
|
||||
- Git (운영환경 배포 시)
|
||||
|
||||
### 필수 소프트웨어 설치
|
||||
|
||||
#### Docker 설치 (Ubuntu)
|
||||
```bash
|
||||
# Docker 공식 GPG 키 추가
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
|
||||
# Docker 리포지토리 추가
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Docker 설치
|
||||
sudo apt update
|
||||
sudo apt install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
# Docker Compose 설치
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# 사용자를 docker 그룹에 추가
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
#### Docker 설치 (CentOS)
|
||||
```bash
|
||||
# Docker 설치
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
sudo yum install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
# Docker Compose 설치
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Docker 서비스 시작
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
|
||||
# 사용자를 docker 그룹에 추가
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
## 환경 설정
|
||||
|
||||
### 1. 환경 변수 파일 생성
|
||||
|
||||
#### 개발환경
|
||||
```bash
|
||||
# 개발환경 환경 변수 파일 생성
|
||||
cp env.development.example .env.development
|
||||
|
||||
# 필요에 따라 설정 수정
|
||||
vim .env.development
|
||||
```
|
||||
|
||||
#### 운영환경
|
||||
```bash
|
||||
# 운영환경 환경 변수 파일 생성
|
||||
cp env.production.example .env.production
|
||||
|
||||
# 운영환경에 맞게 설정 수정 (특히 비밀번호)
|
||||
vim .env.production
|
||||
```
|
||||
|
||||
### 2. 환경 변수 설정 항목
|
||||
|
||||
#### 주요 설정 항목
|
||||
- `DB_URL`: 데이터베이스 연결 URL
|
||||
- `DB_USERNAME`: 데이터베이스 사용자명
|
||||
- `DB_PASSWORD`: 데이터베이스 비밀번호
|
||||
- `JAVA_OPTS`: JVM 옵션 (메모리 설정 등)
|
||||
- `LOG_LEVEL`: 로그 레벨 (DEBUG, INFO, WARN, ERROR)
|
||||
|
||||
## 스크립트 사용법
|
||||
|
||||
### 기본 사용법
|
||||
```bash
|
||||
# 실행 권한 부여 (최초 1회)
|
||||
chmod +x start-docker-linux.sh
|
||||
|
||||
# 개발환경 실행
|
||||
./start-docker-linux.sh
|
||||
|
||||
# 운영환경 실행
|
||||
./start-docker-linux.sh -e prod
|
||||
```
|
||||
|
||||
### 주요 옵션
|
||||
|
||||
#### 환경 설정
|
||||
```bash
|
||||
# 개발환경 실행
|
||||
./start-docker-linux.sh -e dev
|
||||
|
||||
# 운영환경 실행
|
||||
./start-docker-linux.sh -e prod
|
||||
```
|
||||
|
||||
#### 컨테이너 관리
|
||||
```bash
|
||||
# 컨테이너 중지
|
||||
./start-docker-linux.sh -s
|
||||
|
||||
# 컨테이너 재시작
|
||||
./start-docker-linux.sh -r
|
||||
|
||||
# Docker 시스템 정리 후 실행
|
||||
./start-docker-linux.sh -c
|
||||
```
|
||||
|
||||
#### 로그 및 모니터링
|
||||
```bash
|
||||
# 실시간 로그 확인
|
||||
./start-docker-linux.sh -l
|
||||
|
||||
# 도움말 확인
|
||||
./start-docker-linux.sh -h
|
||||
```
|
||||
|
||||
### 옵션 조합
|
||||
```bash
|
||||
# 개발환경에서 Docker 정리 후 재시작
|
||||
./start-docker-linux.sh -e dev -c -r
|
||||
|
||||
# 운영환경에서 재시작
|
||||
./start-docker-linux.sh -e prod -r
|
||||
```
|
||||
|
||||
## 접속 정보
|
||||
|
||||
### 개발환경
|
||||
- 애플리케이션: http://localhost:8090
|
||||
- 데이터베이스: localhost:5432 (내부 DB 사용 시)
|
||||
|
||||
### 운영환경
|
||||
- 애플리케이션: https://ilshin.esgrin.com
|
||||
- 대체 도메인: https://autoclave.co.kr
|
||||
|
||||
## 트러블슈팅
|
||||
|
||||
### 일반적인 문제
|
||||
|
||||
#### 1. Docker 서비스 오류
|
||||
```bash
|
||||
# Docker 서비스 상태 확인
|
||||
sudo systemctl status docker
|
||||
|
||||
# Docker 서비스 시작
|
||||
sudo systemctl start docker
|
||||
|
||||
# Docker 서비스 자동 시작 설정
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
#### 2. 권한 오류
|
||||
```bash
|
||||
# 사용자를 docker 그룹에 추가
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# 로그아웃 후 재로그인 또는 그룹 변경 적용
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
#### 3. 포트 충돌
|
||||
```bash
|
||||
# 포트 사용 확인
|
||||
sudo netstat -tlnp | grep :8090
|
||||
|
||||
# 프로세스 종료
|
||||
sudo kill -9 <PID>
|
||||
```
|
||||
|
||||
#### 4. 환경 변수 파일 오류
|
||||
```bash
|
||||
# 환경 변수 파일 존재 확인
|
||||
ls -la .env.*
|
||||
|
||||
# 환경 변수 파일 내용 확인
|
||||
cat .env.development
|
||||
```
|
||||
|
||||
### 로그 확인
|
||||
|
||||
#### 컨테이너 로그
|
||||
```bash
|
||||
# 전체 로그 확인
|
||||
./start-docker-linux.sh -l
|
||||
|
||||
# 특정 서비스 로그 확인
|
||||
docker-compose -f docker-compose.dev.yml logs plm-ilshin
|
||||
|
||||
# 로그 파일 확인 (컨테이너 내부)
|
||||
docker exec -it plm-ilshin-container tail -f /usr/local/tomcat/logs/catalina.out
|
||||
```
|
||||
|
||||
#### 시스템 로그
|
||||
```bash
|
||||
# Docker 데몬 로그 확인
|
||||
sudo journalctl -u docker.service
|
||||
|
||||
# 시스템 로그 확인
|
||||
sudo journalctl -xe
|
||||
```
|
||||
|
||||
## 고급 사용법
|
||||
|
||||
### 수동 Docker Compose 사용
|
||||
```bash
|
||||
# 개발환경 수동 실행
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# 운영환경 수동 실행
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# 컨테이너 중지
|
||||
docker-compose -f docker-compose.dev.yml down
|
||||
```
|
||||
|
||||
### 컨테이너 내부 접근
|
||||
```bash
|
||||
# 컨테이너 내부 접근
|
||||
docker exec -it plm-ilshin-container bash
|
||||
|
||||
# 데이터베이스 접근 (내부 DB 사용 시)
|
||||
docker exec -it plm-ilshin-db-container psql -U postgres -d ilshin
|
||||
```
|
||||
|
||||
### 백업 및 복원
|
||||
```bash
|
||||
# 데이터베이스 백업
|
||||
docker exec plm-ilshin-db-container pg_dump -U postgres ilshin > backup.sql
|
||||
|
||||
# 데이터베이스 복원
|
||||
docker exec -i plm-ilshin-db-container psql -U postgres ilshin < backup.sql
|
||||
```
|
||||
|
||||
## 보안 고려사항
|
||||
|
||||
### 운영환경 보안
|
||||
1. 환경 변수 파일 권한 설정
|
||||
```bash
|
||||
chmod 600 .env.production
|
||||
```
|
||||
|
||||
2. 방화벽 설정
|
||||
```bash
|
||||
# 필요한 포트만 열기
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
3. SSL 인증서 설정 (Traefik 사용)
|
||||
- Let's Encrypt 자동 갱신 설정
|
||||
- 도메인 검증 설정
|
||||
|
||||
### 개발환경 보안
|
||||
1. 개발용 비밀번호 사용
|
||||
2. 외부 접근 제한
|
||||
3. 정기적인 이미지 업데이트
|
||||
|
||||
## 성능 최적화
|
||||
|
||||
### JVM 튜닝
|
||||
```bash
|
||||
# .env 파일에서 JVM 옵션 조정
|
||||
JAVA_OPTS=-Xms1024m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m
|
||||
```
|
||||
|
||||
### Docker 리소스 제한
|
||||
```yaml
|
||||
# docker-compose.yml에서 리소스 제한
|
||||
services:
|
||||
plm-ilshin:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2.0'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
## 모니터링
|
||||
|
||||
### 컨테이너 상태 모니터링
|
||||
```bash
|
||||
# 컨테이너 상태 확인
|
||||
docker ps
|
||||
|
||||
# 리소스 사용량 확인
|
||||
docker stats
|
||||
|
||||
# 컨테이너 로그 모니터링
|
||||
docker logs -f plm-ilshin-container
|
||||
```
|
||||
|
||||
### 애플리케이션 모니터링
|
||||
- 애플리케이션 로그 확인
|
||||
- 데이터베이스 연결 상태 확인
|
||||
- 메모리 사용량 모니터링
|
||||
|
||||
## 지원 및 문의
|
||||
|
||||
문제가 발생하거나 추가 도움이 필요한 경우:
|
||||
1. 로그 파일 확인
|
||||
2. 환경 설정 검토
|
||||
3. 개발팀 문의
|
||||
20
Dockerfile
20
Dockerfile
|
|
@ -1,20 +0,0 @@
|
|||
FROM localhost:8787/tomcat:7.0.94-jre7-alpine.linux AS production
|
||||
|
||||
# Remove default webapps
|
||||
RUN rm -rf /usr/local/tomcat/webapps/*
|
||||
|
||||
# Copy web application content (compiled classes and web resources)
|
||||
COPY WebContent /usr/local/tomcat/webapps/ROOT
|
||||
COPY src /usr/local/tomcat/webapps/ROOT/WEB-INF/src
|
||||
|
||||
# Copy custom Tomcat context configuration for JNDI
|
||||
COPY ./tomcat-conf/context.xml /usr/local/tomcat/conf/context.xml
|
||||
|
||||
# Copy database driver if needed (PostgreSQL driver is already in WEB-INF/lib)
|
||||
# COPY path/to/postgresql-driver.jar /usr/local/tomcat/lib/
|
||||
|
||||
# Expose Tomcat port
|
||||
EXPOSE 8080
|
||||
|
||||
# Start Tomcat
|
||||
CMD ["catalina.sh", "run"]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
FROM localhost:8787/tomcat:7.0.94-jre7-alpine.linux AS Development
|
||||
|
||||
# Remove default webapps
|
||||
RUN rm -rf /usr/local/tomcat/webapps/*
|
||||
|
||||
# Copy web application content (compiled classes and web resources)
|
||||
COPY WebContent /usr/local/tomcat/webapps/ROOT
|
||||
COPY src /usr/local/tomcat/webapps/ROOT/WEB-INF/src
|
||||
|
||||
# Copy custom Tomcat context configuration for JNDI
|
||||
COPY ./tomcat-conf/context.xml /usr/local/tomcat/conf/context.xml
|
||||
|
||||
# Copy database driver if needed (PostgreSQL driver is already in WEB-INF/lib)
|
||||
# COPY path/to/postgresql-driver.jar /usr/local/tomcat/lib/
|
||||
|
||||
# Expose Tomcat port
|
||||
EXPOSE 8080
|
||||
|
||||
# Start Tomcat
|
||||
CMD ["catalina.sh", "run"]
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
# 윈도우용 PLM 애플리케이션 Dockerfile
|
||||
FROM tomcat:7.0.94-jre7-alpine
|
||||
|
||||
# 메타데이터
|
||||
LABEL maintainer="PLM Development Team"
|
||||
LABEL description="PLM Application for Windows Environment"
|
||||
LABEL version="1.0"
|
||||
|
||||
# 작업 디렉토리 설정
|
||||
WORKDIR /usr/local/tomcat
|
||||
|
||||
# 필수 패키지 설치 (curl 포함)
|
||||
RUN apk add --no-cache curl tzdata
|
||||
|
||||
# 환경 변수 설정
|
||||
ENV CATALINA_HOME=/usr/local/tomcat
|
||||
ENV CATALINA_BASE=/usr/local/tomcat
|
||||
ENV JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m"
|
||||
ENV TZ=Asia/Seoul
|
||||
|
||||
# 타임존 설정 (서울)
|
||||
RUN cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
|
||||
echo "Asia/Seoul" > /etc/timezone
|
||||
|
||||
# 기본 Tomcat 애플리케이션 제거
|
||||
RUN rm -rf /usr/local/tomcat/webapps/*
|
||||
|
||||
# 애플리케이션 복사
|
||||
COPY WebContent/ /usr/local/tomcat/webapps/ROOT/
|
||||
COPY tomcat-conf/context.xml /usr/local/tomcat/conf/
|
||||
|
||||
# 로그 디렉토리 생성
|
||||
RUN mkdir -p /usr/local/tomcat/logs
|
||||
|
||||
# 권한 설정
|
||||
RUN chmod -R 755 /usr/local/tomcat/webapps/ROOT && \
|
||||
chmod 644 /usr/local/tomcat/conf/context.xml
|
||||
|
||||
# 포트 노출
|
||||
EXPOSE 8080
|
||||
|
||||
# 개선된 헬스체크 (윈도우 환경 고려)
|
||||
HEALTHCHECK --interval=30s --timeout=15s --start-period=90s --retries=5 \
|
||||
CMD curl -f http://localhost:8080/ROOT/ || curl -f http://localhost:8080/ || exit 1
|
||||
|
||||
# 실행 명령
|
||||
CMD ["catalina.sh", "run"]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
@echo off
|
||||
echo =================================
|
||||
echo 백엔드 빌드만 실행
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
echo [1/1] 백엔드 빌드 중...
|
||||
docker-compose -f docker-compose.springboot.yml build backend
|
||||
|
||||
echo.
|
||||
echo 백엔드 빌드 완료!
|
||||
echo.
|
||||
pause
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
@echo off
|
||||
echo =================================
|
||||
echo Gradle 백엔드 로컬 빌드
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0\backend
|
||||
|
||||
echo [1/3] Gradle 권한 설정...
|
||||
if not exist "gradlew.bat" (
|
||||
echo gradlew.bat 파일을 찾을 수 없습니다.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [2/3] 이전 빌드 정리...
|
||||
call gradlew clean
|
||||
|
||||
echo [3/3] 프로젝트 빌드...
|
||||
call gradlew build -x test
|
||||
|
||||
if %errorlevel% equ 0 (
|
||||
echo.
|
||||
echo 백엔드 빌드 성공!
|
||||
echo JAR 파일 위치: backend\build\libs\
|
||||
echo.
|
||||
) else (
|
||||
echo.
|
||||
echo 빌드 실패! 오류를 확인하세요.
|
||||
echo.
|
||||
)
|
||||
|
||||
pause
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
@echo off
|
||||
echo =================================
|
||||
echo 백엔드 로그 확인
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
echo 백엔드 컨테이너 로그를 실시간으로 확인합니다...
|
||||
echo Ctrl+C를 눌러서 종료할 수 있습니다.
|
||||
echo.
|
||||
|
||||
docker-compose -f docker-compose.springboot.yml logs -f backend
|
||||
|
|
@ -3,10 +3,13 @@ import { logger } from "../utils/logger";
|
|||
import { AuthenticatedRequest } from "../types/auth";
|
||||
import { ApiResponse } from "../types/common";
|
||||
import { Client } from "pg";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import config from "../config/environment";
|
||||
import { AdminService } from "../services/adminService";
|
||||
import { EncryptUtil } from "../utils/encryptUtil";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
/**
|
||||
* 관리자 메뉴 목록 조회
|
||||
*/
|
||||
|
|
@ -347,10 +350,9 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
|||
const countParams = [...queryParams];
|
||||
|
||||
// 총 개수 조회를 위해 기존 쿼리를 COUNT로 변환
|
||||
const countQuery = query.replace(
|
||||
/SELECT[\s\S]*?FROM/i,
|
||||
"SELECT COUNT(*) as total FROM"
|
||||
).replace(/ORDER BY.*$/i, "");
|
||||
const countQuery = query
|
||||
.replace(/SELECT[\s\S]*?FROM/i, "SELECT COUNT(*) as total FROM")
|
||||
.replace(/ORDER BY.*$/i, "");
|
||||
|
||||
const countResult = await client.query(countQuery, countParams);
|
||||
const totalCount = parseInt(countResult.rows[0].total);
|
||||
|
|
@ -1737,6 +1739,7 @@ export const getUserInfo = async (req: AuthenticatedRequest, res: Response) => {
|
|||
u.fax_no,
|
||||
u.partner_objid,
|
||||
u.rank,
|
||||
u.photo,
|
||||
u.locale,
|
||||
u.company_code,
|
||||
u.data_type,
|
||||
|
|
@ -1789,6 +1792,9 @@ export const getUserInfo = async (req: AuthenticatedRequest, res: Response) => {
|
|||
faxNo: user.fax_no,
|
||||
partnerObjid: user.partner_objid,
|
||||
rank: user.rank,
|
||||
photo: user.photo
|
||||
? `data:image/jpeg;base64,${user.photo.toString("base64")}`
|
||||
: null,
|
||||
locale: user.locale,
|
||||
companyCode: user.company_code,
|
||||
dataType: user.data_type,
|
||||
|
|
@ -2686,6 +2692,127 @@ export const deleteCompany = async (
|
|||
* 사용자 비밀번호 초기화 API
|
||||
* 기존 Java AdminController.resetUserPassword() 포팅
|
||||
*/
|
||||
export const updateProfile = async (
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
) => {
|
||||
try {
|
||||
const userId = req.user?.userId;
|
||||
if (!userId) {
|
||||
res.status(401).json({
|
||||
result: false,
|
||||
error: {
|
||||
code: "TOKEN_MISSING",
|
||||
details: "인증 토큰이 필요합니다.",
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
userName,
|
||||
userNameEng,
|
||||
userNameCn,
|
||||
email,
|
||||
tel,
|
||||
cellPhone,
|
||||
photo,
|
||||
locale,
|
||||
} = req.body;
|
||||
|
||||
// 사용자 정보 업데이트
|
||||
const updateData: any = {};
|
||||
if (userName !== undefined) updateData.user_name = userName;
|
||||
if (userNameEng !== undefined) updateData.user_name_eng = userNameEng;
|
||||
if (userNameCn !== undefined) updateData.user_name_cn = userNameCn;
|
||||
if (email !== undefined) updateData.email = email;
|
||||
if (tel !== undefined) updateData.tel = tel;
|
||||
if (cellPhone !== undefined) updateData.cell_phone = cellPhone;
|
||||
|
||||
// photo 데이터 처리 (Base64를 Buffer로 변환하여 저장)
|
||||
if (photo !== undefined) {
|
||||
if (photo && typeof photo === "string") {
|
||||
try {
|
||||
// Base64 헤더 제거 (data:image/jpeg;base64, 등)
|
||||
const base64Data = photo.replace(/^data:image\/[a-z]+;base64,/, "");
|
||||
// Base64를 Buffer로 변환
|
||||
updateData.photo = Buffer.from(base64Data, "base64");
|
||||
} catch (error) {
|
||||
console.error("Base64 이미지 처리 오류:", error);
|
||||
updateData.photo = null;
|
||||
}
|
||||
} else {
|
||||
updateData.photo = null; // 빈 값이면 null로 설정
|
||||
}
|
||||
}
|
||||
|
||||
if (locale !== undefined) updateData.locale = locale;
|
||||
|
||||
// 업데이트할 데이터가 없으면 에러
|
||||
if (Object.keys(updateData).length === 0) {
|
||||
res.status(400).json({
|
||||
result: false,
|
||||
error: {
|
||||
code: "NO_DATA",
|
||||
details: "업데이트할 데이터가 없습니다.",
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 데이터베이스 업데이트
|
||||
await prisma.user_info.update({
|
||||
where: { user_id: userId },
|
||||
data: updateData,
|
||||
});
|
||||
|
||||
// 업데이트된 사용자 정보 조회
|
||||
const updatedUser = await prisma.user_info.findUnique({
|
||||
where: { user_id: userId },
|
||||
select: {
|
||||
user_id: true,
|
||||
user_name: true,
|
||||
user_name_eng: true,
|
||||
user_name_cn: true,
|
||||
dept_code: true,
|
||||
dept_name: true,
|
||||
position_code: true,
|
||||
position_name: true,
|
||||
email: true,
|
||||
tel: true,
|
||||
cell_phone: true,
|
||||
user_type: true,
|
||||
user_type_name: true,
|
||||
photo: true,
|
||||
locale: true,
|
||||
},
|
||||
});
|
||||
|
||||
// photo가 Buffer 타입인 경우 Base64로 변환
|
||||
const responseData = {
|
||||
...updatedUser,
|
||||
photo: updatedUser?.photo
|
||||
? `data:image/jpeg;base64,${updatedUser.photo.toString("base64")}`
|
||||
: null,
|
||||
};
|
||||
|
||||
res.json({
|
||||
result: true,
|
||||
message: "프로필이 성공적으로 업데이트되었습니다.",
|
||||
data: responseData,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("프로필 업데이트 오류:", error);
|
||||
res.status(500).json({
|
||||
result: false,
|
||||
error: {
|
||||
code: "UPDATE_FAILED",
|
||||
details: "프로필 업데이트 중 오류가 발생했습니다.",
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const resetUserPassword = async (
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
|
|
|
|||
|
|
@ -166,15 +166,33 @@ export class AuthController {
|
|||
|
||||
const userInfo = JwtUtils.verifyToken(token);
|
||||
|
||||
// DB에서 최신 사용자 정보 조회 (locale 포함)
|
||||
const dbUserInfo = await AuthService.getUserInfo(userInfo.userId);
|
||||
|
||||
if (!dbUserInfo) {
|
||||
res.status(401).json({
|
||||
success: false,
|
||||
message: "사용자 정보를 찾을 수 없습니다.",
|
||||
error: {
|
||||
code: "USER_NOT_FOUND",
|
||||
details: "사용자 정보가 삭제되었거나 존재하지 않습니다.",
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const userInfoResponse: UserInfo = {
|
||||
userId: userInfo.userId,
|
||||
userName: userInfo.userName || "",
|
||||
deptName: userInfo.deptName || "",
|
||||
companyCode: userInfo.companyCode || "ILSHIN",
|
||||
userType: userInfo.userType || "USER",
|
||||
userTypeName: userInfo.userTypeName || "일반사용자",
|
||||
userId: dbUserInfo.userId,
|
||||
userName: dbUserInfo.userName || "",
|
||||
deptName: dbUserInfo.deptName || "",
|
||||
companyCode: dbUserInfo.companyCode || "ILSHIN",
|
||||
userType: dbUserInfo.userType || "USER",
|
||||
userTypeName: dbUserInfo.userTypeName || "일반사용자",
|
||||
email: dbUserInfo.email || "",
|
||||
photo: dbUserInfo.photo,
|
||||
locale: dbUserInfo.locale || "KR", // locale 정보 추가
|
||||
isAdmin:
|
||||
userInfo.userType === "ADMIN" || userInfo.userId === "plm_admin",
|
||||
dbUserInfo.userType === "ADMIN" || dbUserInfo.userId === "plm_admin",
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
getUserHistory, // 사용자 변경이력 조회
|
||||
changeUserStatus, // 사용자 상태 변경
|
||||
resetUserPassword, // 사용자 비밀번호 초기화
|
||||
updateProfile, // 프로필 수정
|
||||
getDepartmentList, // 부서 목록 조회
|
||||
checkDuplicateUserId, // 사용자 ID 중복 체크
|
||||
saveUser, // 사용자 등록/수정
|
||||
|
|
@ -45,6 +46,7 @@ router.get("/users/:userId", getUserInfo); // 사용자 상세 조회
|
|||
router.get("/users/:userId/history", getUserHistory); // 사용자 변경이력 조회
|
||||
router.patch("/users/:userId/status", changeUserStatus); // 사용자 상태 변경
|
||||
router.post("/users", saveUser); // 사용자 등록/수정
|
||||
router.put("/profile", updateProfile); // 프로필 수정
|
||||
router.post("/users/check-duplicate", checkDuplicateUserId); // 사용자 ID 중복 체크
|
||||
router.post("/users/reset-password", resetUserPassword); // 사용자 비밀번호 초기화
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ export class AuthService {
|
|||
user_type_name: true,
|
||||
partner_objid: true,
|
||||
company_code: true,
|
||||
locale: true,
|
||||
photo: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -189,6 +191,8 @@ export class AuthService {
|
|||
partnerObjid: userInfo.partner_objid || undefined,
|
||||
authName: authInfo.length > 0 ? authInfo[0].auth_name : undefined,
|
||||
companyCode: userInfo.company_code || "ILSHIN",
|
||||
photo: userInfo.photo ? `data:image/jpeg;base64,${userInfo.photo.toString('base64')}` : undefined,
|
||||
locale: userInfo.locale || "KR",
|
||||
};
|
||||
|
||||
logger.info(`사용자 정보 조회 완료: ${userId}`);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ export interface UserInfo {
|
|||
companyCode: string;
|
||||
userType?: string;
|
||||
userTypeName?: string;
|
||||
email?: string;
|
||||
photo?: string;
|
||||
locale?: string;
|
||||
isAdmin?: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -47,6 +50,8 @@ export interface PersonBean {
|
|||
partnerObjid?: string;
|
||||
authName?: string;
|
||||
companyCode?: string;
|
||||
photo?: string;
|
||||
locale?: string;
|
||||
}
|
||||
|
||||
// 로그인 결과 타입 (기존 LoginService.loginPwdCheck 반환값)
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo ===============================================
|
||||
echo Java 애플리케이션 빌드 (윈도우용)
|
||||
echo ===============================================
|
||||
echo.
|
||||
|
||||
REM Java 환경 확인
|
||||
echo [빌드 1] Java 환경 확인...
|
||||
java -version >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo [오류] Java가 설치되지 않았거나 PATH에 설정되지 않았습니다.
|
||||
echo Java 7 이상을 설치하고 PATH를 설정해주세요.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
javac -version >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo [오류] Java 컴파일러(javac)를 찾을 수 없습니다.
|
||||
echo JDK가 설치되어 있는지 확인해주세요.
|
||||
exit /b 1
|
||||
)
|
||||
echo ✓ Java 환경 확인 완료
|
||||
|
||||
REM 빌드 디렉토리 정리
|
||||
echo [빌드 2] 이전 빌드 결과 정리...
|
||||
if exist "WebContent\WEB-INF\classes" (
|
||||
rmdir /s /q "WebContent\WEB-INF\classes"
|
||||
)
|
||||
echo ✓ 이전 빌드 결과 정리 완료
|
||||
|
||||
REM 필요한 디렉토리 생성
|
||||
echo [빌드 3] 빌드 디렉토리 생성...
|
||||
if not exist "WebContent\WEB-INF\classes" mkdir "WebContent\WEB-INF\classes"
|
||||
if not exist "WebContent\WEB-INF\lib" mkdir "WebContent\WEB-INF\lib"
|
||||
if not exist "logs" mkdir "logs"
|
||||
echo ✓ 빌드 디렉토리 생성 완료
|
||||
|
||||
REM Servlet API JAR 확인
|
||||
echo [빌드 4] 라이브러리 의존성 확인...
|
||||
set "SERVLET_JAR_1=WebContent\WEB-INF\lib\javax.servlet-api-4.0.1.jar"
|
||||
set "SERVLET_JAR_2=WebContent\WEB-INF\lib\servlet-api.jar"
|
||||
|
||||
if not exist "%SERVLET_JAR_1%" if not exist "%SERVLET_JAR_2%" (
|
||||
echo [오류] Servlet API JAR 파일을 찾을 수 없습니다.
|
||||
echo 다음 중 하나가 필요합니다:
|
||||
echo - %SERVLET_JAR_1%
|
||||
echo - %SERVLET_JAR_2%
|
||||
echo.
|
||||
echo Maven Central에서 다운로드하거나 Tomcat lib 폴더에서 복사해주세요.
|
||||
exit /b 1
|
||||
)
|
||||
echo ✓ 라이브러리 의존성 확인 완료
|
||||
|
||||
REM 클래스패스 설정
|
||||
set "CLASSPATH=src;WebContent\WEB-INF\lib\*"
|
||||
echo [빌드 5] 클래스패스: %CLASSPATH%
|
||||
|
||||
REM Java 소스 파일 목록 생성
|
||||
echo [빌드 6] Java 소스 파일 검색...
|
||||
if exist java_sources.tmp del java_sources.tmp
|
||||
|
||||
set "java_count=0"
|
||||
for /r src %%f in (*.java) do (
|
||||
echo %%f >> java_sources.tmp
|
||||
set /a java_count+=1
|
||||
)
|
||||
|
||||
if %java_count% equ 0 (
|
||||
echo [경고] 컴파일할 Java 소스 파일이 없습니다.
|
||||
) else (
|
||||
echo ✓ %java_count%개의 Java 소스 파일을 찾았습니다.
|
||||
)
|
||||
|
||||
REM Java 컴파일
|
||||
if exist java_sources.tmp (
|
||||
echo [빌드 7] Java 소스 컴파일...
|
||||
javac -encoding UTF-8 -source 1.7 -target 1.7 -d WebContent\WEB-INF\classes -cp "%CLASSPATH%" @java_sources.tmp
|
||||
|
||||
if !errorlevel! neq 0 (
|
||||
echo [오류] Java 컴파일에 실패했습니다.
|
||||
if exist java_sources.tmp del java_sources.tmp
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
del java_sources.tmp
|
||||
echo ✓ Java 컴파일 완료
|
||||
)
|
||||
|
||||
REM 리소스 파일 복사
|
||||
echo [빌드 8] 리소스 파일 복사...
|
||||
set "resource_count=0"
|
||||
|
||||
for /r src %%f in (*.xml *.properties *.sql) do (
|
||||
set "source_file=%%f"
|
||||
set "relative_path=!source_file:%CD%\src\=!"
|
||||
set "target_file=WebContent\WEB-INF\classes\!relative_path!"
|
||||
|
||||
REM 대상 디렉토리 생성
|
||||
for %%d in ("!target_file!") do (
|
||||
if not exist "%%~dpd" mkdir "%%~dpd" 2>nul
|
||||
)
|
||||
|
||||
REM 파일 복사
|
||||
copy "!source_file!" "!target_file!" >nul 2>&1
|
||||
if !errorlevel! equ 0 (
|
||||
set /a resource_count+=1
|
||||
) else (
|
||||
echo [경고] 리소스 파일 복사 실패: !source_file!
|
||||
)
|
||||
)
|
||||
|
||||
echo ✓ %resource_count%개의 리소스 파일 복사 완료
|
||||
|
||||
REM 빌드 결과 요약
|
||||
echo.
|
||||
echo ===============================================
|
||||
echo ✓ 빌드 완료!
|
||||
echo ===============================================
|
||||
echo 컴파일된 클래스: WebContent\WEB-INF\classes\
|
||||
echo 라이브러리: WebContent\WEB-INF\lib\
|
||||
echo 로그 디렉토리: logs\
|
||||
echo.
|
||||
|
||||
endlocal
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# MAC OS 만 실행
|
||||
# if [[ "$(uname -s)" != "Darwin" ]]; then
|
||||
# echo "This script runs on MAC OS only."
|
||||
# echo "Current OS: $(uname -s)"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 기존 빌드 폴더 삭제 및 새로운 빌드 시작
|
||||
# ----------------------------------------------------------------------
|
||||
echo "Cleaning up old build artifacts..."
|
||||
rm -rf WebContent/WEB-INF/classes/*
|
||||
|
||||
echo "Building Java application for development..."
|
||||
|
||||
# 필요한 디렉토리 생성
|
||||
mkdir -p WebContent/WEB-INF/classes
|
||||
mkdir -p WebContent/WEB-INF/lib # lib 폴더 존재 확인
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Servlet API JAR 파일 존재 여부 확인 (단순화된 방식)
|
||||
# ----------------------------------------------------------------------
|
||||
SERVLET_API_JAR_PRIMARY_PATH="WebContent/WEB-INF/lib/javax.servlet-api-4.0.1.jar"
|
||||
SERVLET_API_JAR_ALTERNATIVE_PATH="WebContent/WEB-INF/lib/servlet-api.jar"
|
||||
|
||||
if [ ! -f "$SERVLET_API_JAR_PRIMARY_PATH" ] && [ ! -f "$SERVLET_API_JAR_ALTERNATIVE_PATH" ]; then
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
echo "ERROR: Servlet API JAR (javax.servlet-api-4.0.1.jar or servlet-api.jar)"
|
||||
echo " not found in WebContent/WEB-INF/lib/"
|
||||
echo ""
|
||||
echo "Please add the appropriate Servlet API JAR for your project."
|
||||
echo "You can typically find this JAR in a Tomcat distribution's 'lib' folder,"
|
||||
echo "or download it from a trusted source like Maven Central Repository."
|
||||
echo ""
|
||||
echo "Build cannot proceed without it."
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
exit 1
|
||||
else
|
||||
if [ -f "$SERVLET_API_JAR_PRIMARY_PATH" ]; then
|
||||
echo "DEBUG: Confirmed Servlet API JAR is present at $SERVLET_API_JAR_PRIMARY_PATH"
|
||||
elif [ -f "$SERVLET_API_JAR_ALTERNATIVE_PATH" ]; then
|
||||
echo "DEBUG: Confirmed Servlet API JAR is present at $SERVLET_API_JAR_ALTERNATIVE_PATH"
|
||||
fi
|
||||
fi
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 클래스패스 설정 (단순화된 방식)
|
||||
EFFECTIVE_CLASSPATH="src:WebContent/WEB-INF/lib/*"
|
||||
echo "DEBUG: Effective classpath for javac: $EFFECTIVE_CLASSPATH"
|
||||
|
||||
# src 폴더 내의 모든 .java 파일 컴파일
|
||||
echo "Compiling Java files for development..."
|
||||
|
||||
find src -name "*.java" -print0 | xargs -0 javac -encoding UTF-8 -source 1.7 -target 1.7 -d WebContent/WEB-INF/classes -cp "$EFFECTIVE_CLASSPATH"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Java compilation failed. Exiting script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Java compilation successful."
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# src 폴더 내의 리소스 파일(.xml, .properties 등)을 classes 폴더로 복사 (macOS 호환 방식)
|
||||
echo "Copying resource files for development..."
|
||||
find src -type f \( -name "*.xml" -o -name "*.properties" \) | while read -r filepath; do
|
||||
# 'src/' 접두사를 제거하여 상대 경로 생성
|
||||
relative_path="${filepath#src/}"
|
||||
target_file="WebContent/WEB-INF/classes/$relative_path"
|
||||
|
||||
# 대상 디렉토리 생성
|
||||
mkdir -p "$(dirname "$target_file")" || { echo "Error: Failed to create directory $(dirname "$target_file")"; exit 1; }
|
||||
|
||||
# 파일 복사
|
||||
cp "$filepath" "$target_file" || { echo "Error: Failed to copy $filepath to $target_file"; exit 1; }
|
||||
done
|
||||
|
||||
echo "Java application build complete for development."
|
||||
echo "Build process finished successfully!"
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
@echo off
|
||||
chcp 65001 > nul
|
||||
echo =================================
|
||||
echo 백엔드 개발 관리 도구
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
:menu
|
||||
echo.
|
||||
echo 선택하세요:
|
||||
echo 1. 백엔드 재시작 (완전 재빌드)
|
||||
echo 2. 백엔드 빠른 재시작 (캐시 사용)
|
||||
echo 3. 백엔드 빌드만 실행
|
||||
echo 4. 백엔드 로그 실시간 확인
|
||||
echo 5. Gradle 로컬 빌드
|
||||
echo 6. 백엔드 상태 확인
|
||||
echo 0. 종료
|
||||
echo.
|
||||
|
||||
set /p choice="번호를 입력하세요: "
|
||||
|
||||
if "%choice%"=="1" (
|
||||
call restart-backend.bat
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="2" (
|
||||
call quick-restart-backend.bat
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="3" (
|
||||
call backend-build-only.bat
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="4" (
|
||||
call backend-logs.bat
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="5" (
|
||||
call backend-gradle-build.bat
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="6" (
|
||||
echo 백엔드 컨테이너 상태:
|
||||
docker-compose -f docker-compose.springboot.yml ps backend
|
||||
echo.
|
||||
echo 아무 키나 누르세요...
|
||||
pause > nul
|
||||
goto menu
|
||||
)
|
||||
if "%choice%"=="0" (
|
||||
echo 프로그램을 종료합니다.
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
echo 잘못된 선택입니다. 다시 선택해주세요.
|
||||
goto menu
|
||||
173
dev_git_only.bat
173
dev_git_only.bat
|
|
@ -1,173 +0,0 @@
|
|||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM ----------------------------------------------------------------------
|
||||
REM 기존 빌드 폴더 삭제 및 새로운 빌드 시작
|
||||
REM ----------------------------------------------------------------------
|
||||
echo Cleaning up old build artifacts...
|
||||
if exist "WebContent\WEB-INF\classes\*" (
|
||||
rmdir /s /q "WebContent\WEB-INF\classes"
|
||||
)
|
||||
|
||||
echo Building Java application for development...
|
||||
|
||||
REM 필요한 디렉토리 생성
|
||||
if not exist "WebContent\WEB-INF\classes" mkdir "WebContent\WEB-INF\classes"
|
||||
if not exist "WebContent\WEB-INF\lib" mkdir "WebContent\WEB-INF\lib"
|
||||
|
||||
REM ----------------------------------------------------------------------
|
||||
REM Servlet API JAR 파일 존재 여부 확인
|
||||
REM ----------------------------------------------------------------------
|
||||
set "SERVLET_API_JAR_PRIMARY_PATH=WebContent\WEB-INF\lib\javax.servlet-api-4.0.1.jar"
|
||||
set "SERVLET_API_JAR_ALTERNATIVE_PATH=WebContent\WEB-INF\lib\servlet-api.jar"
|
||||
|
||||
if not exist "%SERVLET_API_JAR_PRIMARY_PATH%" if not exist "%SERVLET_API_JAR_ALTERNATIVE_PATH%" (
|
||||
echo ---------------------------------------------------------------------------------
|
||||
echo ERROR: Servlet API JAR (javax.servlet-api-4.0.1.jar or servlet-api.jar^)
|
||||
echo not found in WebContent\WEB-INF\lib\
|
||||
echo.
|
||||
echo Please add the appropriate Servlet API JAR for your project.
|
||||
echo You can typically find this JAR in a Tomcat distribution's 'lib' folder,
|
||||
echo or download it from a trusted source like Maven Central Repository.
|
||||
echo.
|
||||
echo Build cannot proceed without it.
|
||||
echo ---------------------------------------------------------------------------------
|
||||
exit /b 1
|
||||
) else (
|
||||
if exist "%SERVLET_API_JAR_PRIMARY_PATH%" (
|
||||
echo DEBUG: Confirmed Servlet API JAR is present at %SERVLET_API_JAR_PRIMARY_PATH%
|
||||
) else if exist "%SERVLET_API_JAR_ALTERNATIVE_PATH%" (
|
||||
echo DEBUG: Confirmed Servlet API JAR is present at %SERVLET_API_JAR_ALTERNATIVE_PATH%
|
||||
)
|
||||
)
|
||||
|
||||
REM ----------------------------------------------------------------------
|
||||
REM 클래스패스 설정
|
||||
set "EFFECTIVE_CLASSPATH=src;WebContent\WEB-INF\lib\*"
|
||||
echo DEBUG: Effective classpath for javac: %EFFECTIVE_CLASSPATH%
|
||||
|
||||
REM src 폴더 내의 모든 .java 파일 컴파일
|
||||
echo Compiling Java files for development...
|
||||
|
||||
REM Java 파일 목록을 임시 파일에 저장
|
||||
if exist temp_java_files.txt del temp_java_files.txt
|
||||
for /r src %%f in (*.java) do echo %%f >> temp_java_files.txt
|
||||
|
||||
if exist temp_java_files.txt (
|
||||
javac -encoding UTF-8 -source 1.7 -target 1.7 -d WebContent\WEB-INF\classes -cp "%EFFECTIVE_CLASSPATH%" @temp_java_files.txt
|
||||
if !errorlevel! neq 0 (
|
||||
echo Java compilation failed. Exiting script.
|
||||
del temp_java_files.txt
|
||||
exit /b 1
|
||||
)
|
||||
del temp_java_files.txt
|
||||
)
|
||||
|
||||
echo Java compilation successful.
|
||||
|
||||
REM ----------------------------------------------------------------------
|
||||
REM src 폴더 내의 리소스 파일(.xml, .properties 등)을 classes 폴더로 복사
|
||||
echo Copying resource files for development...
|
||||
|
||||
for /r src %%f in (*.xml *.properties) do (
|
||||
set "filepath=%%f"
|
||||
REM src\ 부분을 제거하여 상대 경로 생성
|
||||
set "relative_path=%%f"
|
||||
call set "relative_path=%%relative_path:*src\=%%"
|
||||
set "target_file=WebContent\WEB-INF\classes\!relative_path!"
|
||||
|
||||
REM 대상 디렉토리 생성
|
||||
for %%d in ("!target_file!") do (
|
||||
if not exist "%%~dpd" mkdir "%%~dpd"
|
||||
)
|
||||
|
||||
REM 파일 복사
|
||||
copy "!filepath!" "!target_file!" >nul
|
||||
if !errorlevel! neq 0 (
|
||||
echo Error: Failed to copy !filepath! to !target_file!
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
echo Java application build complete for development.
|
||||
|
||||
REM ----------------------------------------------------------------------
|
||||
REM Git 변경사항 커밋 및 푸시
|
||||
REM ----------------------------------------------------------------------
|
||||
git add .
|
||||
git commit -am "auto commit"
|
||||
|
||||
REM 현재 브랜치 확인
|
||||
for /f "tokens=*" %%i in ('git branch --show-current') do set "current_branch=%%i"
|
||||
|
||||
git push origin %current_branch%
|
||||
|
||||
REM 마스터 브랜치와 병합 여부 확인
|
||||
echo You are currently on branch: %current_branch%
|
||||
set /p "proceed_merge=Would you like to merge the current branch with main? (Y/N) [Y]: "
|
||||
if "%proceed_merge%"=="" set "proceed_merge=Y"
|
||||
|
||||
if /i "%proceed_merge%"=="Y" (
|
||||
REM 마스터 브랜치로 전환 및 업데이트
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
REM 현재 브랜치를 마스터에 병합
|
||||
git merge --no-edit %current_branch%
|
||||
|
||||
REM 병합 결과 푸시
|
||||
git push origin main
|
||||
|
||||
REM 원래 브랜치로 돌아가기
|
||||
git checkout %current_branch%
|
||||
)
|
||||
|
||||
REM 새로운 브랜치 생성
|
||||
REM 현재 날짜를 YYYYMMDD 형식으로 가져오기
|
||||
for /f "tokens=2 delims==" %%i in ('wmic OS Get localdatetime /value') do set "dt=%%i"
|
||||
set "current_date=%dt:~0,8%"
|
||||
|
||||
REM 브랜치 이름에서 날짜 부분 추출
|
||||
set "branch_date=%current_branch:~1,8%"
|
||||
|
||||
REM 현재 날짜와 브랜치 날짜가 같으면 뒤의 2자리 숫자를 증가시킴
|
||||
if "%branch_date%"=="%current_date%" (
|
||||
set "branch_number=%current_branch:~9,2%"
|
||||
set /a "branch_number=branch_number+1"
|
||||
) else (
|
||||
set "branch_number=1"
|
||||
)
|
||||
|
||||
REM 사용 가능한 브랜치 이름 찾기
|
||||
:find_branch
|
||||
if %branch_number% lss 10 (
|
||||
set "formatted_number=0%branch_number%"
|
||||
) else (
|
||||
set "formatted_number=%branch_number%"
|
||||
)
|
||||
set "new_branch=V%current_date%%formatted_number%"
|
||||
|
||||
REM 로컬과 원격에 해당 이름의 브랜치가 존재하는지 확인
|
||||
git show-ref --quiet refs/heads/%new_branch% >nul 2>&1
|
||||
if !errorlevel! equ 0 goto increment_branch
|
||||
|
||||
git ls-remote --exit-code --heads origin %new_branch% >nul 2>&1
|
||||
if !errorlevel! equ 0 goto increment_branch
|
||||
|
||||
goto create_branch
|
||||
|
||||
:increment_branch
|
||||
set /a "branch_number=branch_number+1"
|
||||
goto find_branch
|
||||
|
||||
:create_branch
|
||||
REM 새로운 브랜치 생성
|
||||
git checkout -b %new_branch%
|
||||
|
||||
REM 새로운 브랜치 푸시
|
||||
git push origin %new_branch%
|
||||
|
||||
REM 변경 사항 확인
|
||||
git status
|
||||
|
||||
endlocal
|
||||
145
dev_git_only.sh
145
dev_git_only.sh
|
|
@ -1,145 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# MAC OS 만 실행
|
||||
# if [[ "$(uname -s)" != "Darwin" ]]; then
|
||||
# echo "This script runs on MAC OS only."
|
||||
# echo "Current OS: $(uname -s)"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 기존 빌드 폴더 삭제 및 새로운 빌드 시작
|
||||
# ----------------------------------------------------------------------
|
||||
echo "Cleaning up old build artifacts..."
|
||||
rm -rf WebContent/WEB-INF/classes/*
|
||||
|
||||
echo "Building Java application for development..."
|
||||
|
||||
# 필요한 디렉토리 생성
|
||||
mkdir -p WebContent/WEB-INF/classes
|
||||
mkdir -p WebContent/WEB-INF/lib # lib 폴더 존재 확인
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Servlet API JAR 파일 존재 여부 확인 (단순화된 방식)
|
||||
# ----------------------------------------------------------------------
|
||||
SERVLET_API_JAR_PRIMARY_PATH="WebContent/WEB-INF/lib/javax.servlet-api-4.0.1.jar"
|
||||
SERVLET_API_JAR_ALTERNATIVE_PATH="WebContent/WEB-INF/lib/servlet-api.jar"
|
||||
|
||||
if [ ! -f "$SERVLET_API_JAR_PRIMARY_PATH" ] && [ ! -f "$SERVLET_API_JAR_ALTERNATIVE_PATH" ]; then
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
echo "ERROR: Servlet API JAR (javax.servlet-api-4.0.1.jar or servlet-api.jar)"
|
||||
echo " not found in WebContent/WEB-INF/lib/"
|
||||
echo ""
|
||||
echo "Please add the appropriate Servlet API JAR for your project."
|
||||
echo "You can typically find this JAR in a Tomcat distribution's 'lib' folder,"
|
||||
echo "or download it from a trusted source like Maven Central Repository."
|
||||
echo ""
|
||||
echo "Build cannot proceed without it."
|
||||
echo "---------------------------------------------------------------------------------"
|
||||
exit 1
|
||||
else
|
||||
if [ -f "$SERVLET_API_JAR_PRIMARY_PATH" ]; then
|
||||
echo "DEBUG: Confirmed Servlet API JAR is present at $SERVLET_API_JAR_PRIMARY_PATH"
|
||||
elif [ -f "$SERVLET_API_JAR_ALTERNATIVE_PATH" ]; then
|
||||
echo "DEBUG: Confirmed Servlet API JAR is present at $SERVLET_API_JAR_ALTERNATIVE_PATH"
|
||||
fi
|
||||
fi
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# 클래스패스 설정 (단순화된 방식)
|
||||
EFFECTIVE_CLASSPATH="src:WebContent/WEB-INF/lib/*"
|
||||
echo "DEBUG: Effective classpath for javac: $EFFECTIVE_CLASSPATH"
|
||||
|
||||
# src 폴더 내의 모든 .java 파일 컴파일
|
||||
echo "Compiling Java files for development..."
|
||||
|
||||
find src -name "*.java" -print0 | xargs -0 javac -encoding UTF-8 -source 1.7 -target 1.7 -d WebContent/WEB-INF/classes -cp "$EFFECTIVE_CLASSPATH"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Java compilation failed. Exiting script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Java compilation successful."
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# src 폴더 내의 리소스 파일(.xml, .properties 등)을 classes 폴더로 복사 (macOS 호환 방식)
|
||||
echo "Copying resource files for development..."
|
||||
find src -type f \( -name "*.xml" -o -name "*.properties" \) | while read -r filepath; do
|
||||
# 'src/' 접두사를 제거하여 상대 경로 생성
|
||||
relative_path="${filepath#src/}"
|
||||
target_file="WebContent/WEB-INF/classes/$relative_path"
|
||||
|
||||
# 대상 디렉토리 생성
|
||||
mkdir -p "$(dirname "$target_file")" || { echo "Error: Failed to create directory $(dirname "$target_file")"; exit 1; }
|
||||
|
||||
# 파일 복사
|
||||
cp "$filepath" "$target_file" || { echo "Error: Failed to copy $filepath to $target_file"; exit 1; }
|
||||
done
|
||||
# 파이프라인의 마지막 명령어의 종료 코드를 확인하기 위해 추가적인 검사가 필요할 수 있으나,
|
||||
# while 루프 내에서 오류 발생 시 exit 하므로, 이 지점에 도달하면 성공으로 간주합니다.
|
||||
# 만약 find가 아무 파일도 찾지 못해도 오류가 아니어야 하므로 $? 검사는 주의해야 합니다.
|
||||
|
||||
echo "Java application build complete for development."
|
||||
# ----------------------------------------------------------------------
|
||||
# 빌드 종료
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# Git 변경사항 커밋 및 푸시
|
||||
git add .
|
||||
git commit -am "auto commit"
|
||||
current_branch=$(git branch --show-current)
|
||||
git push origin $current_branch
|
||||
# 마스터 브랜치와 병합 여부 확인
|
||||
echo "You are currently on branch: $current_branch"
|
||||
echo "Would you like to merge the current branch with main? (Y/N) [Y]"
|
||||
read proceed_merge
|
||||
proceed_merge=${proceed_merge:-Y}
|
||||
if [ "$proceed_merge" == "Y" ] || [ "$proceed_merge" == "y" ]; then
|
||||
# 마스터 브랜치로 전환 및 업데이트
|
||||
git checkout main
|
||||
git pull origin main
|
||||
# 현재 브랜치를 마스터에 병합
|
||||
git merge --no-edit $current_branch
|
||||
# 병합 결과 푸시
|
||||
git push origin main
|
||||
# 원래 브랜치로 돌아가기
|
||||
git checkout $current_branch
|
||||
fi
|
||||
# 새로운 브랜치 생성
|
||||
# 현재 날짜를 YYYYMMDD 형식으로 가져오기
|
||||
current_date=$(date +'%Y%m%d')
|
||||
# 브랜치 이름에서 날짜 부분 추출
|
||||
branch_date=${current_branch:1:8}
|
||||
# 현재 날짜와 브랜치 날짜가 같으면 뒤의 2자리 숫자를 증가시킴
|
||||
if [ "$branch_date" == "$current_date" ]; then
|
||||
# 브랜치 이름에서 뒤의 2자리 숫자 추출
|
||||
branch_number=${current_branch:9:2}
|
||||
# 숫자를 10진수로 변환하고 1 증가시킴
|
||||
branch_number=$((10#$branch_number + 1))
|
||||
else
|
||||
# 날짜가 다르면 01부터 시작
|
||||
branch_number=1
|
||||
fi
|
||||
# 사용 가능한 브랜치 이름 찾기
|
||||
while true; do
|
||||
# 2자리 숫자로 포맷팅
|
||||
formatted_number=$(printf "%02d" $branch_number)
|
||||
new_branch="V${current_date}${formatted_number}"
|
||||
|
||||
# 로컬과 원격에 해당 이름의 브랜치가 존재하는지 확인
|
||||
if ! git show-ref --quiet refs/heads/$new_branch && \
|
||||
! git ls-remote --exit-code --heads origin $new_branch > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
|
||||
# 존재한다면 숫자 증가
|
||||
branch_number=$((branch_number + 1))
|
||||
done
|
||||
# 새로운 브랜치 생성
|
||||
git checkout -b $new_branch
|
||||
# 새로운 브랜치 푸시 (원격 브랜치로 푸시하려면 git push origin $new_branch 실행)
|
||||
git push origin $new_branch
|
||||
# 변경 사항 확인
|
||||
git status
|
||||
# .env-dev 파일을 .env로 복사하여 원래 상태로 복원
|
||||
# docker-compose -f docker-compose-dev.yml up -d --build
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Node.js 백엔드
|
||||
backend:
|
||||
build:
|
||||
context: ./backend-node
|
||||
dockerfile: Dockerfile
|
||||
container_name: pms-backend-linux
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- PORT=8080
|
||||
- DATABASE_URL=postgresql://postgres:ph0909!!@39.117.244.52:11132/plm
|
||||
- JWT_SECRET=ilshin-plm-super-secret-jwt-key-2024
|
||||
- JWT_EXPIRES_IN=24h
|
||||
- CORS_ORIGIN=http://localhost:9771
|
||||
- CORS_CREDENTIALS=true
|
||||
- LOG_LEVEL=debug
|
||||
volumes:
|
||||
- ./backend-node:/app
|
||||
- /app/node_modules
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
networks:
|
||||
pms-network:
|
||||
driver: bridge
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
plm:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfile.dev
|
||||
container_name: plm
|
||||
ports:
|
||||
- "9090:8080"
|
||||
environment:
|
||||
CATALINA_OPTS: >-
|
||||
-DDB_URL=jdbc:postgresql://39.117.244.52:11132/plm
|
||||
-DDB_USERNAME=postgres
|
||||
-DDB_PASSWORD=ph0909!!
|
||||
volumes:
|
||||
- plm-project_data:/data_storage
|
||||
- plm-app_data:/path/inside/container
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
plm-project_data:
|
||||
plm-app_data:
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Next.js 프론트엔드만
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: pms-frontend-win
|
||||
ports:
|
||||
- "9771:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:8080/api
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
pms-network:
|
||||
driver: bridge
|
||||
external: true
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Spring Boot 백엔드
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: pms-backend
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- SPRING_PROFILES_ACTIVE=dev
|
||||
- SPRING_DATASOURCE_URL=jdbc:postgresql://39.117.244.52:11132/plm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Seoul
|
||||
- SPRING_DATASOURCE_USERNAME=postgres
|
||||
- SPRING_DATASOURCE_PASSWORD=ph0909!!
|
||||
- LANG=ko_KR.UTF-8
|
||||
- LANGUAGE=ko_KR:ko
|
||||
- LC_ALL=ko_KR.UTF-8
|
||||
- TZ=Asia/Seoul
|
||||
- JAVA_OPTS=-Xms512m -Xmx1024m -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Seoul -Djava.awt.headless=true
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/api/actuator/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
# Next.js 프론트엔드
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: pms-frontend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:8080/api
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
networks:
|
||||
pms-network:
|
||||
driver: bridge
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
services:
|
||||
# 백엔드 서비스 (기존)
|
||||
plm-app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.win
|
||||
platforms:
|
||||
- linux/amd64
|
||||
container_name: plm-windows
|
||||
ports:
|
||||
- "9090:8080"
|
||||
environment:
|
||||
- CATALINA_OPTS=-DDB_URL=jdbc:postgresql://39.117.244.52:11132/plm -DDB_USERNAME=postgres -DDB_PASSWORD=ph0909!! -Xms512m -Xmx1024m
|
||||
- TZ=Asia/Seoul
|
||||
- APP_ENV=development
|
||||
- LOG_LEVEL=INFO
|
||||
- DB_HOST=39.117.244.52
|
||||
- DB_PORT=11132
|
||||
- DB_NAME=plm
|
||||
- DB_USERNAME=postgres
|
||||
- DB_PASSWORD=ph0909!!
|
||||
volumes:
|
||||
- plm-win-project:/data_storage
|
||||
- plm-win-app:/app_data
|
||||
- ./logs:/usr/local/tomcat/logs
|
||||
- ./WebContent:/usr/local/tomcat/webapps/ROOT
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- plm-network
|
||||
|
||||
# 프론트엔드 서비스 (새로 추가)
|
||||
plm-frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: plm-frontend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- TZ=Asia/Seoul
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:9090
|
||||
- WATCHPACK_POLLING=true
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
depends_on:
|
||||
- plm-app
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- plm-network
|
||||
|
||||
volumes:
|
||||
plm-win-project:
|
||||
driver: local
|
||||
plm-win-app:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
plm-network:
|
||||
driver: bridge
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# 개발용 백엔드 Dockerfile
|
||||
FROM node:20-bookworm-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 시스템 패키지 설치
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends openssl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# package.json 복사 및 의존성 설치 (개발 의존성 포함)
|
||||
COPY package*.json ./
|
||||
RUN npm ci --prefer-offline --no-audit
|
||||
|
||||
# 소스 코드는 볼륨 마운트로 처리
|
||||
# Prisma 클라이언트 생성용 스키마만 복사
|
||||
COPY prisma ./prisma
|
||||
RUN npx prisma generate
|
||||
|
||||
# 포트 노출
|
||||
EXPOSE 8080
|
||||
|
||||
# 개발 서버 시작 (nodemon 사용)
|
||||
CMD ["npm", "run", "dev"]
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Node.js 백엔드
|
||||
backend:
|
||||
build:
|
||||
context: ./backend-node
|
||||
dockerfile: Dockerfile
|
||||
context: ../../backend-node
|
||||
dockerfile: ../docker/dev/backend.Dockerfile
|
||||
container_name: pms-backend-mac
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
|
@ -18,9 +16,9 @@ services:
|
|||
- CORS_ORIGIN=http://localhost:9771
|
||||
- CORS_CREDENTIALS=true
|
||||
- LOG_LEVEL=debug
|
||||
# volumes:
|
||||
# - ./backend-node:/app # 개발 모드가 아닐 때는 이 볼륨 마운트를 비활성화
|
||||
# - /app/node_modules
|
||||
volumes:
|
||||
- ../../backend-node:/app # 개발 모드: 코드 변경 시 자동 반영
|
||||
- /app/node_modules
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Next.js 프론트엔드만
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
context: ../../frontend
|
||||
dockerfile: ../docker/dev/frontend.Dockerfile
|
||||
container_name: pms-frontend-mac
|
||||
ports:
|
||||
- "9771:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:8080/api
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- ../../frontend:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
networks:
|
||||
|
|
@ -7,8 +7,8 @@ WORKDIR /app
|
|||
# package.json과 package-lock.json 복사
|
||||
COPY package*.json ./
|
||||
|
||||
# 의존성 설치 (개발 의존성 포함)
|
||||
RUN npm ci
|
||||
# 의존성 설치 (개발 의존성 포함) - 최적화 옵션 추가
|
||||
RUN npm ci --prefer-offline --no-audit
|
||||
|
||||
# 소스 코드 복사
|
||||
COPY . .
|
||||
|
|
@ -12,7 +12,7 @@ RUN apt-get update \
|
|||
# Dependencies stage (install deps and generate Prisma client)
|
||||
FROM base AS deps
|
||||
COPY package*.json ./
|
||||
RUN npm ci --omit=dev && npm cache clean --force
|
||||
RUN npm ci --omit=dev --prefer-offline --no-audit && npm cache clean --force
|
||||
# Copy prisma schema and generate client (glibc target will be detected)
|
||||
COPY prisma ./prisma
|
||||
ENV PRISMA_SKIP_POSTINSTALL_GENERATE=true
|
||||
|
|
@ -22,21 +22,16 @@ RUN npx prisma generate
|
|||
FROM node:20-bookworm-slim AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci && npm cache clean --force
|
||||
RUN npm ci --prefer-offline --no-audit && npm cache clean --force
|
||||
COPY tsconfig.json ./
|
||||
COPY src ./src
|
||||
COPY prisma ./prisma
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
|
||||
# Runtime image
|
||||
FROM node:20-bookworm-slim AS runner
|
||||
WORKDIR /app
|
||||
# Runtime image - base 이미지 재사용으로 중복 설치 제거
|
||||
FROM base AS runner
|
||||
ENV NODE_ENV=production
|
||||
# Ensure OpenSSL present
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends openssl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create non-root user
|
||||
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
|
||||
|
|
@ -1,26 +1,22 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Node.js 백엔드
|
||||
# Node.js 백엔드 (운영용)
|
||||
backend:
|
||||
build:
|
||||
context: ./backend-node
|
||||
dockerfile: Dockerfile
|
||||
container_name: pms-backend-win
|
||||
context: ../../backend-node
|
||||
dockerfile: ../docker/prod/backend.Dockerfile # 운영용 Dockerfile
|
||||
container_name: pms-backend-prod
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- NODE_ENV=production
|
||||
- PORT=8080
|
||||
- DATABASE_URL=postgresql://postgres:ph0909!!@39.117.244.52:11132/plm
|
||||
- JWT_SECRET=ilshin-plm-super-secret-jwt-key-2024
|
||||
- JWT_EXPIRES_IN=24h
|
||||
- CORS_ORIGIN=http://localhost:9771
|
||||
- CORS_CREDENTIALS=true
|
||||
- LOG_LEVEL=debug
|
||||
volumes:
|
||||
- ./backend-node:/app
|
||||
- /app/node_modules
|
||||
- LOG_LEVEL=info
|
||||
# 운영용에서는 볼륨 마운트 없음 (보안상 이유)
|
||||
networks:
|
||||
- pms-network
|
||||
restart: unless-stopped
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Next.js 프론트엔드만
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
context: ../../frontend
|
||||
dockerfile: ../docker/prod/frontend.Dockerfile
|
||||
args:
|
||||
- NEXT_PUBLIC_API_URL=http://192.168.0.70:8080/api
|
||||
container_name: pms-frontend-linux
|
||||
|
|
@ -24,4 +22,4 @@ services:
|
|||
networks:
|
||||
pms-network:
|
||||
driver: bridge
|
||||
external: true
|
||||
external: true
|
||||
|
|
@ -194,7 +194,7 @@ export function AppLayout({ children }: AppLayoutProps) {
|
|||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const { user, logout, refreshUserData } = useAuth();
|
||||
const { userMenus, adminMenus, loading } = useMenu();
|
||||
const { userMenus, adminMenus, loading, refreshMenus } = useMenu();
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [expandedMenus, setExpandedMenus] = useState<Set<string>>(new Set());
|
||||
|
||||
|
|
@ -204,6 +204,7 @@ export function AppLayout({ children }: AppLayoutProps) {
|
|||
formData,
|
||||
selectedImage,
|
||||
isSaving,
|
||||
departments,
|
||||
alertModal,
|
||||
closeAlert,
|
||||
openProfileModal,
|
||||
|
|
@ -212,7 +213,7 @@ export function AppLayout({ children }: AppLayoutProps) {
|
|||
selectImage,
|
||||
removeImage,
|
||||
saveProfile,
|
||||
} = useProfile(user, refreshUserData);
|
||||
} = useProfile(user, refreshUserData, refreshMenus);
|
||||
|
||||
// 현재 경로에 따라 어드민 모드인지 판단
|
||||
const isAdminMode = pathname.startsWith("/admin");
|
||||
|
|
@ -394,6 +395,7 @@ export function AppLayout({ children }: AppLayoutProps) {
|
|||
formData={formData}
|
||||
selectedImage={selectedImage}
|
||||
isSaving={isSaving}
|
||||
departments={departments}
|
||||
alertModal={alertModal}
|
||||
onClose={closeProfileModal}
|
||||
onFormChange={updateFormData}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ interface ProfileModalProps {
|
|||
formData: ProfileFormData;
|
||||
selectedImage: string;
|
||||
isSaving: boolean;
|
||||
departments: Array<{
|
||||
deptCode: string;
|
||||
deptName: string;
|
||||
}>;
|
||||
alertModal: {
|
||||
isOpen: boolean;
|
||||
title: string;
|
||||
|
|
@ -76,6 +80,7 @@ export function ProfileModal({
|
|||
formData,
|
||||
selectedImage,
|
||||
isSaving,
|
||||
departments,
|
||||
alertModal,
|
||||
onClose,
|
||||
onFormChange,
|
||||
|
|
@ -99,12 +104,14 @@ export function ProfileModal({
|
|||
<Avatar className="h-24 w-24">
|
||||
{selectedImage ? (
|
||||
<AvatarImage src={selectedImage} alt="프로필 사진 미리보기" />
|
||||
) : user?.photo ? (
|
||||
<AvatarImage src={user.photo} alt="기존 프로필 사진" />
|
||||
) : (
|
||||
<AvatarFallback className="text-lg">{formData.userName?.substring(0, 1) || "U"}</AvatarFallback>
|
||||
)}
|
||||
</Avatar>
|
||||
|
||||
{selectedImage && (
|
||||
{(selectedImage || user?.photo) && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
|
|
@ -171,12 +178,24 @@ export function ProfileModal({
|
|||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="deptName">부서</Label>
|
||||
<Input
|
||||
id="deptName"
|
||||
value={formData.deptName}
|
||||
onChange={(e) => onFormChange("deptName", e.target.value)}
|
||||
placeholder="부서를 입력하세요"
|
||||
/>
|
||||
<Select value={formData.deptName} onValueChange={(value) => onFormChange("deptName", value)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="부서 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Array.isArray(departments) && departments.length > 0 ? (
|
||||
departments.map((department) => (
|
||||
<SelectItem key={department.deptCode} value={department.deptName}>
|
||||
{department.deptName}
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
<SelectItem value="no-data" disabled>
|
||||
부서 정보가 없습니다
|
||||
</SelectItem>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="positionName">직급</Label>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ interface UserInfo {
|
|||
userTypeName?: string;
|
||||
authName?: string;
|
||||
partnerCd?: string;
|
||||
locale?: string;
|
||||
isAdmin: boolean;
|
||||
sabun?: string;
|
||||
photo?: string | null;
|
||||
|
|
|
|||
|
|
@ -180,5 +180,6 @@ export const useMenu = (user: any, authLoading: boolean) => {
|
|||
isMenuLoading: menuState.isLoading,
|
||||
handleMenuClick,
|
||||
toggleMenu,
|
||||
refreshMenus: loadMenuData, // 메뉴 새로고침 함수 추가
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useCallback } from "react";
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { ProfileFormData, ProfileModalState } from "@/types/profile";
|
||||
import { LAYOUT_CONFIG, MESSAGES } from "@/constants/layout";
|
||||
import { apiCall } from "@/lib/api/client";
|
||||
|
||||
// 알림 모달 상태 타입
|
||||
interface AlertModalState {
|
||||
|
|
@ -15,7 +16,7 @@ interface AlertModalState {
|
|||
/**
|
||||
* 프로필 관련 비즈니스 로직을 관리하는 커스텀 훅
|
||||
*/
|
||||
export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
||||
export const useProfile = (user: any, refreshUserData: () => Promise<void>, refreshMenus?: () => Promise<void>) => {
|
||||
// 상태 관리
|
||||
const [modalState, setModalState] = useState<ProfileModalState>({
|
||||
isOpen: false,
|
||||
|
|
@ -39,6 +40,14 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
|||
type: "info",
|
||||
});
|
||||
|
||||
// 부서 목록 상태
|
||||
const [departments, setDepartments] = useState<
|
||||
Array<{
|
||||
deptCode: string;
|
||||
deptName: string;
|
||||
}>
|
||||
>([]);
|
||||
|
||||
// 알림 모달 표시 함수
|
||||
const showAlert = useCallback((title: string, message: string, type: "success" | "error" | "info" = "info") => {
|
||||
setAlertModal({
|
||||
|
|
@ -54,11 +63,33 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
|||
setAlertModal((prev) => ({ ...prev, isOpen: false }));
|
||||
}, []);
|
||||
|
||||
// 부서 목록 로드 함수
|
||||
const loadDepartments = useCallback(async () => {
|
||||
try {
|
||||
const response = await apiCall("GET", "/admin/departments");
|
||||
if (response.success && response.data) {
|
||||
setDepartments(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("부서 목록 로드 실패:", error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 프로필 모달 열기
|
||||
*/
|
||||
const openProfileModal = useCallback(() => {
|
||||
if (user) {
|
||||
console.log("🔍 프로필 모달 열기 - 사용자 정보:", {
|
||||
userName: user.userName,
|
||||
email: user.email,
|
||||
deptName: user.deptName,
|
||||
locale: user.locale,
|
||||
});
|
||||
|
||||
// 부서 목록 로드
|
||||
loadDepartments();
|
||||
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
isOpen: true,
|
||||
|
|
@ -67,14 +98,14 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
|||
email: user.email || "",
|
||||
deptName: user.deptName || "",
|
||||
positionName: user.positionName || "",
|
||||
locale: user.locale || "",
|
||||
locale: user.locale || "KR", // 기본값을 KR로 설정
|
||||
},
|
||||
selectedImage: user.photo || "",
|
||||
selectedFile: null,
|
||||
isSaving: false,
|
||||
}));
|
||||
}
|
||||
}, [user]);
|
||||
}, [user, loadDepartments]);
|
||||
|
||||
/**
|
||||
* 프로필 모달 닫기
|
||||
|
|
@ -181,48 +212,51 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
|||
photoData = modalState.selectedImage;
|
||||
}
|
||||
|
||||
// 사용자 정보 저장
|
||||
const userSaveData = {
|
||||
userId: user.userId,
|
||||
// 사용자 정보 저장 데이터 준비
|
||||
const updateData = {
|
||||
userName: modalState.formData.userName,
|
||||
email: modalState.formData.email,
|
||||
deptName: modalState.formData.deptName,
|
||||
positionName: modalState.formData.positionName,
|
||||
locale: modalState.formData.locale,
|
||||
photo: photoData,
|
||||
photo: photoData !== user.photo ? photoData : undefined, // 변경된 경우만 전송
|
||||
};
|
||||
|
||||
console.log("사용자 정보 저장 요청:", userSaveData);
|
||||
console.log("프로필 업데이트 요청:", updateData);
|
||||
|
||||
const userResponse = await fetch(`${LAYOUT_CONFIG.API_BASE_URL}${LAYOUT_CONFIG.ENDPOINTS.USER_SAVE}`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(userSaveData),
|
||||
});
|
||||
// API 호출 (JWT 토큰 자동 포함)
|
||||
const response = await apiCall("PUT", "/admin/profile", updateData);
|
||||
|
||||
if (userResponse.ok) {
|
||||
const userResult = await userResponse.json();
|
||||
console.log("사용자 정보 저장 응답:", userResult);
|
||||
console.log("프로필 업데이트 응답:", response);
|
||||
|
||||
if (userResult.result) {
|
||||
// 성공: 세션 정보 새로고침
|
||||
await refreshUserData();
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
selectedFile: null,
|
||||
isOpen: false,
|
||||
}));
|
||||
showAlert("저장 완료", MESSAGES.PROFILE_SAVE_SUCCESS, "success");
|
||||
} else {
|
||||
throw new Error(userResult.msg || "사용자 정보 저장 실패");
|
||||
if (response.result) {
|
||||
// locale이 변경된 경우 전역 변수와 localStorage 업데이트
|
||||
const localeChanged = modalState.formData.locale && modalState.formData.locale !== user.locale;
|
||||
if (localeChanged) {
|
||||
if (typeof window !== "undefined") {
|
||||
// 전역 변수 업데이트
|
||||
(window as any).__GLOBAL_USER_LANG = modalState.formData.locale;
|
||||
// localStorage 업데이트
|
||||
localStorage.setItem("userLocale", modalState.formData.locale);
|
||||
console.log("🌍 사용자 locale 업데이트:", modalState.formData.locale);
|
||||
}
|
||||
}
|
||||
|
||||
// 성공: 사용자 정보 새로고침
|
||||
await refreshUserData();
|
||||
|
||||
// locale이 변경된 경우 메뉴도 새로고침
|
||||
if (localeChanged && refreshMenus) {
|
||||
console.log("🔄 locale 변경으로 인한 메뉴 새로고침 시작");
|
||||
await refreshMenus();
|
||||
console.log("✅ 메뉴 새로고침 완료");
|
||||
}
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
selectedFile: null,
|
||||
isOpen: false,
|
||||
}));
|
||||
showAlert("저장 완료", "프로필이 성공적으로 업데이트되었습니다.", "success");
|
||||
} else {
|
||||
const errorText = await userResponse.text();
|
||||
console.error("API 응답 오류:", errorText);
|
||||
throw new Error(`사용자 정보 저장 실패: ${userResponse.status} ${userResponse.statusText}`);
|
||||
throw new Error(response.message || "프로필 업데이트 실패");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("프로필 저장 실패:", error);
|
||||
|
|
@ -239,6 +273,7 @@ export const useProfile = (user: any, refreshUserData: () => Promise<void>) => {
|
|||
formData: modalState.formData,
|
||||
selectedImage: modalState.selectedImage,
|
||||
isSaving: modalState.isSaving,
|
||||
departments,
|
||||
|
||||
// 알림 모달 상태
|
||||
alertModal,
|
||||
|
|
|
|||
|
|
@ -1,324 +0,0 @@
|
|||
|
||||
SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
|
||||
|
||||
Commands marked with * may be preceded by a number, _N.
|
||||
Notes in parentheses indicate the behavior if _N is given.
|
||||
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
|
||||
|
||||
h H Display this help.
|
||||
q :q Q :Q ZZ Exit.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
MMOOVVIINNGG
|
||||
|
||||
e ^E j ^N CR * Forward one line (or _N lines).
|
||||
y ^Y k ^K ^P * Backward one line (or _N lines).
|
||||
ESC-j * Forward one file line (or _N file lines).
|
||||
ESC-k * Backward one file line (or _N file lines).
|
||||
f ^F ^V SPACE * Forward one window (or _N lines).
|
||||
b ^B ESC-v * Backward one window (or _N lines).
|
||||
z * Forward one window (and set window to _N).
|
||||
w * Backward one window (and set window to _N).
|
||||
ESC-SPACE * Forward one window, but don't stop at end-of-file.
|
||||
ESC-b * Backward one window, but don't stop at beginning-of-file.
|
||||
d ^D * Forward one half-window (and set half-window to _N).
|
||||
u ^U * Backward one half-window (and set half-window to _N).
|
||||
ESC-) RightArrow * Right one half screen width (or _N positions).
|
||||
ESC-( LeftArrow * Left one half screen width (or _N positions).
|
||||
ESC-} ^RightArrow Right to last column displayed.
|
||||
ESC-{ ^LeftArrow Left to first column.
|
||||
F Forward forever; like "tail -f".
|
||||
ESC-F Like F but stop when search pattern is found.
|
||||
r ^R ^L Repaint screen.
|
||||
R Repaint screen, discarding buffered input.
|
||||
---------------------------------------------------
|
||||
Default "window" is the screen height.
|
||||
Default "half-window" is half of the screen height.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
SSEEAARRCCHHIINNGG
|
||||
|
||||
/_p_a_t_t_e_r_n * Search forward for (_N-th) matching line.
|
||||
?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line.
|
||||
n * Repeat previous search (for _N-th occurrence).
|
||||
N * Repeat previous search in reverse direction.
|
||||
ESC-n * Repeat previous search, spanning files.
|
||||
ESC-N * Repeat previous search, reverse dir. & spanning files.
|
||||
^O^N ^On * Search forward for (_N-th) OSC8 hyperlink.
|
||||
^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink.
|
||||
^O^L ^Ol Jump to the currently selected OSC8 hyperlink.
|
||||
ESC-u Undo (toggle) search highlighting.
|
||||
ESC-U Clear search highlighting.
|
||||
&_p_a_t_t_e_r_n * Display only matching lines.
|
||||
---------------------------------------------------
|
||||
Search is case-sensitive unless changed with -i or -I.
|
||||
A search pattern may begin with one or more of:
|
||||
^N or ! Search for NON-matching lines.
|
||||
^E or * Search multiple files (pass thru END OF FILE).
|
||||
^F or @ Start search at FIRST file (for /) or last file (for ?).
|
||||
^K Highlight matches, but don't move (KEEP position).
|
||||
^R Don't use REGULAR EXPRESSIONS.
|
||||
^S _n Search for match in _n-th parenthesized subpattern.
|
||||
^W WRAP search if no match found.
|
||||
^L Enter next character literally into pattern.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
JJUUMMPPIINNGG
|
||||
|
||||
g < ESC-< * Go to first line in file (or line _N).
|
||||
G > ESC-> * Go to last line in file (or line _N).
|
||||
p % * Go to beginning of file (or _N percent into file).
|
||||
t * Go to the (_N-th) next tag.
|
||||
T * Go to the (_N-th) previous tag.
|
||||
{ ( [ * Find close bracket } ) ].
|
||||
} ) ] * Find open bracket { ( [.
|
||||
ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>.
|
||||
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>.
|
||||
---------------------------------------------------
|
||||
Each "find close bracket" command goes forward to the close bracket
|
||||
matching the (_N-th) open bracket in the top line.
|
||||
Each "find open bracket" command goes backward to the open bracket
|
||||
matching the (_N-th) close bracket in the bottom line.
|
||||
|
||||
m_<_l_e_t_t_e_r_> Mark the current top line with <letter>.
|
||||
M_<_l_e_t_t_e_r_> Mark the current bottom line with <letter>.
|
||||
'_<_l_e_t_t_e_r_> Go to a previously marked position.
|
||||
'' Go to the previous position.
|
||||
^X^X Same as '.
|
||||
ESC-m_<_l_e_t_t_e_r_> Clear a mark.
|
||||
---------------------------------------------------
|
||||
A mark is any upper-case or lower-case letter.
|
||||
Certain marks are predefined:
|
||||
^ means beginning of the file
|
||||
$ means end of the file
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
CCHHAANNGGIINNGG FFIILLEESS
|
||||
|
||||
:e [_f_i_l_e] Examine a new file.
|
||||
^X^V Same as :e.
|
||||
:n * Examine the (_N-th) next file from the command line.
|
||||
:p * Examine the (_N-th) previous file from the command line.
|
||||
:x * Examine the first (or _N-th) file from the command line.
|
||||
^O^O Open the currently selected OSC8 hyperlink.
|
||||
:d Delete the current file from the command line list.
|
||||
= ^G :f Print current file name.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS
|
||||
|
||||
-_<_f_l_a_g_> Toggle a command line option [see OPTIONS below].
|
||||
--_<_n_a_m_e_> Toggle a command line option, by name.
|
||||
__<_f_l_a_g_> Display the setting of a command line option.
|
||||
___<_n_a_m_e_> Display the setting of an option, by name.
|
||||
+_c_m_d Execute the less cmd each time a new file is examined.
|
||||
|
||||
!_c_o_m_m_a_n_d Execute the shell command with $SHELL.
|
||||
#_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt.
|
||||
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
|
||||
s _f_i_l_e Save input to a file.
|
||||
v Edit the current file with $VISUAL or $EDITOR.
|
||||
V Print version number of "less".
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
OOPPTTIIOONNSS
|
||||
|
||||
Most options may be changed either on the command line,
|
||||
or from within less by using the - or -- command.
|
||||
Options may be given in one of two forms: either a single
|
||||
character preceded by a -, or a name preceded by --.
|
||||
|
||||
-? ........ --help
|
||||
Display help (from command line).
|
||||
-a ........ --search-skip-screen
|
||||
Search skips current screen.
|
||||
-A ........ --SEARCH-SKIP-SCREEN
|
||||
Search starts just after target line.
|
||||
-b [_N] .... --buffers=[_N]
|
||||
Number of buffers.
|
||||
-B ........ --auto-buffers
|
||||
Don't automatically allocate buffers for pipes.
|
||||
-c ........ --clear-screen
|
||||
Repaint by clearing rather than scrolling.
|
||||
-d ........ --dumb
|
||||
Dumb terminal.
|
||||
-D xx_c_o_l_o_r . --color=xx_c_o_l_o_r
|
||||
Set screen colors.
|
||||
-e -E .... --quit-at-eof --QUIT-AT-EOF
|
||||
Quit at end of file.
|
||||
-f ........ --force
|
||||
Force open non-regular files.
|
||||
-F ........ --quit-if-one-screen
|
||||
Quit if entire file fits on first screen.
|
||||
-g ........ --hilite-search
|
||||
Highlight only last match for searches.
|
||||
-G ........ --HILITE-SEARCH
|
||||
Don't highlight any matches for searches.
|
||||
-h [_N] .... --max-back-scroll=[_N]
|
||||
Backward scroll limit.
|
||||
-i ........ --ignore-case
|
||||
Ignore case in searches that do not contain uppercase.
|
||||
-I ........ --IGNORE-CASE
|
||||
Ignore case in all searches.
|
||||
-j [_N] .... --jump-target=[_N]
|
||||
Screen position of target lines.
|
||||
-J ........ --status-column
|
||||
Display a status column at left edge of screen.
|
||||
-k _f_i_l_e ... --lesskey-file=_f_i_l_e
|
||||
Use a compiled lesskey file.
|
||||
-K ........ --quit-on-intr
|
||||
Exit less in response to ctrl-C.
|
||||
-L ........ --no-lessopen
|
||||
Ignore the LESSOPEN environment variable.
|
||||
-m -M .... --long-prompt --LONG-PROMPT
|
||||
Set prompt style.
|
||||
-n ......... --line-numbers
|
||||
Suppress line numbers in prompts and messages.
|
||||
-N ......... --LINE-NUMBERS
|
||||
Display line number at start of each line.
|
||||
-o [_f_i_l_e] .. --log-file=[_f_i_l_e]
|
||||
Copy to log file (standard input only).
|
||||
-O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e]
|
||||
Copy to log file (unconditionally overwrite).
|
||||
-p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n]
|
||||
Start at pattern (from command line).
|
||||
-P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t]
|
||||
Define new prompt.
|
||||
-q -Q .... --quiet --QUIET --silent --SILENT
|
||||
Quiet the terminal bell.
|
||||
-r -R .... --raw-control-chars --RAW-CONTROL-CHARS
|
||||
Output "raw" control characters.
|
||||
-s ........ --squeeze-blank-lines
|
||||
Squeeze multiple blank lines.
|
||||
-S ........ --chop-long-lines
|
||||
Chop (truncate) long lines rather than wrapping.
|
||||
-t _t_a_g .... --tag=[_t_a_g]
|
||||
Find a tag.
|
||||
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
|
||||
Use an alternate tags file.
|
||||
-u -U .... --underline-special --UNDERLINE-SPECIAL
|
||||
Change handling of backspaces, tabs and carriage returns.
|
||||
-V ........ --version
|
||||
Display the version number of "less".
|
||||
-w ........ --hilite-unread
|
||||
Highlight first new line after forward-screen.
|
||||
-W ........ --HILITE-UNREAD
|
||||
Highlight first new line after any forward movement.
|
||||
-x [_N[,...]] --tabs=[_N[,...]]
|
||||
Set tab stops.
|
||||
-X ........ --no-init
|
||||
Don't use termcap init/deinit strings.
|
||||
-y [_N] .... --max-forw-scroll=[_N]
|
||||
Forward scroll limit.
|
||||
-z [_N] .... --window=[_N]
|
||||
Set size of window.
|
||||
-" [_c[_c]] . --quotes=[_c[_c]]
|
||||
Set shell quote characters.
|
||||
-~ ........ --tilde
|
||||
Don't display tildes after end of file.
|
||||
-# [_N] .... --shift=[_N]
|
||||
Set horizontal scroll amount (0 = one half screen width).
|
||||
|
||||
--exit-follow-on-close
|
||||
Exit F command on a pipe when writer closes pipe.
|
||||
--file-size
|
||||
Automatically determine the size of the input file.
|
||||
--follow-name
|
||||
The F command changes files if the input file is renamed.
|
||||
--form-feed
|
||||
Stop scrolling when a form feed character is reached.
|
||||
--header=[_L[,_C[,_N]]]
|
||||
Use _L lines (starting at line _N) and _C columns as headers.
|
||||
--incsearch
|
||||
Search file as each pattern character is typed in.
|
||||
--intr=[_C]
|
||||
Use _C instead of ^X to interrupt a read.
|
||||
--lesskey-context=_t_e_x_t
|
||||
Use lesskey source file contents.
|
||||
--lesskey-src=_f_i_l_e
|
||||
Use a lesskey source file.
|
||||
--line-num-width=[_N]
|
||||
Set the width of the -N line number field to _N characters.
|
||||
--match-shift=[_N]
|
||||
Show at least _N characters to the left of a search match.
|
||||
--modelines=[_N]
|
||||
Read _N lines from the input file and look for vim modelines.
|
||||
--mouse
|
||||
Enable mouse input.
|
||||
--no-edit-warn
|
||||
Don't warn when using v command on a file opened via LESSOPEN.
|
||||
--no-keypad
|
||||
Don't send termcap keypad init/deinit strings.
|
||||
--no-histdups
|
||||
Remove duplicates from command history.
|
||||
--no-number-headers
|
||||
Don't give line numbers to header lines.
|
||||
--no-paste
|
||||
Ignore pasted input.
|
||||
--no-search-header-lines
|
||||
Searches do not include header lines.
|
||||
--no-search-header-columns
|
||||
Searches do not include header columns.
|
||||
--no-search-headers
|
||||
Searches do not include header lines or columns.
|
||||
--no-vbell
|
||||
Disable the terminal's visual bell.
|
||||
--redraw-on-quit
|
||||
Redraw final screen when quitting.
|
||||
--rscroll=[_C]
|
||||
Set the character used to mark truncated lines.
|
||||
--save-marks
|
||||
Retain marks across invocations of less.
|
||||
--search-options=[EFKNRW-]
|
||||
Set default options for every search.
|
||||
--show-preproc-errors
|
||||
Display a message if preprocessor exits with an error status.
|
||||
--proc-backspace
|
||||
Process backspaces for bold/underline.
|
||||
--PROC-BACKSPACE
|
||||
Treat backspaces as control characters.
|
||||
--proc-return
|
||||
Delete carriage returns before newline.
|
||||
--PROC-RETURN
|
||||
Treat carriage returns as control characters.
|
||||
--proc-tab
|
||||
Expand tabs to spaces.
|
||||
--PROC-TAB
|
||||
Treat tabs as control characters.
|
||||
--status-col-width=[_N]
|
||||
Set the width of the -J status column to _N characters.
|
||||
--status-line
|
||||
Highlight or color the entire line containing a mark.
|
||||
--use-backslash
|
||||
Subsequent options use backslash as escape char.
|
||||
--use-color
|
||||
Enables colored text.
|
||||
--wheel-lines=[_N]
|
||||
Each click of the mouse wheel moves _N lines.
|
||||
--wordwrap
|
||||
Wrap lines at spaces.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
LLIINNEE EEDDIITTIINNGG
|
||||
|
||||
These keys can be used to edit text being entered
|
||||
on the "command line" at the bottom of the screen.
|
||||
|
||||
RightArrow ..................... ESC-l ... Move cursor right one character.
|
||||
LeftArrow ...................... ESC-h ... Move cursor left one character.
|
||||
ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
|
||||
ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
|
||||
HOME ........................... ESC-0 ... Move cursor to start of line.
|
||||
END ............................ ESC-$ ... Move cursor to end of line.
|
||||
BACKSPACE ................................ Delete char to left of cursor.
|
||||
DELETE ......................... ESC-x ... Delete char under cursor.
|
||||
ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
|
||||
ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
|
||||
ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
|
||||
UpArrow ........................ ESC-k ... Retrieve previous command line.
|
||||
DownArrow ...................... ESC-j ... Retrieve next command line.
|
||||
TAB ...................................... Complete filename & cycle.
|
||||
SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
|
||||
ctrl-L ................................... Complete filename, list all.
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
@echo off
|
||||
echo =================================
|
||||
echo 백엔드 빠른 재시작 스크립트
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
echo [1/2] 백엔드 컨테이너 재시작 중...
|
||||
docker-compose -f docker-compose.springboot.yml restart backend
|
||||
|
||||
echo [2/2] 상태 확인 중...
|
||||
timeout /t 5 > nul
|
||||
docker-compose -f docker-compose.springboot.yml ps backend
|
||||
|
||||
echo.
|
||||
echo 백엔드 빠른 재시작 완료!
|
||||
echo 접속 URL: http://localhost:8080
|
||||
echo.
|
||||
pause
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
@echo off
|
||||
echo =================================
|
||||
echo 백엔드 재시작 스크립트
|
||||
echo =================================
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
echo [1/3] 백엔드 컨테이너 중지 중...
|
||||
docker-compose -f docker-compose.springboot.yml stop backend
|
||||
|
||||
echo [2/3] 백엔드 컨테이너 재빌드 중...
|
||||
docker-compose -f docker-compose.springboot.yml build --no-cache backend
|
||||
|
||||
echo [3/3] 백엔드 컨테이너 시작 중...
|
||||
docker-compose -f docker-compose.springboot.yml up -d backend
|
||||
|
||||
echo.
|
||||
echo 백엔드 재시작 완료!
|
||||
echo 접속 URL: http://localhost:8080
|
||||
echo.
|
||||
|
||||
echo 로그 확인을 원하시면 아무 키나 누르세요...
|
||||
pause > nul
|
||||
docker-compose -f docker-compose.springboot.yml logs -f backend
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
@echo off
|
||||
|
||||
echo =====================================
|
||||
echo PLM 솔루션 - Windows 시작
|
||||
echo =====================================
|
||||
|
||||
echo 기존 컨테이너 정리 중...
|
||||
docker-compose -f docker-compose.win.yml down 2>nul
|
||||
|
||||
echo PLM 서비스 시작 중...
|
||||
docker-compose -f docker-compose.win.yml up --build --force-recreate -d
|
||||
|
||||
if %errorlevel% equ 0 (
|
||||
echo.
|
||||
echo ✅ PLM 서비스가 성공적으로 시작되었습니다!
|
||||
echo.
|
||||
echo 🌐 접속 URL:
|
||||
echo • 프론트엔드 (Next.js): http://localhost:3000
|
||||
echo • 백엔드 (Spring/JSP): http://localhost:9090
|
||||
echo.
|
||||
echo 📋 서비스 상태 확인:
|
||||
echo docker-compose -f docker-compose.win.yml ps
|
||||
echo.
|
||||
echo 📊 로그 확인:
|
||||
echo docker-compose -f docker-compose.win.yml logs
|
||||
echo.
|
||||
echo 5초 후 프론트엔드 페이지를 자동으로 엽니다...
|
||||
timeout /t 5 /nobreak >nul
|
||||
start http://localhost:3000
|
||||
) else (
|
||||
echo.
|
||||
echo ❌ PLM 서비스 시작에 실패했습니다!
|
||||
echo.
|
||||
echo 🔍 문제 해결 방법:
|
||||
echo 1. Docker Desktop이 실행 중인지 확인
|
||||
echo 2. 포트가 사용 중인지 확인 (3000, 9090)
|
||||
echo 3. 로그 확인: docker-compose -f docker-compose.win.yml logs
|
||||
echo.
|
||||
pause
|
||||
)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 시작 시간 기록
|
||||
START_TIME=$(date +%s)
|
||||
START_TIME_FORMATTED=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 전체 서비스 시작 (병렬 최적화)"
|
||||
echo "============================================"
|
||||
echo "🕐 시작 시간: $START_TIME_FORMATTED"
|
||||
|
||||
echo ""
|
||||
echo "🚀 백엔드와 프론트엔드를 병렬로 빌드 및 시작합니다..."
|
||||
echo ""
|
||||
|
||||
# 기존 컨테이너 강제 삭제 (이름 충돌 방지)
|
||||
echo "============================================"
|
||||
echo "0. 기존 컨테이너 정리 중..."
|
||||
echo "============================================"
|
||||
docker rm -f pms-backend-mac pms-frontend-mac 2>/dev/null || echo "기존 컨테이너가 없습니다."
|
||||
docker network rm pms-network 2>/dev/null || echo "기존 네트워크가 없습니다."
|
||||
docker network create pms-network 2>/dev/null || echo "네트워크를 생성했습니다."
|
||||
echo ""
|
||||
|
||||
# 병렬 빌드 시작
|
||||
PARALLEL_START=$(date +%s)
|
||||
echo "============================================"
|
||||
echo "1. 병렬 빌드 시작 (백엔드 + 프론트엔드)"
|
||||
echo "============================================"
|
||||
|
||||
# 백엔드 빌드 (백그라운드)
|
||||
echo "🔧 백엔드 빌드 시작..."
|
||||
(
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml build
|
||||
echo "✅ 백엔드 빌드 완료"
|
||||
) &
|
||||
BACKEND_PID=$!
|
||||
|
||||
# 프론트엔드 빌드 (백그라운드)
|
||||
echo "🔧 프론트엔드 빌드 시작..."
|
||||
(
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml build
|
||||
echo "✅ 프론트엔드 빌드 완료"
|
||||
) &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
# 두 빌드가 모두 완료될 때까지 대기
|
||||
echo "⏳ 병렬 빌드 진행 중..."
|
||||
wait $BACKEND_PID
|
||||
wait $FRONTEND_PID
|
||||
|
||||
PARALLEL_END=$(date +%s)
|
||||
PARALLEL_DURATION=$((PARALLEL_END - PARALLEL_START))
|
||||
echo "✅ 병렬 빌드 완료 (${PARALLEL_DURATION}초 소요)"
|
||||
|
||||
# 서비스 시작
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "2. 서비스 시작 중..."
|
||||
echo "============================================"
|
||||
|
||||
SERVICE_START=$(date +%s)
|
||||
|
||||
# 기존 컨테이너 정리
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml down -v 2>/dev/null
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml down -v 2>/dev/null
|
||||
|
||||
# 백엔드 시작 (백그라운드)
|
||||
echo "🚀 백엔드 서비스 시작..."
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml up -d &
|
||||
BACKEND_START_PID=$!
|
||||
|
||||
# 프론트엔드 시작 (백그라운드)
|
||||
echo "🚀 프론트엔드 서비스 시작..."
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml up -d &
|
||||
FRONTEND_START_PID=$!
|
||||
|
||||
# 서비스 시작 완료 대기
|
||||
wait $BACKEND_START_PID
|
||||
wait $FRONTEND_START_PID
|
||||
|
||||
echo ""
|
||||
echo "⏳ 서비스 안정화 대기 중... (8초)"
|
||||
sleep 8
|
||||
|
||||
SERVICE_END=$(date +%s)
|
||||
SERVICE_DURATION=$((SERVICE_END - SERVICE_START))
|
||||
echo "✅ 서비스 시작 완료 (${SERVICE_DURATION}초 소요)"
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "🎉 모든 서비스가 시작되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "[DATABASE] PostgreSQL: http://39.117.244.52:11132"
|
||||
echo "[BACKEND] Node.js API: http://localhost:8080/api"
|
||||
echo "[FRONTEND] Next.js: http://localhost:9771"
|
||||
echo ""
|
||||
echo "서비스 상태 확인:"
|
||||
echo " 백엔드: docker-compose -f docker/dev/docker-compose.backend.mac.yml ps"
|
||||
echo " 프론트엔드: docker-compose -f docker/dev/docker-compose.frontend.mac.yml ps"
|
||||
echo ""
|
||||
echo "로그 확인:"
|
||||
echo " 백엔드: docker-compose -f docker/dev/docker-compose.backend.mac.yml logs -f"
|
||||
echo " 프론트엔드: docker-compose -f docker/dev/docker-compose.frontend.mac.yml logs -f"
|
||||
echo ""
|
||||
echo "서비스 중지:"
|
||||
echo " 백엔드: docker-compose -f docker/dev/docker-compose.backend.mac.yml down"
|
||||
echo " 프론트엔드: docker-compose -f docker/dev/docker-compose.frontend.mac.yml down"
|
||||
echo " 전체: ./stop-all.sh"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
# 종료 시간 계산 및 표시
|
||||
END_TIME=$(date +%s)
|
||||
END_TIME_FORMATTED=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
DURATION=$((END_TIME - START_TIME))
|
||||
MINUTES=$((DURATION / 60))
|
||||
SECONDS=$((DURATION % 60))
|
||||
|
||||
echo "🕐 종료 시간: $END_TIME_FORMATTED"
|
||||
echo "⏱️ 총 소요 시간: ${MINUTES}분 ${SECONDS}초"
|
||||
echo ""
|
||||
echo "📊 단계별 소요 시간:"
|
||||
echo " • 병렬 빌드: ${PARALLEL_DURATION}초"
|
||||
echo " • 서비스 시작: ${SERVICE_DURATION}초"
|
||||
echo "============================================"
|
||||
|
||||
read -p "계속하려면 아무 키나 누르세요..."
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 백엔드 (Spring Boot) 시작"
|
||||
echo "PLM 솔루션 - 백엔드 (Node.js) 시작"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "1. Docker 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.backend.mac.yml build --no-cache
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml build
|
||||
|
||||
echo ""
|
||||
echo "2. 기존 백엔드 컨테이너 정리 중..."
|
||||
docker-compose -f docker-compose.backend.mac.yml down -v
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 생성 중..."
|
||||
|
|
@ -18,11 +18,11 @@ docker network create pms-network 2>/dev/null || echo "네트워크가 이미
|
|||
|
||||
echo ""
|
||||
echo "4. 백엔드 컨테이너 시작 중..."
|
||||
docker-compose -f docker-compose.backend.mac.yml up -d
|
||||
docker-compose -f docker/dev/docker-compose.backend.mac.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "5. 서비스 상태 확인 중..."
|
||||
sleep 15
|
||||
sleep 8
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
|
@ -30,11 +30,11 @@ echo "백엔드 서비스가 시작되었습니다!"
|
|||
echo "============================================"
|
||||
echo ""
|
||||
echo "[DATABASE] PostgreSQL: http://39.117.244.52:11132"
|
||||
echo "[BACKEND] Spring Boot: http://localhost:8080/api"
|
||||
echo "[BACKEND] Node.js API: http://localhost:8080/api"
|
||||
echo ""
|
||||
echo "상태 확인: docker-compose -f docker-compose.backend.mac.yml ps"
|
||||
echo "로그 확인: docker-compose -f docker-compose.backend.mac.yml logs -f"
|
||||
echo "중지하기: docker-compose -f docker-compose.backend.mac.yml down"
|
||||
echo "상태 확인: docker-compose -f docker/dev/docker-compose.backend.mac.yml ps"
|
||||
echo "로그 확인: docker-compose -f docker/dev/docker-compose.backend.mac.yml logs -f"
|
||||
echo "중지하기: docker-compose -f docker/dev/docker-compose.backend.mac.yml down"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
|
|
@ -6,29 +6,23 @@ echo "============================================"
|
|||
|
||||
echo ""
|
||||
echo "1. Docker 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.frontend.mac.yml build --no-cache
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml build
|
||||
|
||||
echo ""
|
||||
echo "2. 기존 프론트엔드 컨테이너 정리 중..."
|
||||
docker-compose -f docker-compose.frontend.mac.yml down -v
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 확인 중..."
|
||||
if ! docker network ls | grep -q pms-network; then
|
||||
echo "❌ 백엔드가 먼저 실행되지 않았습니다!"
|
||||
echo "먼저 './start-backend.sh'를 실행해주세요."
|
||||
echo ""
|
||||
read -p "계속하려면 아무 키나 누르세요..."
|
||||
exit 1
|
||||
fi
|
||||
echo "3. Docker 네트워크 생성 중..."
|
||||
docker network create pms-network 2>/dev/null || echo "네트워크가 이미 존재합니다."
|
||||
|
||||
echo ""
|
||||
echo "4. 프론트엔드 컨테이너 시작 중..."
|
||||
docker-compose -f docker-compose.frontend.mac.yml up -d
|
||||
docker-compose -f docker/dev/docker-compose.frontend.mac.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "5. 서비스 상태 확인 중..."
|
||||
sleep 10
|
||||
sleep 8
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
|
@ -39,9 +33,9 @@ echo "[FRONTEND] Next.js: http://localhost:9771"
|
|||
echo ""
|
||||
echo "💡 백엔드 API가 필요하므로 백엔드도 실행되어 있는지 확인하세요."
|
||||
echo ""
|
||||
echo "상태 확인: docker-compose -f docker-compose.frontend.mac.yml ps"
|
||||
echo "로그 확인: docker-compose -f docker-compose.frontend.mac.yml logs -f"
|
||||
echo "중지하기: docker-compose -f docker-compose.frontend.mac.yml down"
|
||||
echo "상태 확인: docker-compose -f docker/dev/docker-compose.frontend.mac.yml ps"
|
||||
echo "로그 확인: docker-compose -f docker/dev/docker-compose.frontend.mac.yml logs -f"
|
||||
echo "중지하기: docker-compose -f docker/dev/docker-compose.frontend.mac.yml down"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
|
|
@ -27,8 +27,8 @@ echo "0. 기존 서비스 정리 중..."
|
|||
echo "============================================"
|
||||
|
||||
# 기존 컨테이너 중지 및 제거 (무시하고 계속)
|
||||
docker-compose -f docker-compose.backend.linux.yml down -v 2>/dev/null || true
|
||||
docker-compose -f docker-compose.frontend.linux.yml down -v 2>/dev/null || true
|
||||
docker-compose -f docker/prod/docker-compose.backend.prod.yml down -v 2>/dev/null || true
|
||||
docker-compose -f docker/prod/docker-compose.frontend.prod.yml down -v 2>/dev/null || true
|
||||
|
||||
# 사용하지 않는 이미지 정리
|
||||
echo "사용하지 않는 Docker 이미지 정리 중..."
|
||||
|
|
@ -45,10 +45,10 @@ docker network create pms-network 2>/dev/null || echo "네트워크가 이미
|
|||
|
||||
# 백엔드 빌드 및 시작
|
||||
echo "백엔드 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml build --no-cache
|
||||
docker-compose -f docker/prod/docker-compose.backend.prod.yml build --no-cache
|
||||
|
||||
echo "백엔드 서비스 시작 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml up -d
|
||||
docker-compose -f docker/prod/docker-compose.backend.prod.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "⏳ 백엔드 서비스 안정화 대기 중... (30초)"
|
||||
|
|
@ -56,7 +56,7 @@ sleep 30
|
|||
|
||||
# 백엔드 상태 확인
|
||||
echo "백엔드 서비스 상태 확인:"
|
||||
docker-compose -f docker-compose.backend.linux.yml ps
|
||||
docker-compose -f docker/prod/docker-compose.backend.prod.yml ps
|
||||
|
||||
# 프론트엔드 시작
|
||||
echo ""
|
||||
|
|
@ -65,10 +65,10 @@ echo "2. 프론트엔드 서비스 시작 중..."
|
|||
echo "============================================"
|
||||
|
||||
echo "프론트엔드 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml build --no-cache
|
||||
docker-compose -f docker/prod/docker-compose.frontend.prod.yml build --no-cache
|
||||
|
||||
echo "프론트엔드 서비스 시작 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml up -d
|
||||
docker-compose -f docker/prod/docker-compose.frontend.prod.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "⏳ 프론트엔드 서비스 안정화 대기 중... (15초)"
|
||||
|
|
@ -76,7 +76,7 @@ sleep 15
|
|||
|
||||
# 프론트엔드 상태 확인
|
||||
echo "프론트엔드 서비스 상태 확인:"
|
||||
docker-compose -f docker-compose.frontend.linux.yml ps
|
||||
docker-compose -f docker/prod/docker-compose.frontend.prod.yml ps
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
|
@ -90,18 +90,18 @@ echo " [FRONTEND] Next.js: http://localhost:5555"
|
|||
echo ""
|
||||
echo "🔧 관리 명령어:"
|
||||
echo " 서비스 상태 확인:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.linux.yml ps"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.linux.yml ps"
|
||||
echo " 백엔드: docker-compose -f docker/prod/docker-compose.backend.prod.yml ps"
|
||||
echo " 프론트엔드: docker-compose -f docker/prod/docker-compose.frontend.prod.yml ps"
|
||||
echo " 전체: docker ps"
|
||||
echo ""
|
||||
echo " 로그 확인:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.linux.yml logs -f"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.linux.yml logs -f"
|
||||
echo " 실시간: docker-compose -f docker-compose.backend.linux.yml -f docker-compose.frontend.linux.yml logs -f"
|
||||
echo " 백엔드: docker-compose -f docker/prod/docker-compose.backend.prod.yml logs -f"
|
||||
echo " 프론트엔드: docker-compose -f docker/prod/docker-compose.frontend.prod.yml logs -f"
|
||||
echo " 실시간: docker-compose -f docker/prod/docker-compose.backend.prod.yml -f docker-compose.frontend.linux.yml logs -f"
|
||||
echo ""
|
||||
echo " 서비스 중지:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.linux.yml down"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.linux.yml down"
|
||||
echo " 백엔드: docker-compose -f docker/prod/docker-compose.backend.prod.yml down"
|
||||
echo " 프론트엔드: docker-compose -f docker/prod/docker-compose.frontend.prod.yml down"
|
||||
echo " 전체: ./stop-all-linux.sh"
|
||||
echo ""
|
||||
echo " 시스템 모니터링:"
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
@echo off
|
||||
chcp 65001 >nul
|
||||
|
||||
echo ============================================
|
||||
echo PLM 솔루션 - 전체 서비스 시작 (분리형)
|
||||
echo ============================================
|
||||
|
||||
echo.
|
||||
echo 🚀 백엔드와 프론트엔드를 순차적으로 시작합니다...
|
||||
echo.
|
||||
|
||||
REM 백엔드 먼저 시작
|
||||
echo ============================================
|
||||
echo 1. 백엔드 서비스 시작 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.backend.win.yml build --no-cache
|
||||
docker-compose -f docker-compose.backend.win.yml down -v
|
||||
docker network create pms-network 2>nul || echo 네트워크가 이미 존재합니다.
|
||||
docker-compose -f docker-compose.backend.win.yml up -d
|
||||
|
||||
echo.
|
||||
echo ⏳ 백엔드 서비스 안정화 대기 중... (20초)
|
||||
timeout /t 20 /nobreak >nul
|
||||
|
||||
REM 프론트엔드 시작
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 2. 프론트엔드 서비스 시작 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.frontend.win.yml build --no-cache
|
||||
docker-compose -f docker-compose.frontend.win.yml down -v
|
||||
docker-compose -f docker-compose.frontend.win.yml up -d
|
||||
|
||||
echo.
|
||||
echo ⏳ 프론트엔드 서비스 안정화 대기 중... (10초)
|
||||
timeout /t 10 /nobreak >nul
|
||||
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 🎉 모든 서비스가 시작되었습니다!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo [DATABASE] PostgreSQL: http://39.117.244.52:11132
|
||||
echo [BACKEND] Spring Boot: http://localhost:8080/api
|
||||
echo [FRONTEND] Next.js: http://localhost:9771
|
||||
echo.
|
||||
echo 서비스 상태 확인:
|
||||
echo 백엔드: docker-compose -f docker-compose.backend.win.yml ps
|
||||
echo 프론트엔드: docker-compose -f docker-compose.frontend.win.yml ps
|
||||
echo.
|
||||
echo 로그 확인:
|
||||
echo 백엔드: docker-compose -f docker-compose.backend.win.yml logs -f
|
||||
echo 프론트엔드: docker-compose -f docker-compose.frontend.win.yml logs -f
|
||||
echo.
|
||||
echo 서비스 중지:
|
||||
echo 백엔드: docker-compose -f docker-compose.backend.win.yml down
|
||||
echo 프론트엔드: docker-compose -f docker-compose.frontend.win.yml down
|
||||
echo 전체: stop-all-separated.bat
|
||||
echo.
|
||||
echo ============================================
|
||||
|
||||
pause
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 전체 서비스 시작 (분리형)"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "🚀 백엔드(Node.js)와 프론트엔드(Next.js)를 순차적으로 시작합니다..."
|
||||
echo ""
|
||||
|
||||
# 기존 컨테이너 강제 삭제 (이름 충돌 방지)
|
||||
echo "============================================"
|
||||
echo "0. 기존 컨테이너 정리 중..."
|
||||
echo "============================================"
|
||||
docker rm -f pms-backend-mac pms-frontend-mac 2>/dev/null || echo "기존 컨테이너가 없습니다."
|
||||
docker network rm pms-network 2>/dev/null || echo "기존 네트워크가 없습니다."
|
||||
echo ""
|
||||
|
||||
# 백엔드 먼저 시작
|
||||
echo "============================================"
|
||||
echo "1. 백엔드 서비스 시작 중... (Node.js)"
|
||||
echo "============================================"
|
||||
|
||||
docker-compose -f docker-compose.backend.mac.yml build --no-cache
|
||||
docker-compose -f docker-compose.backend.mac.yml down -v
|
||||
docker network create pms-network 2>/dev/null || echo "네트워크가 이미 존재합니다."
|
||||
docker-compose -f docker-compose.backend.mac.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "⏳ 백엔드 서비스 안정화 대기 중... (20초)"
|
||||
sleep 20
|
||||
|
||||
# 프론트엔드 시작
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "2. 프론트엔드 서비스 시작 중... (Next.js)"
|
||||
echo "============================================"
|
||||
|
||||
docker-compose -f docker-compose.frontend.mac.yml build --no-cache
|
||||
docker-compose -f docker-compose.frontend.mac.yml down -v
|
||||
docker-compose -f docker-compose.frontend.mac.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "⏳ 프론트엔드 서비스 안정화 대기 중... (10초)"
|
||||
sleep 10
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "🎉 모든 서비스가 시작되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "[DATABASE] PostgreSQL: http://39.117.244.52:11132"
|
||||
echo "[BACKEND] Node.js API: http://localhost:8080/api"
|
||||
echo "[FRONTEND] Next.js: http://localhost:9771"
|
||||
echo ""
|
||||
echo "서비스 상태 확인:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.mac.yml ps"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.mac.yml ps"
|
||||
echo ""
|
||||
echo "로그 확인:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.mac.yml logs -f"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.mac.yml logs -f"
|
||||
echo ""
|
||||
echo "서비스 중지:"
|
||||
echo " 백엔드: docker-compose -f docker-compose.backend.mac.yml down"
|
||||
echo " 프론트엔드: docker-compose -f docker-compose.frontend.mac.yml down"
|
||||
echo " 전체: ./stop-all.sh"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
read -p "계속하려면 아무 키나 누르세요..."
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 백엔드 (Spring Boot) 시작 - Linux"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "🚀 Spring Boot 백엔드를 Linux 서버에서 시작합니다..."
|
||||
echo ""
|
||||
|
||||
# 시스템 정보 출력
|
||||
echo "시스템 정보:"
|
||||
echo " OS: $(uname -s)"
|
||||
echo " Architecture: $(uname -m)"
|
||||
echo " Kernel: $(uname -r)"
|
||||
echo ""
|
||||
|
||||
# Docker 버전 확인
|
||||
echo "Docker 환경 확인:"
|
||||
docker --version 2>/dev/null || echo " ❌ Docker가 설치되지 않았습니다."
|
||||
docker-compose --version 2>/dev/null || echo " ❌ Docker Compose가 설치되지 않았습니다."
|
||||
echo ""
|
||||
|
||||
echo "1. Docker 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml build --no-cache
|
||||
|
||||
echo ""
|
||||
echo "2. 기존 백엔드 컨테이너 정리 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 생성 중..."
|
||||
docker network create pms-network 2>/dev/null || echo "네트워크가 이미 존재합니다."
|
||||
|
||||
echo ""
|
||||
echo "4. 백엔드 컨테이너 시작 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "5. 서비스 상태 확인 중..."
|
||||
sleep 20
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "🎉 백엔드 서비스가 시작되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "📊 서비스 접속 정보:"
|
||||
echo " [DATABASE] PostgreSQL: http://39.117.244.52:11132"
|
||||
echo " [BACKEND] Spring Boot: http://localhost:8080/api"
|
||||
echo ""
|
||||
echo "💡 API 테스트:"
|
||||
echo " 헬스체크: curl http://localhost:8080/api/actuator/health"
|
||||
echo ""
|
||||
echo "🔧 관리 명령어:"
|
||||
echo " 상태 확인: docker-compose -f docker-compose.backend.linux.yml ps"
|
||||
echo " 로그 확인: docker-compose -f docker-compose.backend.linux.yml logs -f"
|
||||
echo " 중지하기: docker-compose -f docker-compose.backend.linux.yml down"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
# 헬스체크
|
||||
echo ""
|
||||
echo "🏥 백엔드 헬스체크 수행 중..."
|
||||
for i in {1..12}; do
|
||||
if curl -s http://localhost:8080/api/actuator/health >/dev/null 2>&1; then
|
||||
echo " ✅ 백엔드 서비스 정상"
|
||||
echo " 📋 헬스체크 결과:"
|
||||
curl -s http://localhost:8080/api/actuator/health | jq . 2>/dev/null || curl -s http://localhost:8080/api/actuator/health
|
||||
break
|
||||
else
|
||||
echo " ⏳ 백엔드 응답 대기 중... ($i/12)"
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🎯 백엔드 시작 완료! API는 http://localhost:8080/api 에서 확인하세요."
|
||||
echo ""
|
||||
|
||||
read -p "계속하려면 Enter 키를 누르세요..."
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
@echo off
|
||||
chcp 65001 >nul
|
||||
|
||||
echo ============================================
|
||||
echo PLM 솔루션 - 백엔드 서비스 시작
|
||||
echo ============================================
|
||||
|
||||
echo.
|
||||
echo 🚀 백엔드 서비스를 시작합니다...
|
||||
echo.
|
||||
|
||||
REM 백엔드 시작
|
||||
echo ============================================
|
||||
echo 백엔드 서비스 시작 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.backend.win.yml build --no-cache
|
||||
docker-compose -f docker-compose.backend.win.yml down -v
|
||||
docker network create pms-network 2>nul || echo 네트워크가 이미 존재합니다.
|
||||
docker-compose -f docker-compose.backend.win.yml up -d
|
||||
|
||||
echo.
|
||||
echo ⏳ 백엔드 서비스 안정화 대기 중... (15초)
|
||||
timeout /t 15 /nobreak >nul
|
||||
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 🎉 백엔드 서비스가 시작되었습니다!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo [DATABASE] PostgreSQL: http://39.117.244.52:11132
|
||||
echo [BACKEND] Spring Boot: http://localhost:8080/api
|
||||
echo.
|
||||
echo 서비스 상태 확인:
|
||||
echo docker-compose -f docker-compose.backend.win.yml ps
|
||||
echo.
|
||||
echo 로그 확인:
|
||||
echo docker-compose -f docker-compose.backend.win.yml logs -f
|
||||
echo.
|
||||
echo 서비스 중지:
|
||||
echo docker-compose -f docker-compose.backend.win.yml down
|
||||
echo.
|
||||
echo ============================================
|
||||
|
||||
pause
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 프론트엔드 (Next.js) 시작 - Linux"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "🚀 Next.js 프론트엔드를 Linux 서버에서 시작합니다..."
|
||||
echo ""
|
||||
|
||||
# 시스템 정보 출력
|
||||
echo "시스템 정보:"
|
||||
echo " OS: $(uname -s)"
|
||||
echo " Architecture: $(uname -m)"
|
||||
echo " Kernel: $(uname -r)"
|
||||
echo ""
|
||||
|
||||
# Docker 버전 확인
|
||||
echo "Docker 환경 확인:"
|
||||
docker --version 2>/dev/null || echo " ❌ Docker가 설치되지 않았습니다."
|
||||
docker-compose --version 2>/dev/null || echo " ❌ Docker Compose가 설치되지 않았습니다."
|
||||
echo ""
|
||||
|
||||
echo "1. Docker 이미지 빌드 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml build --no-cache
|
||||
|
||||
echo ""
|
||||
echo "2. 기존 프론트엔드 컨테이너 정리 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 확인 중..."
|
||||
if ! docker network ls | grep -q pms-network; then
|
||||
echo "❌ 백엔드가 먼저 실행되지 않았습니다!"
|
||||
echo "먼저 백엔드를 실행해주세요."
|
||||
echo ""
|
||||
read -p "계속하려면 Enter 키를 누르세요..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "4. 프론트엔드 컨테이너 시작 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "5. 서비스 상태 확인 중..."
|
||||
sleep 15
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "🎉 프론트엔드 서비스가 시작되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "📊 서비스 접속 정보:"
|
||||
echo " [FRONTEND] Next.js: http://localhost:5555"
|
||||
echo ""
|
||||
echo "💡 백엔드 API가 필요하므로 백엔드도 실행되어 있는지 확인하세요."
|
||||
echo ""
|
||||
echo "🔧 관리 명령어:"
|
||||
echo " 상태 확인: docker-compose -f docker-compose.frontend.linux.yml ps"
|
||||
echo " 로그 확인: docker-compose -f docker-compose.frontend.linux.yml logs -f"
|
||||
echo " 중지하기: docker-compose -f docker-compose.frontend.linux.yml down"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
# 헬스체크
|
||||
echo ""
|
||||
echo "🏥 프론트엔드 헬스체크 수행 중..."
|
||||
for i in {1..6}; do
|
||||
if curl -s http://localhost:5555 >/dev/null 2>&1; then
|
||||
echo " ✅ 프론트엔드 서비스 정상"
|
||||
break
|
||||
else
|
||||
echo " ⏳ 프론트엔드 응답 대기 중... ($i/6)"
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🎯 프론트엔드 시작 완료! 브라우저에서 http://localhost:5555 을 확인하세요."
|
||||
echo ""
|
||||
|
||||
read -p "계속하려면 Enter 키를 누르세요..."
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
@echo off
|
||||
chcp 65001 >nul
|
||||
|
||||
echo ============================================
|
||||
echo PLM 솔루션 - 프론트엔드 서비스 시작
|
||||
echo ============================================
|
||||
|
||||
echo.
|
||||
echo 🚀 프론트엔드 서비스를 시작합니다...
|
||||
echo.
|
||||
|
||||
REM 프론트엔드 시작
|
||||
echo ============================================
|
||||
echo 프론트엔드 서비스 시작 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.frontend.win.yml build --no-cache
|
||||
docker-compose -f docker-compose.frontend.win.yml down -v
|
||||
docker-compose -f docker-compose.frontend.win.yml up -d
|
||||
|
||||
echo.
|
||||
echo ⏳ 프론트엔드 서비스 안정화 대기 중... (10초)
|
||||
timeout /t 10 /nobreak >nul
|
||||
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 🎉 프론트엔드 서비스가 시작되었습니다!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo [FRONTEND] Next.js: http://localhost:9771
|
||||
echo.
|
||||
echo 서비스 상태 확인:
|
||||
echo docker-compose -f docker-compose.frontend.win.yml ps
|
||||
echo.
|
||||
echo 로그 확인:
|
||||
echo docker-compose -f docker-compose.frontend.win.yml logs -f
|
||||
echo.
|
||||
echo 서비스 중지:
|
||||
echo docker-compose -f docker-compose.frontend.win.yml down
|
||||
echo.
|
||||
echo ============================================
|
||||
|
||||
pause
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
@echo off
|
||||
echo ============================================
|
||||
echo PLM 솔루션 - Spring Boot 버전 시작
|
||||
echo ============================================
|
||||
|
||||
echo.
|
||||
echo 1. Docker 이미지 빌드 중...
|
||||
docker-compose -f docker-compose.springboot.yml build --no-cache
|
||||
|
||||
echo.
|
||||
echo 2. 기존 컨테이너 정리 중...
|
||||
docker-compose -f docker-compose.springboot.yml down -v
|
||||
|
||||
echo.
|
||||
echo 3. 컨테이너 시작 중...
|
||||
docker-compose -f docker-compose.springboot.yml up -d
|
||||
|
||||
echo.
|
||||
echo 4. 서비스 상태 확인 중...
|
||||
timeout /t 10 /nobreak >nul
|
||||
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 서비스가 시작되었습니다!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo [DATABASE] PostgreSQL: http://localhost:
|
||||
|
||||
echo [BACKEND] Spring Boot: http://localhost:8080/api
|
||||
echo [FRONTEND] Next.js: http://localhost:3000
|
||||
echo.
|
||||
echo 로그 확인: docker-compose -f docker-compose.springboot.yml logs -f
|
||||
echo 중지하기: docker-compose -f docker-compose.springboot.yml down
|
||||
echo.
|
||||
echo ============================================
|
||||
|
||||
pause
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
@echo off
|
||||
|
||||
echo =====================================
|
||||
echo PLM 솔루션 (WACE) - 상태 확인
|
||||
echo =====================================
|
||||
|
||||
echo.
|
||||
echo 📊 컨테이너 상태 확인 중...
|
||||
echo.
|
||||
|
||||
docker-compose -f docker-compose.win.yml ps
|
||||
|
||||
echo.
|
||||
echo 🌐 서비스 접속 정보:
|
||||
echo • 프론트엔드 (Next.js): http://localhost:3000
|
||||
echo • 백엔드 (Spring/JSP): http://localhost:9090
|
||||
echo.
|
||||
|
||||
echo 🔧 유용한 명령어:
|
||||
echo • 로그 확인: docker-compose -f docker-compose.win.yml logs
|
||||
echo • 실시간 로그: docker-compose -f docker-compose.win.yml logs -f
|
||||
echo • 특정 서비스 로그: docker-compose -f docker-compose.win.yml logs [plm-app|plm-frontend]
|
||||
echo.
|
||||
|
||||
echo 💻 개별 서비스 상태 확인:
|
||||
echo.
|
||||
|
||||
echo [프론트엔드 서비스]
|
||||
docker-compose -f docker-compose.win.yml ps plm-frontend
|
||||
|
||||
echo.
|
||||
echo [백엔드 서비스]
|
||||
docker-compose -f docker-compose.win.yml ps plm-app
|
||||
|
||||
echo.
|
||||
echo 🌐 브라우저에서 접속하시겠습니까? (Y/N)
|
||||
set /p choice="선택: "
|
||||
|
||||
if /i "%choice%"=="Y" (
|
||||
echo 프론트엔드 페이지를 엽니다...
|
||||
start http://localhost:3000
|
||||
) else if /i "%choice%"=="y" (
|
||||
echo 프론트엔드 페이지를 엽니다...
|
||||
start http://localhost:3000
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 아무 키나 누르면 종료됩니다...
|
||||
pause >nul
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 전체 서비스 중지 - Linux"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "🛑 모든 서비스를 중지합니다..."
|
||||
echo ""
|
||||
|
||||
# 프론트엔드 먼저 중지
|
||||
echo "1. 프론트엔드 서비스 중지 중..."
|
||||
docker-compose -f docker-compose.frontend.linux.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "2. 백엔드 서비스 중지 중..."
|
||||
docker-compose -f docker-compose.backend.linux.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 정리 중..."
|
||||
docker network rm pms-network 2>/dev/null || echo "네트워크가 이미 제거되었거나 사용 중입니다."
|
||||
|
||||
echo ""
|
||||
echo "4. 사용하지 않는 리소스 정리 중..."
|
||||
docker system prune -f
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "✅ 모든 서비스가 중지되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "정리된 항목:"
|
||||
echo " ✓ 프론트엔드 컨테이너 (pms-frontend-linux)"
|
||||
echo " ✓ 백엔드 컨테이너 (pms-backend-linux)"
|
||||
echo " ✓ Docker 네트워크 (pms-network)"
|
||||
echo " ✓ 사용하지 않는 이미지 및 볼륨"
|
||||
echo ""
|
||||
echo "🔄 서비스 재시작: ./start-all-separated-linux.sh"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
read -p "계속하려면 Enter 키를 누르세요..."
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
@echo off
|
||||
chcp 65001 >nul
|
||||
|
||||
echo ============================================
|
||||
echo PLM 솔루션 - 전체 서비스 중지 (분리형)
|
||||
echo ============================================
|
||||
|
||||
echo.
|
||||
echo 🛑 백엔드와 프론트엔드 서비스를 순차적으로 중지합니다...
|
||||
echo.
|
||||
|
||||
REM 프론트엔드 먼저 중지
|
||||
echo ============================================
|
||||
echo 1. 프론트엔드 서비스 중지 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.frontend.win.yml down -v
|
||||
|
||||
echo.
|
||||
echo ⏳ 프론트엔드 서비스 완전 중지 대기 중... (5초)
|
||||
timeout /t 5 /nobreak >nul
|
||||
|
||||
REM 백엔드 중지
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 2. 백엔드 서비스 중지 중...
|
||||
echo ============================================
|
||||
|
||||
docker-compose -f docker-compose.backend.win.yml down -v
|
||||
|
||||
echo.
|
||||
echo ⏳ 백엔드 서비스 완전 중지 대기 중... (5초)
|
||||
timeout /t 5 /nobreak >nul
|
||||
|
||||
REM 네트워크 정리 (선택사항)
|
||||
echo.
|
||||
echo ============================================
|
||||
echo 3. 네트워크 정리 중...
|
||||
echo ============================================
|
||||
|
||||
docker network rm pms-network 2>nul || echo 네트워크가 이미 삭제되었습니다.
|
||||
|
||||
echo.
|
||||
echo ============================================
|
||||
echo ✅ 모든 서비스가 중지되었습니다!
|
||||
echo ============================================
|
||||
echo.
|
||||
echo 서비스 상태 확인:
|
||||
echo docker ps
|
||||
echo.
|
||||
echo 서비스 시작:
|
||||
echo start-all-separated.bat
|
||||
echo.
|
||||
echo ============================================
|
||||
|
||||
pause
|
||||
32
stop-all.sh
32
stop-all.sh
|
|
@ -1,32 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "============================================"
|
||||
echo "PLM 솔루션 - 전체 서비스 중지"
|
||||
echo "============================================"
|
||||
|
||||
echo ""
|
||||
echo "🛑 모든 서비스를 중지합니다..."
|
||||
echo ""
|
||||
|
||||
echo "1. 프론트엔드 서비스 중지 중..."
|
||||
docker-compose -f docker-compose.frontend.mac.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "2. 백엔드 서비스 중지 중..."
|
||||
docker-compose -f docker-compose.backend.mac.yml down -v
|
||||
|
||||
echo ""
|
||||
echo "3. Docker 네트워크 정리 중..."
|
||||
docker network rm pms-network 2>/dev/null || echo "네트워크가 이미 제거되었거나 사용 중입니다."
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "✅ 모든 서비스가 중지되었습니다!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "컨테이너 상태 확인: docker ps -a"
|
||||
echo "이미지 정리하기: docker system prune -f"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
|
||||
read -p "계속하려면 아무 키나 누르세요..."
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
@echo off
|
||||
|
||||
echo =====================================
|
||||
echo PLM 솔루션 - Windows 정지
|
||||
echo =====================================
|
||||
|
||||
echo PLM 서비스 정지 중...
|
||||
echo • 프론트엔드 (Next.js) 정지
|
||||
echo • 백엔드 (Spring/JSP) 정지
|
||||
echo • 볼륨 및 네트워크 정리
|
||||
|
||||
docker-compose -f docker-compose.win.yml down --volumes --remove-orphans
|
||||
|
||||
if %errorlevel% equ 0 (
|
||||
echo.
|
||||
echo ✅ PLM 서비스가 성공적으로 정지되었습니다.
|
||||
echo.
|
||||
echo 📋 정리 완료:
|
||||
echo • 모든 컨테이너 정지 및 제거
|
||||
echo • 볼륨 데이터 정리
|
||||
echo • 네트워크 정리
|
||||
echo.
|
||||
) else (
|
||||
echo.
|
||||
echo ❌ PLM 서비스 정지 중 오류가 발생했습니다.
|
||||
echo.
|
||||
echo 🔍 수동으로 정리하려면:
|
||||
echo docker-compose -f docker-compose.win.yml down --volumes
|
||||
echo.
|
||||
)
|
||||
|
||||
echo 작업 완료. 아무 키나 누르면 종료됩니다...
|
||||
pause >nul
|
||||
Loading…
Reference in New Issue