ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쿠버네티스 - 도커 구성 후 어플리케이션 배포
    Back end/Server 2025. 8. 18. 16:32

    * Tomcat + JSP(+JNI) 앱을 Docker로 “폴더 배포”하기 — 완전 가이드

    대상: ve20 웹앱(JSP) + 네이티브 라이브러리(JNI, 라이선스 파일 포함)
    방식: WAR가 아닌 폴더(폭파형) 배포
    예시 IP: 192.168.213.132, 컨테이너 이름: ve20-container


    1) 프로젝트 구조(권장)

     
    /home/master/ve20-docker/
    └─ ve20/                      # ★ 이 폴더 자체를 webapps/ve20 로 배포
       ├─ WEB-INF/
       │   └─ lib/                # ★ 모든 JAR 여기에 (의존성 포함)
       ├─ jni/
       │   ├─ libVECodeRVMaker64.so
       │   ├─ MatrixCode-licensev2.cfg
       │   └─ VECodeRVMaker.ini   # 로그 경로 등 설정 파일
       ├─ barcode/                # 비어 있어도 됨(코드에서 mkdirs)
       ├─ ve20_test.jsp
       └─ ve10_test.jsp

    - JSP에서 “경로/디렉터리 보장” (중요)

     
    String p = application.getRealPath("/barcode/JNI_RVMakerBarcode_1.bmp");
    if (p == null) {
      String base = System.getProperty("catalina.base") + "/webapps" + request.getContextPath();
      p = base + "/barcode/JNI_RVMakerBarcode_1.bmp";
    }
    java.io.File parent = new java.io.File(p).getParentFile();
    if (parent != null && !parent.exists()) parent.mkdirs();

    INI(로그 경로) 수정

    컨테이너 경로로 변경:

     
    rootdir = /usr/local/tomcat/webapps/ve20/log

    2) 기존 배포 싹 정리

     
    # 컨테이너/이미지 정리
    docker rm -f ve20-container 2>/dev/null
    docker rmi -f ve20-app:1.0.* ve20-app:folder-* 2>/dev/null

    # 작업 폴더로 이동
    cd /home/master/ve20-docker

    # 폴더 배포라 WAR는 불필요(섞여있으면 혼란)
    rm -f ve20.war

    3) Dockerfile 작성

    베이스: tomcat:9.0-jdk17 (Ubuntu 24.04 기반)
    의존성: libstdc++6, libgcc-s1, libjpeg-turbo8 (없으면 대체 패키지 시도)

     
    cat > Dockerfile <<'EOF'
    FROM tomcat:9.0-jdk17

    # 네이티브 의존성(노블 계열: libjpeg-turbo8 우선, 없으면 폴백 시도)
    RUN apt-get update && \
        (apt-get install -y --no-install-recommends libstdc++6 libgcc-s1 libjpeg-turbo8 || \
         apt-get install -y --no-install-recommends libjpeg62 || \
         apt-get install -y --no-install-recommends libjpeg62-turbo || true) && \
        rm -rf /var/lib/apt/lists/*

    # 기본 웹앱 제거
    RUN rm -rf /usr/local/tomcat/webapps/* || true

    # ★ WAR 대신 '폴더(폭파형)' 배포
    COPY ve20/ /usr/local/tomcat/webapps/ve20/

    # JNI 배치 + 경로 설정
    COPY ve20/jni /opt/ve20/jni
    ENV LD_LIBRARY_PATH="/opt/ve20/jni:${LD_LIBRARY_PATH}"
    ENV JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/opt/ve20/jni"

    # INI 로그 경로를 이미지 빌드 시 보증
    RUN mkdir -p /usr/local/tomcat/webapps/ve20/log && \
        sed -i 's#^rootdir *=.*#rootdir = /usr/local/tomcat/webapps/ve20/log#' /opt/ve20/jni/VECodeRVMaker.ini

    EXPOSE 8080
    EOF

    4) 이미지 빌드 & 컨테이너 실행

     
    # 빌드
    docker build -t ve20-app:folder-1 .

    # 실행(기본)
    docker run -d --name ve20-container -p 8080:8080 ve20-app:folder-1

    (옵션) 라이선스가 머신ID/MAC 바인딩이면 테스트용:

     
    docker rm -f ve20-container 2>/dev/null
    # 호스트 네트워크 + machine-id 공유
    docker run -d --name ve20-container \
      --network host \
      -v /etc/machine-id:/etc/machine-id:ro \
      ve20-app:folder-1

    (옵션) 생성 BMP를 호스트에서 바로 보려면 barcode 폴더 마운트:

     
    docker rm -f ve20-container 2>/dev/null
    mkdir -p /home/master/ve20-out/barcode
    docker run -d --name ve20-container -p 8080:8080 \
      -v /home/master/ve20-out/barcode:/usr/local/tomcat/webapps/ve20/barcode \
      ve20-app:folder-1

    5) 동작 확인(생성 트리거 → BMP 확인)

     
    # JSP 호출(생성 트리거)
    curl -I "http://192.168.213.132:8080/ve20/ve20_test.jsp" || true
    # 또는
    curl -I "http://192.168.213.132:8080/ve20/ve10_test.jsp" || true

    # 로그에서 결과/에러 코드 확인
    docker logs --tail=200 ve20-container | egrep -i "retCode|license|Load JNI|Error Code"

    # BMP 확인(파일명/대소문자 정확히!)
    curl -I "http://192.168.213.132:8080/ve20/barcode/JNI_RVMakerBarcode_1.bmp"
    # (ve10_test.jsp가 jni1.bmp를 만들면 파일명 바꿔서 확인)

    컨테이너 내부에서도:

    docker exec -it ve20-container bash -lc 'ls -l /usr/local/tomcat/webapps/ve20/barcode || true'

     

    JSP 본문이 EUC-KR이면 내용 확인 시:

    curl -s "http://192.168.213.132:8080/ve20/ve20_test.jsp" | iconv -f euc-kr -t utf-8 | sed -n '1,120p'
    curl -s "http://192.168.213.132:8080/ve20/ve20_test.jsp" | iconv -f euc-kr -t utf-8 | sed -n '1,120p'

    6) 재배포 루틴(업데이트 시 매번)

     
    # 코드/INI/JSP 수정 후
    cd /home/master/ve20-docker
    docker rm -f ve20-container 2>/dev/null
    docker build -t ve20-app:folder-2 .
    docker run -d --name ve20-container -p 8080:8080 ve20-app:folder-2

    7) 로그 & 진단 치트시트

     
    # 컨테이너 표준 로그
    docker logs --tail=200 ve20-container
    docker logs -f ve20-container

    # 톰캣 파일 로그(컨테이너 내부)
    docker exec -it ve20-container bash
    ls -l /usr/local/tomcat/logs
    tail -f /usr/local/tomcat/logs/catalina.*.log

    # 앱 로그(우리가 INI로 지정한 경로)
    ls -l /usr/local/tomcat/webapps/ve20/log
    tail -n 200 /usr/local/tomcat/webapps/ve20/log/*.log 2>/dev/null

    환경 변수/네이티브 의존성:

    docker exec -it ve20-container bash -lc \
      'echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"; java -XshowSettings:properties -version 2>&1 | grep -i "java.library.path"'

    docker exec -it ve20-container bash -lc \
      'ldd /opt/ve20/jni/libVECodeRVMaker64.so | grep "not found" || true'

     

    => 다음은 master docker images -> worker images 로 전달 해보기

Designed by Tistory.