# 배포 (Docker · 192.168.0.176)

이 앱은 **단일 Spring Boot jar**다. React는 빌드 시점에 jar 안(`static/`)으로 들어가므로
서버에는 Node도 웹서버도 필요 없다. 컨테이너 하나만 띄우면 된다.

| 항목 | 값 |
|---|---|
| 런타임 | JDK 21 (이미지에 포함) |
| 컨테이너 내부 포트 | 8080 |
| 서버에 노출할 포트 | 8091 (compose에서 변경 가능) |
| DB | 외부 PostgreSQL 16 `192.168.0.60:5432/itnhub` (컨테이너로 띄우지 않음) |
| 영속 볼륨 | **불필요** — 업로드 파일은 DB(`org_report`)와 Mattermost에 저장된다 |
| 스키마 생성 | 기동 시 Flyway가 `itnhub` 스키마와 V1~V12를 자동 적용 |
| 헬스체크 | `GET /login` 200 (actuator 미포함) |

## 1. 176 서버 준비 (최초 1회)

```bash
# Docker / compose 플러그인
sudo dnf install -y docker docker-compose-plugin    # 또는 apt install docker.io docker-compose-plugin
sudo systemctl enable --now docker

# 배포 파일 위치
sudo install -d -m 755 /opt/itnhub
sudo install -d -m 750 /etc/itnhub

# 환경변수 파일 (값은 직접 채운다)
sudo cp deploy/itnhub.env.example /etc/itnhub/itnhub.env
sudo chmod 600 /etc/itnhub/itnhub.env
sudo vi /etc/itnhub/itnhub.env

# compose 파일
sudo cp deploy/docker-compose.yml /opt/itnhub/

# 방화벽
sudo firewall-cmd --add-port=8091/tcp --permanent && sudo firewall-cmd --reload
```

서버 밖에서 챙길 것 두 가지:

- **DB**: `192.168.0.60`의 `pg_hba.conf`에 176 IP를 허용하고, `itnhub` 계정에 스키마 생성 권한을 준다.
- **아웃바운드**: 176에서 `https://hub.iten.co.kr`(Mattermost API)로 나갈 수 있어야 한다.

## 2. 이미지 만들기

저장소 루트에서:

```bash
docker build -t itnhub:$(git rev-parse --short HEAD) -t itnhub:latest .
```

빌드 컨테이너가 Node v20.17.0과 npm 패키지, Maven 의존성을 내려받으므로 **빌드하는 머신에
인터넷이 열려 있어야 한다**(실행 서버는 필요 없다). 사내망이 막혀 있으면 Maven `settings.xml`의
미러와 `frontend-maven-plugin`의 `nodeDownloadRoot`를 사내 저장소로 돌려야 한다.

## 3. 176으로 옮겨 실행

레지스트리가 있으면 push/pull이 제일 깔끔하다.

```bash
# (A) 사내 레지스트리가 있을 때
docker tag itnhub:latest registry.iten.co.kr/itnhub:latest
docker push registry.iten.co.kr/itnhub:latest
ssh deploy@192.168.0.176 "cd /opt/itnhub && ITNHUB_IMAGE=registry.iten.co.kr/itnhub:latest docker compose pull && ITNHUB_IMAGE=registry.iten.co.kr/itnhub:latest docker compose up -d"

# (B) 레지스트리가 없을 때 - 이미지를 파일로 넘긴다
docker save itnhub:latest | gzip | ssh deploy@192.168.0.176 "gunzip | sudo docker load"
ssh deploy@192.168.0.176 "cd /opt/itnhub && sudo docker compose up -d"
```

## 4. 확인

```bash
ssh deploy@192.168.0.176 "sudo docker compose -f /opt/itnhub/docker-compose.yml ps"
curl -f http://192.168.0.176:8091/login && echo OK
ssh deploy@192.168.0.176 "sudo docker logs --tail 100 itnhub"
```

기동 로그에 Flyway가 어디까지 적용했는지 찍힌다. `Successfully applied N migrations` 또는
`Schema itnhub is up to date` 가 보이면 정상이다.

## 되돌리기

이미지 태그를 커밋 해시로 남겨두면 한 줄로 돌아간다.

```bash
ssh deploy@192.168.0.176 "cd /opt/itnhub && ITNHUB_IMAGE=registry.iten.co.kr/itnhub:<이전해시> docker compose up -d"
```

**주의**: 애플리케이션은 되돌아가지만 Flyway가 이미 적용한 DB 마이그레이션은 되돌아가지 않는다.
스키마를 바꾸는 버전을 배포할 때는 이전 버전 앱이 새 스키마에서도 동작하는지 먼저 확인한다.

## nginx를 앞에 둘 경우

- **서브패스(`/itnhub/`)로는 붙일 수 없다.** Vite `base`가 `/`라 에셋 경로가 절대경로다.
  도메인 루트 또는 전용 포트로 노출한다.
- 정적 파일을 nginx가 직접 서빙하려 하지 말고 전부 앱으로 프록시한다(SPA 경로 포워딩이 앱에 있다).
- TLS를 nginx가 종단하면 `/etc/itnhub/itnhub.env`에
  `SERVER_FORWARD_HEADERS_STRATEGY=framework` 를 넣는다.

## CI(Jenkins)에서 돌릴 때

- 테스트(`mvn test`)는 Testcontainers로 PostgreSQL을 띄우므로 **에이전트에 Docker 소켓이 필요**하다.
  이미지 빌드 안에서는 테스트를 돌리지 않는다(Docker-in-Docker가 되므로).
- 권장 순서: `mvn -B verify`(테스트) → `docker build` → 레지스트리 push → 176에서 `compose up -d`
  → `curl -f http://192.168.0.176:8091/login` 로 확인.
