easycode

[배포] SpringBoot+Docker+AWS lightsail로 애플리케이션 서버에 배포하기(feat. m1) 본문

AWS

[배포] SpringBoot+Docker+AWS lightsail로 애플리케이션 서버에 배포하기(feat. m1)

ez() 2023. 12. 7. 15:40

프로젝트 우연에서... GCP 프리티어가 끝나고 우린 인프라 난민이 됐다.

기능 개발은 됐는데, 테스트를 못한다. 포스트맨으로 테스트하는 것과 실제 배포해서 하는 건 생각보다 큰 차이가 있었다. 우린 그렇게 인프라 난민이 됐고... 당장 테스트는 해야 하고... 인프라 난민 구출 작전을 세웠다.

우리 kanbanboard의 가장 큰 문제

정규 회의에서 이번 인프라 담당을 누가 할 것인지 정할 때, 나도 너무 해보고 싶었지만 처음 해보는 것에 대한 두려움은 조금 있었다. 그러나 해보면 정말로 좋은 경험이 될 것 같았고, 한 번 CI/CD를 담당했던 팀원들이 모르는 거 있으면 도와준다고 걱정하지 말라고 하길래 이번 인프라 담당은 내가 하게 되었다.

어떤 걸 사용할까 하다가 aws의 lightsail이 3개월 간 프리티어도 있고, aws의 RDS처럼 쓴 만큼 확장되고 청구되는 방식이 아닌 정해진 용량 내에서만 사용 가능하도록 했다는 점이 그나마 과금을 덜할 것 같아 aws lightsail로 배포하기로 했다. (aws는 항상 청구되는 영수증에 대한 두려움이 있다... 괴담이 너무 많아)

서버에 배포 성공하고, api 통신이 되는 걸 확인했을 때 얼마나 기뻤는지 모릅니다. 저도 했으니 이 글을 따라오는 여러분도 하실 수 있을 거에요! (이제 CI/CD 남았다)

 

 

그래서 오늘은 Springboot 애플리케이션을 Docker를 이용해 AWS lightsail 서버에 배포하는 방법을 포스팅 해보겠습니다. 이 방법은 수동으로 서버를 켜서 배포하는 방법이라 git merge를 통해 새로운 버전의 애플리케이션이 나오면 해당 파일을 다시 서버에 배포해야 한다는 점에서 귀찮긴 합니다. 이건 CI/CD를 통해 해결할 수 있습니다.

제 환경은 mac M1, Springboot는 gradle, JDK 11입니다. Docker는 설치가 되어 있다는 가정 하에 진행합니다.

lightsail은 x86_64(amd64) 아키텍처와 호환됩니다. 윈도우는 상관없지만 m1과 같이 arm64 아키텍처인 경우 추후에 도커에 빌드할 때 플랫폼을 amd64로 지정해줘야 하더라고요. 만약 윈도우시라면 해당 명령어를 빼고 사용하시면 됩니다!

누군가에게 제 글이 도움이 되었으면 합니다.

 

 


Springboot 애플리케이션 빌드해서 jar 파일로 내려 받기

도커에 빌드할 jar 파일이 있어야 합니다. 저는 터미널에서 명령어를 통해 생성해 줬습니다.

터미널에서 cd 명령어를 통해 해당 Springboot 프로젝트 파일로 들어가 주세요 (윈도우는 cmd)

cd 프로젝트 위치

 

자신의 운영체제에 맞춰 아래 명령어를 사용해 주세요.

맥 : ./gradlew build
윈도우 : ./gradlew.bat build

위 명령어를 통해 jar 파일을 생성합니다.

permission denied는 언제까지 보게 될까

저는 permission denied가 떠서 sudo chmod로 잠깐 바꿔주고 사용했습니다. 하지만 chmod 777은 모든 권한을 열어주는 것이기 때문에 나중에 꼭 다시 chmod로 변경해 주세요!!

빌드가 되면 jar 파일이 나옵니다.

저는 프로젝트 폴더 내에 /build/libs 안에 jar 파일이 나왔습니다.

 

 


Dockerfile 작성하기

다른 포스팅엔 다들 Dockerfile을 작성하라고 하는데, 저는 이걸 도대체 어디에 무슨 확장자로 작성해야 할지를 모르겠더라고요. 그래서 구글 bard에게 물어봤더니 이렇게 답변해 주더라고요.

Dockerfile은 텍스트 파일로 작성할 수 있습니다. 일반적으로 텍스트 편집기 또는 IDE를 사용하여 작성합니다.
Dockerfile을 작성할 위치는 자유입니다. Lightsail 인스턴스에서 작성할 수도 있고, 로컬 컴퓨터에서 작성할 수도 있습니다.

그래서 처음엔 텍스트 파일로 했죠... 그랬더니 나중에 빌드할 때 자꾸 Dockerfile을 못 찾는 거 아니겠어요?

뭘까... 뭐가 문제일까 하고 체크해보다가 어떤 글을 보니 Dockerfile은 .txt 확장자를 사용하지 않는다고 하더라고요. 그리고 IDE에서 해당 파일이 도커 파일로 인식을 하는지 따져보라는 하길래 파일 확장자를 .txt에서 없애 주었더니 IDE가 인식했습니다!!!!!!

 

 

 

Dockerfile (확장자는 없어도 됩니다!! 그리고 DockerFile이 아닌 Dockerfile입니다!!!)

FROM --platform=linux/amd64 openjdk:11-jdk
ARG JAR_FILE=build/libs/yeon-0.0.1-SNAPSHOT.jar
ADD ${JAR_FILE} wooyeon.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "wooyeon.jar"]

위와 같이 dockerfile을 작성해 줍니다. 만약 arm64 아키텍처(m1, m2...)가 아니라면 --platform=linux/amd64 부분은 빼주세요!

위에서 말했듯이 저는 arm64 아키텍처로 lightsail에서 지원하는 아키텍처와 호환되지 않아 지정했습니다.

 

 

참고로 도커파일을 작성할 때 주의사항은 아래와 같습니다.

  • 프로젝트 폴더 최상위 위치(루트)에 작성하기
  • jar 파일 위치 정확하게 작성해 주기
  • 이름은 Dockerfile로(DockerFile 안됨)

 

무슨 뜻인지 살펴보면,

FROM --platform=linux/amd64 openjdk:11-jdk

배포하는 jdk 버전은 11입니다.

ARG JAR_FILE=build/libs/yeon-0.0.1-SNAPSHOT.jar

JAR_FILE이라는 변수로 .jar의 위치를 저장합니다. 아까 생성된 jar 파일이 있는 위치를 입력해 주세요.

ADD ${JAR_FILE} wooyeon.jar

JAR_FILE에 도커 이미지로 사용할 이름을 입력합니다. jar의 이름은 yeon-0.0.1-SNAPSHOT.jar이지만 도커에서는 wooyeon으로 출력됩니다.

EXPOSE 8080

접근포트는 8080입니다.

ENTRYPOINT ["java", "-jar", "wooyeon.jar"]

docker 이미지가 컨테이너에 올라갈 때 실행되는 명령어입니다.

 

 


로컬(내 PC)에서 명령어를 통해 Docker image를 빌드하기

 

Dockerfile이 있는 프로젝트 폴더에서 터미널을 켜고, 아래 명령어를 입력합니다.

docker build --platform linux/amd64 -t 도커이미지로사용되는이름:tag명 . -f Dockerfile

윈도우 유저시라면 --platform=linux/amd64은 빼주세요! 저는 m1 호환성 문제로 인해서 넣었습니다.

도커 빌더가 지원하는 플랫폼. lightsail은 x86_64(amd64)와 호환된다.

명령어 예시는 다음과 같습니다.

docker build --platform linux/amd64 -t wooyeon:amd . -f Dockerfile

저는 permission denied가 나서 앞에 sudo를 붙여서 해줬습니다.

sudo docker build --platform linux/amd64 -t wooyeon:amd . -f Dockerfile

 

저는 당시에 확장자를 혹시 몰라 .dockerfile을 붙여 줬습니다. 하지만 없어도 됩니다!

제대로 실행됐다면 다음과 같은 화면이 나타납니다.

 

docker images

위 명령어를 통해 제대로 도커 이미지로 올라가 있는지 확인해 주세요. 혹은 DockerDesktop을 이용해서도 확인 가능합니다.

DockerDesktop - Builders에 들어가면 아래와 같이 나와 있습니다.

 


Docker hub에 푸시해 주기

lightsail의 컨테이너에서 해당 도커 이미지를 실행시키기 위해선 dockerhub에 해당 이미지를 푸시해야 합니다.

먼저 dockerhub에 가입 후, 로그인해 주세요.

여기서 User 위에 있는 검은색 부분이 dockerhub유저명(=닉네임)입니다. 꼭 기억해 두세요!

 

 

다시 터미널로 돌아와서, 도커에 로그인해 줍니다.

docker login

도커에 로그인이 됐다면 Login Succeeded가 뜹니다.

 

아래 명령어를 통해 해당 도커 이미지에 태그를 부여해 줍니다.

docker tag 도커이미지이름:태그명 도커hub닉네임/도커이미지이름:태그명

 

예시는 다음과 같습니다.

docker tag wooyeon:amd 도커hub유저명/wooyeon:amd

 

 

이제 dockerhub에 푸시해 줍시다. 아래 명령어로 도커 허브에 푸시해 줍니다.

docker push 도커hub유저이름/도커이미지이름:태그이름

 

 

 


AWS lightsail에 도커 설치하기

aws lightsail 인스턴스에 있는 ssh 접속으로도 괜찮고, 터미널에서 명령어를 입력해서 접속해도 괜찮습니다.

 

2023.12.04 - [AWS] - [AWS] aws lightsail ubuntu root로 키 대신 비밀번호로 접속할 수 있도록 설정하기

 

[AWS] aws lightsail ubuntu root로 키 대신 비밀번호로 접속할 수 있도록 설정하기

현재 진행하고 있는 팀 프로젝트(우연)에서 이번엔 인프라를 담당하게 되어, aws lightsail을 구축하게 되었다. lightsail 구축 및 서배 배포를 기록으로 남겨 보려고 한다. 오늘 포스팅 할 주제는 첫

easyoungcode.tistory.com

 

ligthsail에 접속했다면, 도커를 설치해 줍시다.

sudo apt update
sudo apt install docker.io

 

도커가 제대로 설치 됐는지 hello-world를 통해 확인해 줍시다.

짜잔 Hello Docker!

 

 

확인했다면 도커를 실행시켜 줍시다.

sudo service docker start

 

 

 


Dockerhub에 빌드된 이미지를 AWS lightsail 서버에 배포하기

docker login

먼저 우리의 dockerhub 계정과 연결해 줍니다.

 

docker run -d -p 80:8080 도커hub유저이름/도커이미지명:태그명

 

 

성공 시 모습입니다.

 

docker ps

해당 명령어를 통해 현재 컨테이너로 실행된 도커 이미지를 볼 수 있습니다.

 

 


이제 도메인에 접속해 보면...!!!!

easy했죠?

 

 

짜잔 제대로 배포가 된 모습을 확인할 수 있습니다. 포스트맨을 통해 api 하나를 실험해봤는데 통신이 잘 되더라고요.

여기까지 따라오느라 고생하셨습니다. 다음 시간엔 배포하면서 제가 마주쳤던 오류들에 대해 포스팅해보겠습니다.

 

 

 


참고한 글

https://pinokio0702.tistory.com/160

 

[Springboot+Docker+AWSLightsail]애플리케이션 배포하기

안녕하세요. 이번 글은 제가 너무나 해보고 싶었던 Springboot+Docker+AWS조합으로 애플리케이션을 배포하는 공부를 해보려고 합니다. 유튜브 영상을 통해서 따라서 구현을 해보았고, 궁금한 점들은 D

pinokio0702.tistory.com

https://velog.io/@msung99/Docker-이미지-빌드-플랫폼-호환성-관련-에러-linuxamd64

 

[Docker] 이미지 빌드 플랫폼 호환성 관련 에러 (linux/amd64)

왜 로컬에서 잘 실행되던 Docker Image 가 클라우드 Linux 서버에서는 실행되지 않을까?

velog.io