개발 ON
  • [Network | Docker] jar 배포
    2024년 07월 07일 02시 10분 44초에 업로드 된 글입니다.
    작성자: 이주여이

    ✅ 진행은 root 계정이 아닌 배포할 도커 컨테이너의 관리자 계정으로 진행했다.(컨테이너 1개 당 각각 다른 관리자 계정을 가진다)

     

    (참고) 컨테이너 전용 계정 docker 그룹에 추가

    더보기
    $ usermod -aG ${그룹명 } ${계정명 }
    $ cat /etc/group # 그룹 및 그룹에 속한 계정 확인

    1. jar 추출

    1. Gradle - build - bootJar 더블 클릭!
    2. Project - build - libs - ${프로젝트명 }-0.0.1-SNAPSHOT.jar 오른쪽 클릭 - Open In - Explorer
    3. 해당 jar 파일을 원하는 곳으로 복사해둔다.(filezilla에서 쉽게 찾아 옮기기 위함 …)

    2. FTP 프로그램(Filezilla)을 통해 jar 파일 이동(Host PC)

    3. jdk 이미지 다운로드(Linux)

    jdk 버전은 구글에 검색하면 잘나오니 확인하고 다운로드 받도록 한다. 혹은 docker search ${이미지명 } 을 통해 검색한다.

     

    $ docker pull openjdk:17-alpine

    4. Dockerfile 생성(Linux)

    FROM openjdk:17-jdk-alpine
    ARG JAR_FILE=*.jar
    ADD ${JAR_FILE} app.jar
    EXPOSE 80
    WORKDIR /home/user5221
    VOLUME /home/download/
    ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"]

    5. docker build(Linux)

    $ docker build -t blog .

    6. docker run(Linux)

    $ docker run -d \
    > --name blog \
    > -p 3000:80 \
    > blog
    
    $ docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
    80eb44c2d36d   blog      "java -jar -Dspring.…"   16 seconds ago   Up 15 seconds   0.0.0.0:3000->80/tcp, :::3000->80/tcp   blog

    7. 확인(Host PC)

    💥 template might not exist or might not be accessible by any of the configured Template Resolvers

    검색해보니 기본적으로 jar 파일의 classpath의 기본 값은 public/, resources/, static/, templates/, META-INF/\*\*, \* 인데 IntellJ에서는 컨트롤러의 return 타입에 ‘/’가 1개 더 붙더라도 알아서 처리해주지만 jar 배포할 때는 처리해주지 않는다.

     

    2024-07-05T03:23:56.802Z ERROR 1 --- [p-nio-80-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] :
    Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
    [Request processing failed: org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/login],
    template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

     

    위와 같이 src/main/resources/templates 경로 뒤에 ‘/’가 붙기 때문에 컨트롤러에서 return 값으로 ‘/’를 붙여버리면 //${templates 내 파일명 } 이 되기 때문에 에러가 발생한다.

     

    따라서 컨트롤러에서 return 타입을 String으로 갖고있는 메소드들의 반환 타입들을 확인 후 return "/ ..." return 뒤에 ‘/’가 붙을 경우 아래와 같이 지워준다.

     

        // 변경 전
        @GetMapping("/login")
        public String login() {
            return "/login";
        }
    
        // 변경 후
        @GetMapping("/login")
        public String login() {
            return "login";
        }

     

     

    잘나오는 것을 확인할 수 있다!

     

    외부에서도 볼 수 있게 하고싶다면 docker run 할 때 지정했던 포트 번호를 공유기랑 가상 서버에 포트 포워딩 시켜주면 된다. 하는 방법은 이전 포스팅에서 많이 다뤄서 패스한다.

     

    PS. 다시 보니 도커 컨테이너 관리자 계정명은 user5221인데 포트는 3000..😅


    참고 레퍼런스

    https://velog.io/@hyunho058/Docker-docker를-이용한-jar파일-배포

    https://myserena.tistory.com/155

    댓글