S E P H ' S

[SpringBoot] Gradle Project 수동 배포 본문

Programing & Coding/Server 구축 및 CI&CD

[SpringBoot] Gradle Project 수동 배포

yoseph0310 2021. 11. 23. 17:09

(2023.07.22 추가)

조회수가 갑자기 늘어나서 몇자 적어본다. 우선 많이 찾아줘서 감사하다는 말씀드린다.

 

하지만 알아두셔야 할게 있다. 분명 이번이 첫 프로젝트일테고 급해서 따라만 하면 뚝딱 되는 것들을 많이들 찾으셨을 것이다. 일단 이 포스팅은 그러기엔 최적화 되어있다. 그러라고 썼으니까. 그래서 개념적, 원리적인 내용은 많이 부족하다. 참고하고 보시길 부탁드린다.

이 포스팅은 굳이 따지자면 Gradle Project 수동 배포라기보다는 Spring Gradle Docker image 만들기가 더 맞다. (심지어 조금만 더 생각해보면 도커를 사용한다면 이 글에 있는 것처럼 굳이 ubuntu 서버에 레포지토리를 클론해올 필요도 없다...) 도커를 사용하지 않고 스프링 프로젝트를 배포하는 방법을 찾고 싶다면 nohup 이라는 키워드로 검색해보길 바란다. 배포에는 정말 다양한 방법이 있다. 지금까지 Spring 프로젝트를 배포해본 방법들은 내가 해본것만 해도 엄청 많은 방법들이 있기 때문에 여러 방향으로 고민해보자.

 

또 한가지, 늘 배포에 대한 질문을 받게 되면 강조했던 것이 있다. 목적을 분명히 하세요!

팀 내의 프로젝트 일정과 전략에 맞춰서 가는 것이 중요하다. 서버나 인프라에 무게를 조금 더 두고 강조하고 싶다면 더 깊게 알고 쓰는 것을 추천드리고 그렇지 않고 단순 배포만 하고 기능에 더 집중하자는 방향이라면 배포가 되었구나 하고 넘어가시길 바란다. 

 

무엇이든 깊게 아는 것은 중요하다. 그러나 방향을 잡지 못하고 깊게 파고들어 이도저도 아닌 상황인 분들을 많이 본적이 있다. 목적을 분명히하고 깊게 파고드는 것과 아닌 것은 천지 차이이다. 물론 그렇지 못한 경우라도 교육과정 중이니 그 또한 의미있고 가치있는 시간일 테지만 너무 아깝지 않은가. 반드시 내가 배워가야겠다는 것은 하나쯤은 분명히 하고 팀원들과 공유하도록 하자. 그렇게 진행되는 세 번의 프로젝트 동안 프로그래밍과 개발에 대한 이해도는 엄청나게 향상된다.

 

만약 깊게 공부하지 못했다고 해서 잘못하고 있는 것이 아니다. 실제로도 항상 100% 만족이란 것은 없으니 부담없이 온전히 첫 프로젝트를 즐기셨으면 한다.


 

(이 포스팅은 EC2 인스턴스는 생성, spring boot 프로젝트가 만들어져 있다는 가정하에 시작합니다.)

 

SpringBoot 프로젝트를 AWS EC2 인스턴스에 배포하는 방법을 적어보려고 합니다.

 

수동으로 직접 배포해보는 과정을 거쳐야 Jenkins와 같은 자동 배포화 (CI/CD) 도구에도 더 익숙해질 수 있습니다.

 

이번 포스트에서는 두 가지 방법으로 배포해보겠습니다.

 

1. jar 파일 build

- EC2 인스턴스에 접속

ssh -i '발급받은키'.pem '사용자이름'@'도메인주소 or IPv4'

- Boot 프로젝트를 Git에 등록하고 그 프로젝트를 clone

 

Test 가 git clone 되었다.

 

- Test 로 접근

 

gradlew란 gradle wrapper 를 말하는 것으로 java나 gradle을 설치하지 않고도 빌드 할 수 있게 해주는 역할을 합니다.

밑의 명령어들을 차례로 수행하면 빌드가 됩니다.

sudo chown 777 ./gradlew
./gradlew build

gradlew build를 하게 되면 폴더에 build 파일이 생성이 되고 libs로 접근하면 jar 파일이 생성됩니다.

 

# 참고해야할 것

더보기

1. Ubuntu 환경에서 JAVA_HOME이 설정이 되지 않았다면 :compilejava 에러가 발생할 것입니다.

   Ubuntu 에 jdk를 설치해주고 JAVA_HOME을 지정해주면 해결됩니다.

 

2. 깃에 등록된 프로젝트 내 gitignore에 applicaion.properties(사용자에 따라 yml 등등이 될 수도 있다.)를 지정해줘서 build 시에 오류가 났었던 적이 있습니다. 반드시 properties 파일을 포함하고 build를 해주어야 합니다.

 

cd build/libs

java -jar '프로젝트명'-0.0.1-SNAPSHOT.jar

위의 명령어를 실행하면 spring boot가 실행되고 다음과 같이 나오면 '서버도메인 or 서버공인IP':8080으로 접속하여 접근이 되는지 확인해 봅시다.

 

 

 

2. Docker image 활용

- 프로젝트 루트 폴더에서 New - File - Dockerfile 생성 파일명이 중요합니다. 오타나지 않게 조심!

- Dockerfile 에 다음을 입력.

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

내용을 잠시 들여다보자면 open jdk java 8버전의 환경을 구성하고 ARG는 build 시점에 활용되는 변수선언문으로 JAR_FILE이라는 변수에 build/libs/*.jar라는 표현식을 담은 것이라고 보면 됩니다. 또한 이를 복사하여 app.jar 로 복사하고, ENTRYPOINT 명령어로 기존 jar 파일을 단순 실행하듯이 java -jar /app.jar 라는 jar 파일을 실행하는 명령어를 실행하면서 스프링부트가 올라갑니다.

 

- (2021.11.23 수정내용)

FROM openjdk:8-jdk-alpine
RUN apk add --no-cache tzdata
ENV TZ Asia/Seoul
COPY build/libs/promise-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

도커 이미지로 만들어 스프링부트를 구성하게 되면 도커 컨테이너의 시간이 표준시(UTC)로 설정되어 있을 것입니다.

물론 도커 컨테이너가 이미 만들어진 상태에서도 시간 설정을 바꿀 수는 있지만 만들때 부터 설정을 잡아주면 편할 것입니다.

RUN, ENV 명령어에 타임존을 Asia/Seoul 으로 설정합니다.

Jenkins 빌드 후 조치에서 COPY 문에서 ARG에 명명한 JAR_FILE을 읽어들이지 못해서 직접 파일명을 입력해주었습니다.

 

 

- 도커 허브

 

Docker Hub Container Image Library | App Containerization

Build and Ship any Application Anywhere Docker Hub is the world's easiest way to create, manage, and deliver your teams' container applications.

hub.docker.com

- 도커 허브에 가입한다. Github와 같이 Repository를 갖고 원격 저장소로 활용할 수 있습니다.

- 로그인 한 후 Create Repository를 해서 Repository를 하나 생성합니다.

- 간단히 Repo명을 설정하고 public을 유지한 채 create를 합니다.

- Dockerfile 빌드 (2021.11.23 수정)

 

이제 도커 파일을 빌드해보자.

 

docker build -t [사용할 이미지 이름] .

# ex
docker build -t lb-spring .

 

이렇게 하면 도커파일이 빌드됐고 이미지를 생성한 것입니다. 제대로 생성이 되었는지 다음 명령어를 실행하여 확인해봅시다.

 

docker images

# 별도로 sudo 명령어 없이 사용할 수 있도록 서버에서 설정하지 않았다면 
# sudo를 붙여서 docker 명령어를 사용해야합니다.
sudo docker images

 

이제 만들어진 도커 이미지를 도커 허브에 push 할 것입니다. 

docker login
docker tag [도커이미지이름]:latest [도커허브아이디]/[도커이미지이름]:latest
docker push [도커허브아이디]/[도커이미지이름]:latest

# ex
docker login -> 계정이 연동된 상태라면 바로 Login Success라는 메세지가 뜰 것입니다.
아니라면 도커 허브 계정명, PW를 입력하면 됩니다.

docker tag lb-spring:latest tjdytpq0310/lb-spring:latest
docker push tjdytpq0310/lb-spring:latest

도커 허브에서 확인해보면 새로운 레포지토리에 도커 이미지가 생성되었을 것입니다.

 

이제 서버에서 생성된 도커 이미지를 가져와서 실행만 시키면 됩니다.

docker run -d -p [호스트포트]:[컨테이너포트] [생성한 이미지이름]

# 예시
docker run -d -p 8080:8080 tjdytpq0310/lb-spring

 

Nginx 설정에 대해서는 다음 포스트에서 다루겠지만, 별다른 프록시 설정이 없다면 서버 도메인 : [실행된 도커 이미지 포트번호]로 접속하면 됩니다.

 

 

참고링크

https://cholol.tistory.com/489
https://blog.siner.io/2019/02/25/django-docker-custom-image/