27 KiB
ITAM 도커라이징 실전 가이드
1. 문서 목적
이 문서는 Gitea에 올라가 있는 현재 저장소를 기준으로, 개발 PC에 WSL2와 Ubuntu만 설치되어 있는 상태에서 지금의 Docker 실행 구조를 재현하는 방법을 처음부터 끝까지 설명하는 실전 가이드다.
이 문서는 아래 상황을 가정한다.
- 소스 코드는 아직 로컬에 없거나, Gitea에서 막 받아올 예정이다.
- Windows에는 WSL2와 Ubuntu는 설치되어 있다.
- 그 외 Docker 관련 세팅은 아직 안 되어 있을 수 있다.
- 최종 목표는 현재 저장소 기준
frontend + backend + external DB구조를 Docker로 재현하는 것이다.
이 문서의 목적은 아래 네 가지다.
- 현재 시스템 구조와 Docker 구조를 먼저 이해하게 한다.
- 기존 파일 중 무엇이 새로 추가되었고 무엇이 수정되었는지 정리한다.
- 각 단계별로 정확히 어디에서 명령을 실행해야 하는지 명시한다.
- Gitea 소스만 받은 상태에서 지금과 같은 Docker 실행 상태까지 도달하게 한다.
2. 현재 시스템 구조 개요
2.1 애플리케이션 원래 구조
현재 저장소의 본래 실행 구조는 다음과 같다.
- 프런트엔드: Vite 기반 TypeScript 앱
- 백엔드: Express 기반 Node.js API 서버
- 데이터베이스: 외부 MySQL 서버
즉, 원래부터 MySQL이 Docker 안에 들어 있던 구조가 아니다.
프런트와 백엔드는 각각 별도 프로세스로 실행되며, 프런트는 /api 상대 경로로 백엔드 API를 호출한다.
2.2 현재 Docker 구조
현재 최종 Docker 구조는 아래와 같다.
frontend컨테이너backend컨테이너- 외부 MySQL DB
즉, 지금은 내부 db 컨테이너가 없고, 내부 db-bootstrap 컨테이너도 없다.
현재 구조를 문장으로 풀면 다음과 같다.
- 브라우저는
http://localhost:8080으로frontend컨테이너에 접속한다. frontend는/api요청을backend:3000으로 프록시한다.backend는.env에 적힌 외부 DB 정보로 외부 MySQL에 직접 접속한다.- 조회 결과 JSON을 프런트가 받아 화면에 렌더링한다.
간단한 흐름은 아래와 같다.
Browser
-> frontend container :8080
-> Vite proxy (/api)
-> backend container :3000
-> external MySQL (.env)
2.3 왜 이 구조가 맞는가
현재 구조가 적절한 이유는 다음과 같다.
- 원래 시스템도 외부 MySQL을 쓰는 구조였다.
- 지금 목표는 운영형 단일 배포가 아니라 현재 개발형 구조를 Docker로 재현하는 것이다.
- 프런트는 Vite dev server 기반이라 운영형 nginx 정적 배포 구조로 억지로 바꾸는 것보다, 현 구조를 유지하는 편이 안전하다.
- 실무 표준 관점에서도 앱 컨테이너는 무상태로 유지하고, DB는 외부 인프라를 사용하는 구성이 더 일반적이다.
3. 이번 도커라이징에서 추가되거나 수정된 파일 정리
아래 파일들은 이번 Docker 재현 구조를 위해 새로 추가되었거나 수정된 핵심 파일이다.
3.1 새로 추가된 파일
Dockerfile.frontendDockerfile.backend.dockerignoredocker-compose.yamlstart_docker_wsl.ps1stop_docker_wsl.ps1start_docker_wsl.batstop_docker_wsl.batdocker/mysql/init/README.mddocker_task_plan.mddoc_readme2.md
3.2 기존 파일 중 수정된 핵심 파일
server.jsvite.config.tsdoc_readme.md
3.3 각 파일의 역할
Dockerfile.frontend
역할:
- 프런트 Vite 개발 서버 이미지를 만든다.
- 컨테이너 내부에서
npm run dev -- --host 0.0.0.0를 실행한다.
Dockerfile.backend
역할:
- 백엔드 Express 서버 이미지를 만든다.
- 컨테이너 내부에서
npm run server를 실행한다.
.dockerignore
역할:
node_modules,build,.git,.env,uploads같은 불필요한 파일을 Docker build context에서 제외한다.
docker-compose.yaml
역할:
frontend,backend두 컨테이너를 동시에 띄운다.backend는.env의 외부 DB를 사용한다.frontend는backend:3000으로 프록시한다.
start_docker_wsl.ps1
역할:
- Windows 경로를 WSL 경로로 안전하게 바꾼다.
- WSL 내부 Docker를 사용해
docker compose up --build -d를 실행한다. - 한글 경로와 공백 경로에서도 안정적으로 실행되게 한다.
stop_docker_wsl.ps1
역할:
- 같은 방식으로 WSL 내부에서
docker compose down을 실행한다.
start_docker_wsl.bat, stop_docker_wsl.bat
역할:
- PowerShell 스크립트를 쉽게 실행하는 래퍼 역할을 한다.
server.js
중요 수정 사항:
dotenv.config({ override: true })가 아니라dotenv.config()를 사용한다.
이유:
- Compose나 실행 환경이 주는 환경변수를
.env가 덮어써 버리면 안 된다. - 외부 DB 정보와 포트 설정 등 실행 환경 우선 구조를 유지해야 한다.
vite.config.ts
중요 수정 사항:
- 프록시 타깃을 고정
localhost:3000이 아니라 환경변수 기반으로 받도록 바꿨다.
현재 구조:
const proxyTarget = process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:3000';
이유:
- 로컬에서 직접 프런트를 띄울 때는
localhost:3000이 맞다. - Docker 안에서는
frontend컨테이너에서 보는localhost가 백엔드가 아니므로backend:3000을 써야 한다.
4. 현재 docker-compose.yaml 기준 실제 동작 구조
현재 docker-compose.yaml은 아래 구조다.
backend
Dockerfile.backend로 이미지를 빌드한다..env를 읽는다.- DB 관련 변수는
${DB_HOST},${DB_PORT},${DB_USER},${DB_PASS},${DB_NAME}를 그대로 사용한다. - 포트
3000:3000으로 노출한다. uploads,map_config.json을 마운트한다.
frontend
Dockerfile.frontend로 이미지를 빌드한다.VITE_DEV_PROXY_TARGET: http://backend:3000환경변수를 사용한다.- 포트
8080:8080으로 노출한다. - 브라우저의
/api요청을backend로 프록시한다.
즉, 현재 Compose는 DB를 띄우지 않고 앱 두 개만 띄운다.
5. 사전 준비 사항
이 섹션은 Gitea에서 코드를 받기 전 또는 받은 직후에 확인해야 한다.
5.1 가정하는 기본 상태
이미 설치되어 있다고 가정하는 것:
- Windows
- WSL2
- Ubuntu 배포판
아직 없을 수 있는 것:
- Docker Desktop 또는 WSL 내부 Docker 사용 환경
- Git 클라이언트
- 프로젝트
.env
5.2 권장 Docker 실행 방식
현재 저장소 구조상 가장 권장하는 방식은 다음이다.
- Windows에 Docker Desktop 설치
- Docker Desktop에서 WSL2 통합 활성화
- Ubuntu WSL 내부에서
docker명령을 사용할 수 있게 한다.
이유:
- 현재
start_docker_wsl.ps1가 WSL 내부의docker를 호출하는 구조다. - 실제 검증도 WSL 내부 Docker 기준으로 이루어졌다.
5.3 외부 DB 정보 준비
현재 구조는 외부 MySQL을 사용하므로 .env 파일이 반드시 필요하다.
최소한 아래 값이 필요하다.
DB_HOST=<외부 MySQL 호스트>
DB_PORT=3306
DB_USER=<외부 MySQL 계정>
DB_PASS=<외부 MySQL 비밀번호>
DB_NAME=itam
필요 시 추가 환경변수는 현재 백엔드 코드 기준으로 함께 넣을 수 있다.
6. Gitea에서 소스 받기
6.1 작업 실행 위치
이 단계는 Windows PowerShell 또는 Windows 터미널의 PowerShell에서 수행한다.
실행 위치 이유:
- 이후
start_docker_wsl.ps1도 Windows PowerShell에서 실행하는 것이 가장 자연스럽다. - 로컬 작업 폴더를 Windows 경로 기준으로 준비할 수 있다.
6.2 소스 클론
예시:
git clone <Gitea 저장소 URL>
cd <클론된 저장소 경로>
현재 프로젝트처럼 한글 경로를 사용할 수도 있지만, 가능하면 너무 복잡한 경로는 피하는 것이 좋다.
현재 실제 프로젝트 경로 예시는 아래였다.
c:\Users\user\Desktop\안건 파일\itam
이 경로도 현재 스크립트로는 동작 가능하다.
7. Docker 환경 준비
7.1 작업 실행 위치
이 단계는 Windows PowerShell과 WSL Ubuntu 터미널을 둘 다 사용한다.
- 설치 확인은 Windows PowerShell에서 시작
- 실제 Docker 동작 확인은 WSL Ubuntu에서 수행
7.2 Docker Desktop 설치 여부 확인
실행 위치: Windows PowerShell
docker version
만약 여기서 바로 안 잡혀도 현재 프로젝트는 WSL 내부 Docker를 쓰므로, 다음 단계로 넘어가 WSL 내부 확인을 한다.
7.3 WSL 내부 Docker 확인
실행 위치: Windows PowerShell
wsl -l -v
wsl sh -lc "docker --version"
정상 기대 결과:
- Ubuntu가 Running 상태
docker --version이 정상 출력
만약 docker --version이 실패하면, Docker Desktop 설치 및 WSL 통합을 먼저 완료해야 한다.
8. .env 파일 준비
8.1 작업 실행 위치
이 단계는 Windows PowerShell, VS Code, 또는 아무 텍스트 편집기**에서 수행한다.
즉, 프로젝트 루트에 .env 파일을 만드는 작업이다.
8.2 .env 작성
프로젝트 루트에 .env를 만든다.
예시:
DB_HOST=your-external-db-host
DB_PORT=3306
DB_USER=your-db-user
DB_PASS=your-db-password
DB_NAME=itam
주의:
- 현재 Compose는 내부 DB를 만들지 않는다.
- 따라서 이 값이 곧 실제 운영/개발 외부 DB 연결 정보다.
- 이 정보가 틀리면
backend는 기동해도 API에서 DB 오류가 난다.
9. 현재 Docker 파일이 어떻게 동작하는지 이해하기
9.1 Dockerfile.frontend
확인 위치: 프로젝트 루트 / VS Code
현재 내용 핵심:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 8080
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
의미:
- Node 20 Alpine 기반
- 의존성 설치 후 전체 소스 복사
- Vite 개발 서버 실행
9.2 Dockerfile.backend
확인 위치: 프로젝트 루트 / VS Code
현재 내용 핵심:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "run", "server"]
의미:
- Node 20 Alpine 기반
- Express 서버 실행
9.3 vite.config.ts
확인 위치: 프로젝트 루트 / VS Code
현재 핵심:
const proxyTarget = process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:3000';
그리고 /api, /uploads가 모두 proxyTarget으로 프록시된다.
의미:
- 로컬 실행 시 기본값은
localhost:3000 - Docker 실행 시 Compose가
http://backend:3000을 주입
이 수정이 있어야 Docker 안에서도 화면에 데이터가 표시된다.
10. Docker Compose 기동
10.1 작업 실행 위치
이 단계는 반드시 Windows PowerShell에서 수행하는 것을 권장한다.
이유:
start_docker_wsl.ps1가 Windows 경로를 받아 WSL 경로로 바꾸는 구조다.- 한글/공백 경로에서 가장 안전하다.
10.2 권장 기동 방법
실행 위치: 프로젝트 루트의 Windows PowerShell
.\start_docker_wsl.ps1
또는
.\start_docker_wsl.bat
이 스크립트는 내부적으로 아래를 수행한다.
- PowerShell 출력 인코딩을 UTF-8로 설정
- 현재 Windows 경로를 WSL 경로로 변환
- WSL 동작 확인
- WSL 내부 Docker 동작 확인
docker compose up --build -d수행
10.3 직접 기동이 필요할 때
실행 위치: WSL Ubuntu 터미널
직접 실행 예시는 아래와 같다.
cd /mnt/c/Users/user/Desktop/안건\ 파일/itam
docker compose up --build -d
하지만 현재 프로젝트는 한글 경로 이슈가 있었기 때문에, 특별한 이유가 없으면 start_docker_wsl.ps1를 우선 사용한다.
11. 컨테이너 기동 후 검증
11.1 컨테이너 상태 확인
실행 위치: Windows PowerShell
wsl sh -lc "docker ps -a --format 'table {{.Names}}\t{{.Status}}' | grep itam"
정상 기대 상태:
itam-backend->Upitam-frontend->Up
현재는 itam-db, itam-db-bootstrap가 없어야 정상이다.
11.2 백엔드 API 확인
실행 위치: Windows PowerShell
Invoke-WebRequest -Uri http://localhost:3000/api/assets/master -UseBasicParsing | Select-Object -ExpandProperty StatusCode
정상 기대값:
200
이 검사는 backend가 외부 DB에 정상 연결됐는지 보는 가장 직접적인 검사다.
11.3 프런트 경유 API 확인
실행 위치: Windows PowerShell
Invoke-WebRequest -Uri http://localhost:8080/api/assets/master -UseBasicParsing | Select-Object -ExpandProperty StatusCode
정상 기대값:
200
이 검사는 프런트 프록시가 정상인지 확인한다.
예전에 화면에 데이터가 안 보였던 것은 외부 DB 자체가 아니라, 이 프록시 경로가 잘못돼 있었기 때문이다.
11.4 브라우저 화면 확인
실행 위치: 브라우저
http://localhost:8080
확인 포인트:
- 화면이 열리는지
- 목록/대시보드/테이블 데이터가 비어 있지 않은지
- 모달 진입 시 데이터가 정상적으로 보이는지
12. 지금 데이터가 표시되는 원리
현재는 내부 DB로 데이터를 옮겨 담지 않는다.
현재 실제 동작 원리는 다음과 같다.
- 브라우저가
frontend에 접속한다. - 프런트가
/api/...로 요청한다. - Vite 프록시가
backend:3000으로 요청을 넘긴다. backend가.env의 외부 MySQL에 직접 접속한다.- 조회 결과 JSON을 프런트가 받아 화면에 렌더링한다.
즉, 현재는 아래 구조다.
Browser -> frontend -> backend -> external MySQL
예전 외부 DB 구조에서 화면에 데이터가 안 보였던 이유는 외부 DB 때문이 아니라, 프런트 컨테이너가 localhost:3000을 잘못 바라보고 있었기 때문이다.
지금은 VITE_DEV_PROXY_TARGET: http://backend:3000으로 수정되어 있기 때문에 정상 표시된다.
13. 자주 헷갈리는 포인트
13.1 현재는 내부 DB 컨테이너가 없다
현재 docker-compose.yaml에는 아래가 없다.
db서비스db-bootstrap서비스itam_mysql_data볼륨
즉, DB는 Docker 스택 밖에 있다.
13.2 현재는 .env가 곧 실제 DB 연결 정보다
현재 backend는 아래처럼 Compose에서 그대로 받는다.
DB_HOST: ${DB_HOST}DB_PORT: ${DB_PORT}DB_USER: ${DB_USER}DB_PASS: ${DB_PASS}DB_NAME: ${DB_NAME}
즉, .env를 틀리게 적으면 화면도 데이터가 안 뜬다.
13.3 server.js는 여전히 중요하게 수정된 상태다
현재 server.js는 dotenv.config()를 사용한다.
이 구조는 이후 Compose나 실행 환경에서 변수를 주입할 때, 애플리케이션이 그 값을 받아들일 수 있게 하기 위해 유지해야 한다.
14. 스택 중지 방법
14.1 작업 실행 위치
Windows PowerShell / 프로젝트 루트
14.2 권장 종료 명령
.\stop_docker_wsl.ps1
또는
.\stop_docker_wsl.bat
이 스크립트는 내부적으로 WSL 경로 변환 후 docker compose down을 수행한다.
15. 장애 발생 시 점검 순서
15.1 frontend 화면은 뜨는데 데이터가 없을 때
실행 위치: Windows PowerShell
먼저 아래 두 API를 분리해서 본다.
Invoke-WebRequest -Uri http://localhost:3000/api/assets/master -UseBasicParsing | Select-Object -ExpandProperty StatusCode
Invoke-WebRequest -Uri http://localhost:8080/api/assets/master -UseBasicParsing | Select-Object -ExpandProperty StatusCode
판단 기준:
3000은 200이고8080만 실패 -> 프런트 프록시 문제- 둘 다 실패 -> 백엔드 또는 외부 DB 연결 문제
15.2 백엔드가 외부 DB에 연결되지 않을 때
실행 위치: Windows PowerShell
wsl sh -lc "docker logs --tail=200 itam-backend"
점검 항목:
.env의 DB 정보가 정확한지- 외부 DB 서버 접근이 가능한지
- 계정/비밀번호가 맞는지
- 방화벽 또는 네트워크 이슈가 없는지
16. 운영 수동 배포 플로우
이 섹션은 현재 ITAM 저장소 기준으로 운영 서버에 반영할 때의 전체 흐름을 설명한다.
중요한 전제는 아래와 같다.
- 로컬 수정본을 서버에 직접 복사하지 않는다.
- 반드시 Gitea에 올라간 커밋을 기준으로 배포한다.
- 운영 반영은 자동 푸시 배포가 아니라 Gitea workflow 수동 실행으로 진행한다.
- 현재 기준 운영 배포 workflow는
.gitea/workflows/itam_production_deploy.yml이다.
16.1 전체 운영/배포 분기 흐름
운영 반영은 크게 세 상황으로 나뉜다.
- 최초 운영 서버 구축 후 첫 배포
- 코드 수정 후 일반 재배포
- 검증 실패 또는 배포 실패 후 수정 재배포
아래 분기 구조로 이해하면 된다.
flowchart TD
START["배포 필요 발생"] --> CASE{"어떤 상황인가?"}
CASE -->|초기 구축| INIT["초기 운영 배포 준비"]
CASE -->|수정 반영| CHANGE["수정 후 재배포 준비"]
CASE -->|실패 후 재시도| RETRY["실패 원인 분석 후 재배포 준비"]
INIT --> INIT1["운영 서버 Docker / compose 확인"]
INIT1 --> INIT2["Gitea Variables / Secrets 등록"]
INIT2 --> INIT3["map_config.json / uploads 초기 데이터 준비"]
INIT3 --> MANUAL["Gitea에서 수동 배포 workflow 실행"]
CHANGE --> CHANGE1["로컬 수정 및 테스트"]
CHANGE1 --> CHANGE2["Gitea 커밋 / push"]
CHANGE2 --> CHANGE3["Code Check / Docker Build Check 통과"]
CHANGE3 --> MANUAL
RETRY --> RETRY1{"어디서 실패했는가?"}
RETRY1 -->|코드 체크 실패| FIX1["코드 또는 설정 수정"]
RETRY1 -->|배포 단계 실패| FIX2["서버 / 변수 / 권한 / 네트워크 수정"]
RETRY1 -->|Smoke Check 실패| FIX3["앱 기동 상태 / 프록시 / DB 상태 수정"]
FIX1 --> CHANGE2
FIX2 --> MANUAL
FIX3 --> MANUAL
MANUAL --> DEPLOY["운영 서버 반영 수행"]
DEPLOY --> RESULT{"최종 검증 통과?"}
RESULT -->|예| DONE["운영 반영 완료"]
RESULT -->|아니오| RETRY
linkStyle default stroke:#d32f2f,stroke-width:2px;
핵심은 아래와 같다.
- 초기 구축은 서버와 운영 데이터 준비가 먼저다.
- 수정 반영은 반드시 커밋과 push가 먼저다.
- 실패 후 재배포는 실패 지점에 따라 수정 위치가 달라진다.
16.2 최초 운영 배포 플로우
최초 배포에서는 코드보다 운영 환경 준비가 더 중요하다.
순서는 아래와 같다.
- 운영 서버에 Docker Engine과
docker compose를 설치한다. - 운영 서버에서 Gitea 저장소에 접근 가능한 SSH 키를 준비한다.
- Gitea repository Variables / Secrets를 등록한다.
PROD_DEPLOY_PATH경로를 정한다.map_config.json,uploads/초기 데이터를 준비한다.- Gitea에서
itam_production_deploy.yml을 수동 실행한다. - 배포 후
ps,/health,/,/ready를 확인한다.
즉 최초 배포는 아래 조건이 먼저 충족되어야 한다.
서버 준비 완료
-> Gitea 변수 / 시크릿 등록 완료
-> 초기 데이터 준비 완료
-> 수동 배포 실행
16.3 수정 후 일반 재배포 플로우
일반적인 수정 반영은 아래 흐름이다.
- 개발자가 로컬에서 코드 또는 설정을 수정한다.
- 로컬에서 필요한 테스트를 수행한다.
- 변경사항을 Gitea에 커밋 후 push 한다.
itam_code_check.yml이 빌드와 compose 문법을 검사한다.itam_docker_build_check.yml이 운영용 이미지 빌드 가능 여부를 검사한다.- 두 검증이 통과하면 운영자가 Gitea에서
itam_production_deploy.yml을 수동 실행한다. - 운영 서버가 최신 커밋으로 동기화되고 컨테이너가 다시 올라온다.
- smoke check 통과 여부를 확인한다.
아래 다이어그램은 이 일반 재배포 흐름을 보여준다.
flowchart LR
DEV["로컬 수정"] --> TEST["로컬 확인"]
TEST --> PUSH["커밋 / push"]
PUSH --> CODE["ITAM Code Check"]
CODE --> BUILD["ITAM Docker Build Check"]
BUILD --> GATE{"검증 통과?"}
GATE -->|예| RUN["Gitea에서 수동 배포 실행"]
GATE -->|아니오| FIX["로컬 수정 후 재커밋"]
FIX --> PUSH
RUN --> PROD["운영 서버 배포"]
PROD --> SMOKE{"Smoke Check 통과?"}
SMOKE -->|예| OK["배포 완료"]
SMOKE -->|아니오| FIXDEPLOY["원인 수정 후 재배포"]
FIXDEPLOY --> RUN
linkStyle default stroke:#d32f2f,stroke-width:2px;
16.4 수동 배포 workflow 내부 실행 순서
Gitea에서 itam_production_deploy.yml을 수동 실행하면 내부적으로는 아래 순서로 진행된다.
- SSH agent를 설정한다.
- 필수 Variables / Secrets가 모두 있는지 확인한다.
- 운영용
.env.deploy파일을 생성한다. - 운영 서버에 접속한다.
PROD_DEPLOY_PATH를 생성한다.- 저장소를 clone 또는 fetch 한다.
- 선택한 브랜치의 최신 커밋으로 checkout, reset, clean 한다.
uploads,logs/nginx디렉토리를 준비한다..env.deploy를 서버의.env로 복사한다.docker compose -f docker-compose.prod.yaml config를 수행한다.docker compose -f docker-compose.prod.yaml up -d --build를 수행한다.docker compose ps를 확인한다./health,/, backend/readysmoke check를 수행한다.
아래 다이어그램은 workflow 내부 실행 순서다.
flowchart TD
A["수동 배포 시작"] --> B["SSH agent 설정"]
B --> C["Variables / Secrets 검증"]
C --> D{"필수 값 누락 여부"}
D -->|예| E["즉시 실패 후 설정 보완"]
D -->|아니오| F[".env.deploy 생성"]
F --> G["운영 서버 SSH 접속"]
G --> H["배포 경로 생성"]
H --> I["git clone 또는 fetch"]
I --> J["지정 브랜치 checkout / reset / clean"]
J --> K["uploads / logs/nginx 준비"]
K --> L[".env 업로드 및 권한 설정"]
L --> M["compose config 검증"]
M --> N{"compose config 성공?"}
N -->|아니오| O["설정 수정 후 재실행"]
N -->|예| P["compose up -d --build"]
P --> Q["docker compose ps 확인"]
Q --> R["/health, /, /ready smoke check"]
R --> S{"smoke check 성공?"}
S -->|예| T["운영 배포 완료"]
S -->|아니오| U["원인 분석 후 재배포"]
linkStyle default stroke:#d32f2f,stroke-width:2px;
16.5 실패 후 검증 및 재배포 플로우
실패가 났다고 해서 항상 같은 방식으로 다시 배포하면 안 된다.
실패 지점별 판단은 아래처럼 나눈다.
- Code Check 실패: TypeScript, build, compose 문법 문제를 먼저 수정한다.
- Docker Build Check 실패: Dockerfile, 정적 자산 복사, 운영 빌드 컨텍스트 문제를 수정한다.
- Deploy 단계 실패: SSH, Gitea 변수, 서버 권한, 경로, git 접근, Docker 권한을 수정한다.
- Smoke Check 실패: Nginx 프록시, backend readiness, 외부 DB 연결, 앱 런타임 오류를 수정한다.
즉 재배포 전 판단 기준은 아래와 같다.
CI 실패 -> 로컬 코드 / 설정 수정 후 재커밋
배포 실패 -> 서버 환경 또는 배포 설정 수정 후 수동 재실행
Smoke Check 실패 -> 앱 / 프록시 / DB 상태 수정 후 수동 재실행
운영 관점에서는 아래 순서를 지키는 것이 안전하다.
- 실패 지점 확인
- 원인 수정
- 같은 실패가 다시 나는지 좁은 범위로 재검증
- 그 다음에만 수동 배포 재실행
16.6 문서 기준 요약
현재 ITAM 운영 배포는 아래 원칙으로 이해하면 된다.
- 수정은 로컬에서 한다.
- 배포 기준점은 Gitea에 올라간 커밋이다.
- 운영 반영은 Gitea 수동 workflow 실행으로 한다.
- 초기 배포, 일반 재배포, 실패 후 재배포는 분기 기준이 다르다.
- 최종 성공 여부는 컨테이너 상태가 아니라 smoke check까지 통과했는지로 판단한다.
15.3 프런트 프록시가 의심될 때
확인 위치: vite.config.ts, docker-compose.yaml
다음 두 설정이 유지되는지 확인한다.
vite.config.ts
const proxyTarget = process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:3000';
docker-compose.yaml
VITE_DEV_PROXY_TARGET: http://backend:3000
이 둘 중 하나라도 바뀌면 Docker 안에서 화면 데이터가 다시 안 보일 수 있다.
17. 현재 기준 재현 절차 요약
가장 짧게 정리하면 아래 순서다.
- Gitea에서 소스를 클론한다.
- Windows PowerShell에서 프로젝트 루트로 이동한다.
.env에 외부 MySQL 정보를 작성한다.- Docker Desktop + WSL 통합 또는 WSL 내부 Docker 사용 가능 상태를 만든다.
start_docker_wsl.ps1를 실행한다.http://localhost:3000/api/assets/master가 200인지 확인한다.http://localhost:8080/api/assets/master가 200인지 확인한다.- 브라우저에서
http://localhost:8080을 열어 실제 데이터 표시를 확인한다.
18. 현재 최종 결론
현재 저장소의 도커라이징 구조는 실무 표준에 맞는 무상태 앱 컨테이너 + 외부 DB 구조다.
현재 핵심은 아래 세 가지다.
backend는 외부 MySQL에 직접 연결한다.frontend는backend:3000으로 API 프록시한다.- WSL 경로 변환 스크립트를 통해 Windows 한글 경로에서도 안정적으로 실행한다.
즉, 이 문서대로 진행하면 Gitea 소스만 받은 상태에서 지금과 같은 Docker 실행 구조를 재현할 수 있다.