회사 관리 기능 확장 + 테넌트/비번 보안 하드닝
- 첫 로그인 비번 강제 변경 (RUN_082): FORCE_PASSWORD_CHANGE 컬럼, ForcePasswordChangeGuardFilter, /auth/change-password API + 페이지 - 테넌트 일관성 가드: TenantConsistencyGuardFilter 로 JWT.company_code ↔ 서브도메인 company_code 대조, CompanyResolver 가 (db_name, company_code) 동시 반환 - 회사 관리 확장 (RUN_083 audit log, RUN_084 lifecycle 컬럼): CompanyAdmin/Members/Templates/Lifecycle/AuditLog 서비스 + CompanyMgmtController + SuperAdminGuard - 회사 관리 UI: CompanyAccordionRow 탭화 + 모달 4종 (AdminInfo/Deactivate/Delete/RecopyTemplates) + AuditLogDrawer + csvExport - 프로비저닝 마법사: force_password_change 토글 반영 - 프론트 인증: storage 이벤트 멀티탭 동기화, 403 errorCode (PASSWORD_CHANGE_REQUIRED / CROSS_TENANT_REJECTED / TENANT_NOT_RESOLVED) 전역 리다이렉트 - 기타: StartupSchemaMigrator, OS별 도커 기동 스크립트, CLAUDE.md 트래킹 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# scripts/start — invyone 도커 기동 스크립트
|
||||
|
||||
플랫폼별 1-클릭 실행 스크립트. `docker/dev/docker-compose.invyone.yml` 을 기준으로 프론트엔드 + 백엔드-스프링 컨테이너를 자동 기동합니다.
|
||||
|
||||
## 파일 구성
|
||||
|
||||
| 파일 | 플랫폼 | 실행 방법 |
|
||||
|---|---|---|
|
||||
| `invyone-start-docker-all.bat` | Windows | 더블클릭 또는 cmd 에서 실행 |
|
||||
| `invyone-start-docker-all.sh` | Linux | `./invyone-start-docker-all.sh` |
|
||||
| `invyone-start-docker-all.command` | macOS | Finder 더블클릭 (Terminal 자동 오픈) |
|
||||
|
||||
## 하는 일
|
||||
|
||||
1. `docker` CLI 설치 여부 + daemon 실행 여부 체크
|
||||
2. `docker compose -f docker/dev/docker-compose.invyone.yml up -d` 실행
|
||||
3. 컨테이너 상태 + 접속 URL 안내 출력
|
||||
|
||||
## 접속 URL (기동 후)
|
||||
|
||||
| 대상 | URL |
|
||||
|---|---|
|
||||
| Frontend | `http://localhost:9772` |
|
||||
| Backend API | `http://localhost:8083/api` |
|
||||
| 테넌트 (서브도메인) | `http://<subdomain>.localhost:9772` — 예: `http://test01.localhost:9772` |
|
||||
|
||||
서브도메인 멀티테넌시는 `*.localhost` RFC 6761 자동 매핑을 이용합니다 (Chrome / Firefox / Edge 기본 지원, hosts 편집 · DNS 설정 불필요).
|
||||
|
||||
## 리눅스/맥 첫 실행 전 — 실행 권한 1회
|
||||
|
||||
```bash
|
||||
chmod +x scripts/start/invyone-start-docker-all.sh
|
||||
chmod +x scripts/start/invyone-start-docker-all.command
|
||||
```
|
||||
|
||||
Windows 에서 작성된 파일을 git 으로 받은 경우 executable bit 가 빠질 수 있습니다. 리포에 박아두려면:
|
||||
|
||||
```bash
|
||||
git update-index --chmod=+x scripts/start/invyone-start-docker-all.sh
|
||||
git update-index --chmod=+x scripts/start/invyone-start-docker-all.command
|
||||
```
|
||||
|
||||
## 관련 명령 (참고용)
|
||||
|
||||
| 용도 | 명령 |
|
||||
|---|---|
|
||||
| 로그 실시간 | `docker compose -f docker/dev/docker-compose.invyone.yml logs -f` |
|
||||
| 재시작 (볼륨 유지) | `docker compose -f docker/dev/docker-compose.invyone.yml restart` |
|
||||
| 컨테이너 내리기 | `docker compose -f docker/dev/docker-compose.invyone.yml down` |
|
||||
| 상태 확인 | `docker ps` |
|
||||
|
||||
## 트러블슈팅
|
||||
|
||||
### `docker daemon 이 실행 중이지 않습니다`
|
||||
Docker Desktop 실행 후 재시도.
|
||||
|
||||
### 포트 충돌 (9772 / 8083)
|
||||
같은 머신에서 다른 프로젝트가 해당 포트를 점유했는지 확인 (`docker ps` · 태스크 매니저 · `lsof -i :9772`). 필요하면 `docker-compose.invyone.yml` 의 호스트 포트 매핑을 바꿔서 회피.
|
||||
|
||||
### 테넌트 서브도메인 접속 시 META DB 로 떨어지는 경우
|
||||
현재 백엔드 `SubdomainResolverFilter` 와 프론트 `subdomain.ts` / `client.ts` 는 **`*.invyone.com` 만** 서브도메인으로 인식합니다. dev 환경에서 `*.localhost` 를 허용하는 패치는 별도 작업으로 예정 (`TENANT_ALLOWED_SUFFIXES` / `NEXT_PUBLIC_TENANT_HOST_SUFFIXES` 환경변수 기반).
|
||||
|
||||
### 프론트 `routes-manifest.json` ENOENT
|
||||
`frontend/next.config.mjs` 의 `output: "standalone"` + `experimental.webpackMemoryOptimizations: true` 가 dev 모드에서 청크/매니페스트를 깨는 이슈. 이미 `isDev` 분기로 수정됨 (2026-04-07). 재발 시 해당 설정이 prod build 전용인지 확인.
|
||||
|
||||
## 전제 조건
|
||||
|
||||
- Docker Desktop (Windows/Mac) 또는 docker-ce + docker-compose-plugin (Linux)
|
||||
- 프로젝트 루트에 `docker/dev/docker-compose.invyone.yml` 존재
|
||||
- 본인 로컬 머신에 `.env` 등 필요 설정이 이미 놓여있어야 함 (syncthing 환경이면 자동 동기화)
|
||||
@@ -0,0 +1,55 @@
|
||||
@echo off
|
||||
REM invyone 개발용 도커 컨테이너 기동 (Windows)
|
||||
REM 사용법: 더블클릭 또는 cmd 에서 실행
|
||||
chcp 65001 >nul
|
||||
|
||||
pushd "%~dp0..\.."
|
||||
set COMPOSE_FILE=docker\dev\docker-compose.invyone.yml
|
||||
|
||||
where docker >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [invyone] docker 가 설치되어있지 않습니다. Docker Desktop 설치 후 다시 실행해주세요.
|
||||
popd
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
docker info >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [invyone] docker daemon 이 실행 중이지 않습니다. Docker Desktop 을 실행해주세요.
|
||||
popd
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%COMPOSE_FILE%" (
|
||||
echo [invyone] compose 파일을 찾을 수 없음: %COMPOSE_FILE%
|
||||
popd
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo [invyone] 도커 컨테이너 기동 중...
|
||||
docker compose -f %COMPOSE_FILE% up -d
|
||||
if errorlevel 1 (
|
||||
echo [invyone] 기동 실패. 로그를 확인해주세요.
|
||||
popd
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo [invyone] 컨테이너 상태:
|
||||
docker compose -f %COMPOSE_FILE% ps
|
||||
|
||||
echo.
|
||||
echo [invyone] 접속 URL:
|
||||
echo Frontend: http://localhost:9772
|
||||
echo Backend: http://localhost:8083/api
|
||||
echo 테넌트: http://^<subdomain^>.localhost:9772 (예: http://test01.localhost:9772)
|
||||
echo.
|
||||
echo [invyone] 로그 보기: docker compose -f docker/dev/docker-compose.invyone.yml logs -f
|
||||
echo [invyone] 컨테이너 내리기: docker compose -f docker/dev/docker-compose.invyone.yml down
|
||||
|
||||
popd
|
||||
pause
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# invyone 개발용 도커 컨테이너 기동 (macOS)
|
||||
# 사용법: Finder 에서 더블클릭 또는 터미널에서 ./invyone-start-docker-all.command
|
||||
# 실행권한 필요 시: chmod +x invyone-start-docker-all.command
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
COMPOSE_FILE="$PROJECT_ROOT/docker/dev/docker-compose.invyone.yml"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "[invyone] docker 가 설치되어있지 않습니다. Docker Desktop 설치 후 다시 실행해주세요."
|
||||
read -n 1 -s -r -p "아무 키나 눌러 종료"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "[invyone] docker daemon 이 실행 중이지 않습니다. Docker Desktop 을 실행해주세요."
|
||||
read -n 1 -s -r -p "아무 키나 눌러 종료"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||
echo "[invyone] compose 파일을 찾을 수 없음: $COMPOSE_FILE"
|
||||
read -n 1 -s -r -p "아무 키나 눌러 종료"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[invyone] 도커 컨테이너 기동 중..."
|
||||
docker compose -f "$COMPOSE_FILE" up -d
|
||||
|
||||
echo ""
|
||||
echo "[invyone] 컨테이너 상태:"
|
||||
docker compose -f "$COMPOSE_FILE" ps
|
||||
|
||||
echo ""
|
||||
echo "[invyone] 접속 URL:"
|
||||
echo " Frontend: http://localhost:9772"
|
||||
echo " Backend: http://localhost:8083/api"
|
||||
echo " 테넌트: http://<subdomain>.localhost:9772 (예: http://test01.localhost:9772)"
|
||||
echo ""
|
||||
echo "[invyone] 로그 보기: docker compose -f docker/dev/docker-compose.invyone.yml logs -f"
|
||||
echo "[invyone] 컨테이너 내리기: docker compose -f docker/dev/docker-compose.invyone.yml down"
|
||||
echo ""
|
||||
read -n 1 -s -r -p "아무 키나 눌러 종료"
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
# invyone 개발용 도커 컨테이너 기동 (리눅스)
|
||||
# 사용법: ./invyone-start-docker-all.sh
|
||||
# 실행권한 필요 시: chmod +x invyone-start-docker-all.sh
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
COMPOSE_FILE="$PROJECT_ROOT/docker/dev/docker-compose.invyone.yml"
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "[invyone] docker 가 설치되어있지 않습니다. Docker 설치 후 다시 실행해주세요."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "[invyone] docker daemon 이 실행 중이지 않습니다. Docker Desktop 또는 dockerd 를 실행해주세요."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||
echo "[invyone] compose 파일을 찾을 수 없음: $COMPOSE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[invyone] 도커 컨테이너 기동 중..."
|
||||
docker compose -f "$COMPOSE_FILE" up -d
|
||||
|
||||
echo ""
|
||||
echo "[invyone] 컨테이너 상태:"
|
||||
docker compose -f "$COMPOSE_FILE" ps
|
||||
|
||||
echo ""
|
||||
echo "[invyone] 접속 URL:"
|
||||
echo " Frontend: http://localhost:9772"
|
||||
echo " Backend: http://localhost:8083/api"
|
||||
echo " 테넌트: http://<subdomain>.localhost:9772 (예: http://test01.localhost:9772)"
|
||||
echo ""
|
||||
echo "[invyone] 로그 보기: docker compose -f docker/dev/docker-compose.invyone.yml logs -f"
|
||||
echo "[invyone] 컨테이너 내리기: docker compose -f docker/dev/docker-compose.invyone.yml down"
|
||||
Reference in New Issue
Block a user