Jenkins Maven Project와 Tomcat 연동
위 사이트에서 만든 Item을 복사하여 새로 만든다.
일단 지금은 war파일이 없음을 볼 수 있다.
참고로 docker-server에 접속하기 위한 명령어는 아래와 같다.
docker exec -it docker-server bash
hello-world.war 파일이 생성되었음을 알 수 있다
FROM tomcat:9.0
COPY ./hello-world.war /usr/local/tomcat/webapps
우리는 Tomcat 9.0.x 버전을 활용할 것이므로 tomcat:9.0으로 설정했다.
또한 hello-world.war 파일을 /usr/local/tomcat/webapps 밑에 저장함으로써 Tomcat에서 hello-world.war 파일이 수행될 수 있도록 만들겠다.
docker build -t docker-server -f Dockerfile .
Docker-Server 환경 자체를 Dockerfile 파일을 통해 Image로 만들 것이다.
명령어에 대해서는 Docker를 공부할 때 알아보자
"docker images" 명령어를 통해 존재하는 Image를 보면 docker-server라는 Image가 새로 생성되었음을 볼 수 있다.
이는 DooD 방식으로 Container를 생성했기 때문에 Host Machine 역할을 하는 Docker Desktop에서 docker-server Image를 생성한 것과 같은 역할이 수행되었기 때문이다
docker run -d -p 8081:8080 --name mytomcat docker-server:latest
필자는 Web 개발을 하면서 8080 Port를 많이 활용하기 때문에 8081 Port를 통해 접근할 수 있도록 했다.
/hello-world를 붙이는 것은 Tomcat의 설정과 관련된 내용이다.
Tomcat의 기본 설정은 webapps 디렉터리를 기본 Directory로 간주하여 HTML 파일을 Search 한다.
우리는 위 설정에서 webapps/hello-world.war가 저장되도록 설정을 해놓았다.
즉, 실행되고 있는 hello-world 프로그램은 "/hello-world"로 입력해야지만 프로그램의 "/" Path로 접근할 수 있게 되는 것이다.
<Context>
명령을 통해 Tomcat의 Root Directory를 변경시켜줄 수도 있는데, 이는 Tomcat에 관련된 내용이니 여기선 넘어가겠다.
docker build --tag=cicd-project -f Dockerfile .
docker run -d -p 8081:8080 --name mytomcat cicd-project:latest
중간 실수는 무시하자.(Container 다시 생성하기 너무 귀찮아요 ㅠㅠ)
docker stop mytomcat
docker rm mytomcat
docker rmi [삭제할 Image ID]
Configuration > 빌드 후 조치 > Send build artifacts over SSH에서 Exec Command를 추가할 것이다.
위 사진에서 볼 수 있듯 0번에서 상기했던 명령어들이 그대로 입력되어 있다.
단지 docker build ~ 명령 이후 세미콜론(;)을 붙여 줘 2개의 명령어가 따로 실행되어야 함을 명시해줬다.
여기에서 가장 중요한 것은 "-d"를 docker run 뒤에 붙이는 것이다.
만약 -d Option을 붙여주지 않는다면 Daemon으로 Container가 실행되는 것이 아니라 일반 Process로 실행될 것이다.
이게 무슨 큰일이냐 싶겠지만 생각보다 심각한 일인 게 Build 수행이 완료되었는지 확인할 수가 없다.
Jenkins에서는 SUCCESS 문구가 떠야 성공임을 확인할 수 있는데, docker run 명령어를 통해 일반 Process가 계속 실행되고 있는 중이므로 CI/CD 과정이 Finish 되었음을 확인할 수 없다.
docker run 명령어 수행이 완료되어야지 command까지 모두 처리하고 Jenkins를 통한 배포가 완료되었음을 확인할 수 있을 텐데 Command 수행 과정에서 Container는 끝나면 안 되기 때문에 배포가 끝나지 않는 것이다.
따라서 -d를 통해 Daemon으로 처리함으로써 Console에서는 배포된 애플리케이션이 실행되는 것에 대한 Log를 보지 않도록 하는 것이다.
여기에서 발생하는 문제점이 1가지가 있다.
지금 생성한 Item을 다시 빌드시켜보자. 그렇다면 아마 노란색 느낌표와 함께 Build가 실패할 것이다.
왜 그럴까?
이는 CMD창에서 docker conatiner를 실행하는 명령어를 입력해보면 된다.
이게 무슨 말이냐, 이미 docker-server라는 이름의 Container가 존재하므로 또다시 docker-server라는 Container를 생성할 수는 없다는 의미이다. 이런 상황은 Jenkins에서 Container를 생성할 때도 똑같이 벌어진다.
Jenkins를 활용하더라도 사용하는 방법에 차이가 있을 뿐 위 CMD 창에 docker run ~ 명령어를 입력하는 것과 동일한 과정이 수행되는 것이고, 당연히 오류 원인도 같을 것이다.
따라서 이를 해결하기 위해선 빌드를 수행하기 이전 존재하는 Docker Container 중 동일한 이름이 있는지 확인한 뒤 만약 동일한 이름의 Container가 존재한다면 이를 중지시키고 메모리 상에서 삭제해야 한다.
우리는 이 과정을 1번 과정(Mytomcat Container 삭제 & 만들었던 이미지 삭제)에서 수동으로 수행했던 것이다.
하지만 이를 수동으로 한다는 것은 자동화와는 거리가 먼 작업이다.
이제부터 이런 문제를 해결하기 위한 방법을 알아보자