chore(dev): 로컬 도커 dev override 추가 (이미지 재빌드 없이 spring-boot:run)
로컬은 docker-compose.override.yml 로 app 을 소스 bind-mount + mvn spring-boot:run (offline, 호스트 ~/.m2 캐시)으로 재정의 — JSP 즉시 반영, Java 는 restart. 배포 이미지는 base Dockerfile(WAR 굽기)로 분리: docker compose -f docker-compose.yml up --build. devtools 는 컨테이너 spring-boot:run 에서 이득 적고 SNAPSHOT offline 불안정해 미도입. 가이드(local-dev-setup.md) 갱신. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K3FeMrbtxfTScjrwUukyHD
This commit is contained in:
parent
3405de4350
commit
c7ea189c85
|
|
@ -0,0 +1,31 @@
|
||||||
|
# =============================================================================
|
||||||
|
# 로컬 dev 전용 오버라이드 — `docker compose` 가 docker-compose.yml 과 자동 병합한다.
|
||||||
|
# 목적: app 을 "WAR 굽기" 대신 소스 bind-mount + `mvn spring-boot:run` 으로 띄워
|
||||||
|
# 코드/JSP 변경을 이미지 재빌드 없이 반영(로컬 빠른 루프).
|
||||||
|
#
|
||||||
|
# 배포 이미지는 이 파일과 무관(별도 경로). 배포/운영 빌드는 base 만 명시 사용:
|
||||||
|
# docker compose -f docker-compose.yml up -d --build app # Dockerfile WAR 굽기
|
||||||
|
# (override 자동병합을 피하려고 `-f docker-compose.yml` 로 base 만 지정한다.)
|
||||||
|
#
|
||||||
|
# 반영 방법(로컬, 이미지 재빌드 0):
|
||||||
|
# - JSP/정적: 저장 즉시 반영(Jasper 가 마운트된 webapp 에서 재컴파일). 재시작 불필요.
|
||||||
|
# - Java 코드: `docker compose restart app` (spring-boot:run 재기동 ~1~2s)
|
||||||
|
# 또는 `docker compose exec app mvn -o -P dev -DskipTests compile` 후 restart.
|
||||||
|
# 전제: 호스트 ~/.m2 에 의존성이 캐시돼 있어야 offline(-o) 으로 뜬다(기존 빌드 이력으로 충족).
|
||||||
|
#
|
||||||
|
# 참고: devtools 자동재시작은 도입하지 않음 — 컨테이너 spring-boot:run 에는 소스 자동
|
||||||
|
# 재컴파일러가 없어(IDE 부재) 이득이 미미하고, SNAPSHOT devtools 의 offline 해소가
|
||||||
|
# 불안정해 restart/exec-compile 루프가 더 견고하다.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: maven:3.9-eclipse-temurin-21
|
||||||
|
# base 의 build(Dockerfile WAR 굽기)를 로컬에선 사용하지 않는다.
|
||||||
|
build: !reset null
|
||||||
|
working_dir: /build
|
||||||
|
# offline: 프록시 CA 우회 + 재현성. 새 의존성 추가 시에만 일시적으로 -o 제거 후 1회 온라인.
|
||||||
|
command: ["mvn", "-o", "-P", "dev", "-DskipTests", "spring-boot:run"]
|
||||||
|
volumes:
|
||||||
|
- .:/build # 소스 bind-mount (코드/JSP 즉시 공유)
|
||||||
|
- ${HOME}/.m2:/root/.m2 # 호스트 의존성 캐시 재사용(offline 가능)
|
||||||
|
|
@ -13,13 +13,37 @@
|
||||||
| 구동 방식 | 재빌드·재시작 |
|
| 구동 방식 | 재빌드·재시작 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| **IDE / 호스트 JVM** (`./mvnw spring-boot:run`, 또는 IntelliJ Run) | 앱 **Stop → 프로젝트 rebuild → 다시 Run**. 컴파일된 컨트롤러 변경은 hot-reload 안 됨(devtools 미사용). JSP 변경도 재기동으로 확실히 반영. |
|
| **IDE / 호스트 JVM** (`./mvnw spring-boot:run`, 또는 IntelliJ Run) | 앱 **Stop → 프로젝트 rebuild → 다시 Run**. 컴파일된 컨트롤러 변경은 hot-reload 안 됨(devtools 미사용). JSP 변경도 재기동으로 확실히 반영. |
|
||||||
| **docker compose** (`bibimbap-app` 컨테이너) | `docker compose up -d --build app` — 이미지를 새 소스로 다시 빌드 후 교체 기동. (8080 을 IDE 앱이 점유 중이면 먼저 그쪽을 멈출 것 — 포트 충돌.) |
|
| **docker compose (로컬 dev — 권장)** | 아래 "로컬 도커 dev" 참조. JSP 는 즉시, Java 는 `docker compose restart app`. **이미지 재빌드 불필요**. |
|
||||||
|
| **docker compose (배포 이미지 빌드)** | `docker compose -f docker-compose.yml up -d --build app` — Dockerfile 로 WAR 굽기. 배포/운영용. |
|
||||||
| **수동 WAR** | `./mvnw -P dev clean package spring-boot:repackage -DskipTests` 로 실행형 WAR 재패키지(프로필·repackage goal 주의 — 본 문서 함정 참조) 후 재기동. |
|
| **수동 WAR** | `./mvnw -P dev clean package spring-boot:repackage -DskipTests` 로 실행형 WAR 재패키지(프로필·repackage goal 주의 — 본 문서 함정 참조) 후 재기동. |
|
||||||
|
|
||||||
확인: 재시작 후 의도한 신규 엔드포인트가 응답하는지 1회 스모크(예: 좋아요는 로그인 상태에서 클릭 → 새로고침·목록에서도 카운트 유지). 미로그인 클릭은 신 코드에선 401(로그인 유도)이 정상 — 더 이상 클라이언트에서 토글되지 않는다.
|
확인: 재시작 후 의도한 신규 엔드포인트가 응답하는지 1회 스모크(예: 좋아요는 로그인 상태에서 클릭 → 새로고침·목록에서도 카운트 유지). 미로그인 클릭은 신 코드에선 401(로그인 유도)이 정상 — 더 이상 클라이언트에서 토글되지 않는다.
|
||||||
|
|
||||||
> 코드 변경을 핸드오프할 때는 이 재빌드·재시작 단계를 `needs_user_verification`/배포 후 체크리스트에 **명시**한다. 커밋·테스트 통과 ≠ 실행 인스턴스 반영.
|
> 코드 변경을 핸드오프할 때는 이 재빌드·재시작 단계를 `needs_user_verification`/배포 후 체크리스트에 **명시**한다. 커밋·테스트 통과 ≠ 실행 인스턴스 반영.
|
||||||
|
|
||||||
|
## 로컬 도커 dev (override) vs 배포 이미지 — 분리
|
||||||
|
|
||||||
|
로컬은 **이미지 재빌드 없이** 빠르게 돌리고, 배포 이미지는 **별도 경로**로 굽는다.
|
||||||
|
|
||||||
|
- **로컬 dev**: `docker-compose.override.yml`(git 추적, dev 기본)이 `app` 을 재정의한다 — `maven:3.9-eclipse-temurin-21` 이미지에 소스를 bind-mount(`.:/build`)하고 호스트 `~/.m2` 캐시를 물려 `mvn -o -P dev spring-boot:run` 으로 띄운다. `docker compose` 는 base + override 를 **자동 병합**하므로 평소엔 그냥:
|
||||||
|
```bash
|
||||||
|
docker compose up -d app # 로컬 dev (override 자동 적용, WAR 안 구움)
|
||||||
|
docker compose logs -f app
|
||||||
|
```
|
||||||
|
반영(이미지 재빌드 0):
|
||||||
|
- **JSP/정적**: 저장 즉시(Jasper 가 마운트된 webapp 재컴파일). 재시작 불필요.
|
||||||
|
- **Java 코드**: `docker compose restart app` (spring-boot:run 재기동 ~1~2s). 또는 `docker compose exec app mvn -o -P dev -DskipTests compile` 후 restart.
|
||||||
|
- 전제: 호스트 `~/.m2` 에 의존성 캐시 존재(offline `-o`). **새 의존성 추가 시**: override 의 `-o` 를 일시 제거해 1회 온라인 받거나, 호스트에서 `./mvnw -P dev dependency:go-offline` 후 다시 offline.
|
||||||
|
|
||||||
|
- **배포 이미지**: override 를 **제외**하고 base 만 명시한다(자동병합 회피).
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.yml build app # Dockerfile WAR 굽기
|
||||||
|
docker compose -f docker-compose.yml up -d --build app
|
||||||
|
```
|
||||||
|
Dockerfile 은 멀티스테이지(WAR repackage → `eclipse-temurin:21-jre` + `java -jar`)로 운영과 동일한 산출물을 만든다(프록시 CA·`-P dev`·repackage goal 은 본 문서 함정 참조).
|
||||||
|
|
||||||
|
> devtools 자동재시작은 도입하지 않았다 — 컨테이너 `spring-boot:run` 에는 소스 자동 재컴파일러가 없어(IDE 부재) 이득이 작고, `3.5.x-SNAPSHOT` devtools 의 offline 해소가 불안정했다. `restart`/`exec compile` 루프가 더 견고하다.
|
||||||
|
|
||||||
## 업로드 저장 루트 (static 트리 밖)
|
## 업로드 저장 루트 (static 트리 밖)
|
||||||
|
|
||||||
업로드물(프로필 이미지·게임 WebGL asset)은 **웹서버 정적 서빙 트리(`src/main/resources/static/`) 밖**에 저장한다. 직접 서빙을 차단하고 컨트롤러 권한 게이트를 강제하기 위함이다(보안 하드닝, commit `9041bb7`).
|
업로드물(프로필 이미지·게임 WebGL asset)은 **웹서버 정적 서빙 트리(`src/main/resources/static/`) 밖**에 저장한다. 직접 서빙을 차단하고 컨트롤러 권한 게이트를 강제하기 위함이다(보안 하드닝, commit `9041bb7`).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue