spring 프로젝트 docker로 배포하기

주민·2023년 9월 7일
0

Docker

목록 보기
3/3

Docker로 배포하기

AWS - EC2 서버와 local에 docker를 설치하고 local에서 프로젝트 jar 파일을 실행하는 이미지를 만들어 docker hub에 업로드하고 EC2 서버에서 받아와 실행하는 방식이다.

※ EC2 : AWS에서 사용자가 가상 컴퓨터를 임대 받아 그 위에 자신만의 컴퓨터 애플리케이션들을 실행할 수 있게 한다.

환경

환경마다 작성해야되는 내용이 조금씩 다르니 환경에 맞는 내용으로 진행하는 게 좋다.

  • Spring Boot
  • java 17
  • gradle
  • window
  • EC2: Ubuntu

순서

  1. local에 docker 설치
  2. EC2 인스턴스를 Ubuntu로 생성
  3. 1에서 생성한 서버에 docker 설치
  4. 설정 파일 추가(Dockerfile,build.gradle)
  5. 빌드하여 jar 파일 생성
  6. docker hub 회원가입& local에서 로그인
  7. jar 파일를 이미지로 생성 & 만든 이미지를 docker hub에 push
  8. EC2 서버에서 다운로드
  9. 배포 확인
    + RDS 연결

도커 기본

데이터 또는 프로그램을 격리시키는 기능을 제공하는 소프트웨어로 보통 배포, 작업 환경(아파치, mysql 등) 공유, 한 사람이 여러 프로젝트를 진행해야 할 때 사용한다.

  • 이미지 : 컨테이너를 만드는 데 사용하는 틀로 docker hub에 다운로드&업로드가 가능하다.
  • 컨테이너 : 이미지를 통해 만들며 별도의 서버인 것처럼 사용할 수 있게 만든 것으로 여러 개를 만들 수 있다.

코드

확인 & 삭제는 docker desktop에서 가능하나 대부분의 명령은 CMD(터미널)에서 진행

# 조회(실행 중인 것만)
docker ps

# 전체 조회
docker ps -a

# 컨테이너 생성 및 실행
# -d : 백그라운드로 실행
# 이미지가 없어도 자동으로 다운로드 됩니다. 
docker run --name {컨테이너명} -d {이미지명}

# 실행
docker start {컨테이너명}

# 중지
docker stop {컨테이너명}

# 삭제(실행 중일 때는 불가능함 중지 후 삭제)
docker rm {컨테이너명}

# 이미지 조회 / 삭제
docker image ls
docker image rm {이미지명}

# 포트 설정
# -p : 포트 설정용
# 8080:8080 = 호스트 포트 : 컨테이너 포트 => 컨테이너 포트는 다 달라야 함
docker run --name {컨테이너명} -d -p 8080:8080 {이미지명}

# 환경 변수 설정
# -e : 환경 변수 설정용/변수 별로 한번 씩 써줘야 함
# DATABASE=test => 환경변수명 = 들어가야 하는 값
docker run --name {컨테이너명} -d -e DATABASE=test -e USERNAME=root {이미지명}

# 최종 실행
# -dit : 백그라운드에서 실행 및 키보드를 통해 컨테이너 내부의 파일 시스템을 조작
docker run --name {컨테이너명} -dit -p 8080:8080 -e DATABASE=test -e USERNAME=root {이미지명}

백엔드 개발자의 경우 회사 내에 공유된 이미지를 받아 프로젝트를 진행하는 정도만 하기 때문에 컨테이너 관리 정도까지만 알아두면 된다 합니다. 다만, 회사마다 조금씩 다르고 대기업에 경우에는 도커를 많이 쓴다고 합니다.


1. EC2 Ubuntu 인스턴스 생성

AWS에 EC2을 검색해 아래 순서에 따라 만들고 인스턴스 시작을 해주면 된다.
※ 키 페어로 만든 .pem 공유되면 안되는 파일이니 잘 저장해 둘 것!


2. EC2 서버에 docker 설치

mac은 터미널에서 가능하지만 window는 리눅스 SSH 접속 툴이 필요하다.
여기서는 Putty를 사용했다.

Putty 사용법

※ mac을 사용하거나 다른 툴을 사용한다면 Putty 부분을 볼 필요는 없다.
window 기준 다른 SSH

설치 및 기본 세팅은 여기를 봐주세요

PuTTYgen을 먼저 키고 Load에서 . pem 파일을 가져오고 Generate를 선택하면 ppk 파일로 변환된다.

IPv4를 입력하고 변환한 ppk 파일을 AUth - Credentials - private key 올리고 open을 눌러준다.
(* 저장을 하지 않으면 다시 켰을 때 전 내용으로 돌아간다. 수정 시 저장을 계속 해줘야 한다.)

login as에는 이름을 입력하면 되는데 아무런 설정도 하지 않은 경우에는 ec2-user , admin, root , ubuntu , bitnami 중 하나이다. 지금은 ubuntu 였다. > 참고

docker 설치

참고블로그

ubuntu@ip-172-31-43-244:~$

putty에 뜬 로그인 정보가 입력한 이름@ip 주소가 맞다면 아래 명령어를 순서대로 입력해주면 된다.

# 패키지 업데이트
sudo apt update

# https관련 패키지 설치
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# docker repository 접근을 위한 gpg 키 설정
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# docker repository 등록
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

# 다시 업데이트
sudo apt update

# 도커 설치
sudo apt install docker-ce

# 도커 설치 버전 확인
docker --version

3. 설정 파일 추가(Dockerfile,build.gradle)

프로젝트 폴더 안에 Dockerfile 파일 생성
(* 대소문자까지 동일해야 하고 확장자는 없이 만든다)

설정 파일 추가

Dockerfile

FROM openjdk:17-jdk
WORKDIR /app
COPY build/libs/test.jar app.jar
EXPOSE 8080

CMD ["java", "-jar", "app.jar"]
  • FROM : 토대가 되는 이미지 지정
    * 사용하는 java 버전으로 맞출것
  • WORKDIR : RUN, CMD, ENTRYPOINT, ADD, COPY에 정의된 명령어를 실행하는 작업 디렉터리를 지정
  • COPY : 기존 파일을 복사하여 이미지에 파일이나 폴더를 추가
    - build/libs/test.jar => jar 파일 위치와 파일명
    - app.jar => 복사된 파일명
  • EXPOSE : 통신에 사용할 포트
  • CMD : 컨테이너를 실행할 때 실행할 명령어를 지정
    -app.jar 파일 실행

build.gradle

jar {
    enabled = false
}

위 설정 없이 빌드를 하면 기본.jar / plain.jar 파일 두개가 생성되는데 jar가 2개면 도커 이미지가 생성되지 않을 수도 있기 때문에 추가해줘야 한다.


4. jar 파일 생성

CMD에서 프로젝트 폴더로 위치를 이동하고 빌드하여 jar 파일을 생성한다.
-x test : test를 진행 X

C:\Users\user>cd C:\Users\user\Desktop\PetNexus
C:\Users\user\Desktop\PetNexus>gradlew clean build -x test

BUILD SUCCESSFUL 가 뜨면 성공


5. docker hub 회원가입& local에서 로그인

docker hub 회원가입

https://hub.docker.com/

위 URL로 들어가 회원가입을 하고 로그인 ID와 password, ID를 확인한다.

※ docker hub 화면

local 로그인

CMD에서 'docker login -u {ID}' 를 입력하면 Password를 입력할 수 있다. 둘 다 맞게 입력해주면 내 docker hub에 작업이 가능하다.
(* ID 또는 로그인 ID(이메일)을 입력해주면 된다.)


6. jar 파일을 이미지로 생성 & 만든 이미지를 docker hub에 push

이미지 생성

# docker build -t {ID} / {이미지명}:{태그} {Docker 파일 위치}
docker build -t test/test_image:1.0 C:\Users\user\Desktop\test

docker desktop에 아래 내용으로 만들어진다.
Name => user/test_image
Tag => 1.0

※ tag를 지정하지 않으면 자동으로 latest 으로 저장되며 push할 때 tag를 입력하지 않아도 된다.

docker hub push

5번에서 로그인한 docker hub 계정에 push 한다.

# docker push  {ID}/[{이미지명}:{태그}]
docker push test/test_image:1.0

올라간 건 docker hub - Repositories에서 확인 할 수 있다.


7. EC2 서버에서 다운로드

이제 docker hub에 있는 이미지 서버에 받아오기만 하면 된다.
다만, 지금까지 오류 없던 이미지가 다운로드 후에 오류가 나는 경우에 많으니 local에 한 번 다운로드 & 실행해보고 하는 것이 좋다.

오류 > 컨테이너가 계속 Exited 상태로 뜨는 경우

2번에서 세팅한 Putty를 실행하고 로그인한다.
※ 리눅스에서는 꼭 먼저 sudo를 써줘야 하는데 번거롭다면 sudo su - 을 써서 root로 이동하면 sudo를 쓰지 않아도 된다.

login as : ubuntu

sudo docker login -u {ID}
Password : 
------------------------------------------------------------------
# 컨테이너명  : spring
# 포트 : 8080 (뒤에 있는 포트 사용)
# 이미지명 : test/test_image:1.0

sudo docker run --name spring -d -p 8080:8080 test/test_image:1.0

docker ps 로 컨테이너를 조회 해봤을 때 만든 이미지가 Up 상태로 나오면 된다.
※ 처음에는 Up 상태인데 몇 초 정도 지나면 Exited 상태로 바뀌는 경우가 많다. 여러 번 조회 해보는게 좋다.


8. 배포 확인

아래 URL로 들어가 페이지가 나오면 성공이다.

http:// 퍼블릭 IPv4 주소 : 포트번호
http://13.124.143.109:8080

오류 > 사이트에 연결할 수 없음


RDS 연결

RDS 연결은 코드를 따로 수정 할 필요는 없고 RDS를 구매하고 인텔리제이에 연결하면 된다. 이 상태로 jar 파일을 만들어 이미지를 만들면 끝이다.

※ RDS : 아마존 웹 서비스(AWS)가 서비스하는 분산 관계형 데이터베이스

RDS 구매 하는 방법은 여기 블로그 참고

그리고 application.properties에 아래 3가지를 수정해주면 된다.

spring.datasource.url=jdbc:mysql://{엔드포인트}:3306/{DB 이름}
spring.datasource.username={RDS 사용자 이름}
spring.datasource.password={RDS 암호}

오류

#컨테이너 생성 오류

이미지를 다운로드 받으면 컨테이너가 생성되는데 몇 초후에 컨테이너의 상태가 Up -> Exited로 변경되는 이유는 이미지가 잘 못 되었거나 코드를 잘 못 입력한 경우이다.

오류의 내용이 표시되지 않기 때문에 로그를 찍어서 확인해봐야한다.

docker logs {컨테이너명}

환경변수

log를 찍어보니 username을 찾지 못한다고 나온다.
인텔리제이에 환경변수로 설정한 값들이 EC2 서버에서는 없어서 발생한 문제로 서버에도 환경변수를 설정해주면 된다.

# application.properties

spring.datasource.username=${NAME}
spring.datasource.password=${PASSWORD}

환경변수를 설정하는 방법은 여러가지가 있지만 가장 간단한 방법은 컨테이너 생성시(run) 입력해주는 것이다.

# 리눅스 서버
# -e : 옵션 설정, 건 마다 적어줘야 한다.
# -e {환경변수 이름}={적용되는 값}

sudo docker run --name spring -d -p 8080:8080 -e NAME=admin -e PASSWORD=pwd test/test_image:1.0

이렇게 하면 보안이 중요한 데이터들이 이미지가 올리지 않고 컨테이너를 만들 수 있다.


#웹페이지 연결 불가

이미지 만들어서 docker hub에 올리고 EC2 서버에서 컨테이너가 Up 상태인거 까지 확인했는데 접속하면 로딩이 오래 걸리고 결국에는 시간이 오래 걸려 연결할 수 없다는 내용이 뜬다.

사이트 연결 문제는 AWS - ES2 에 인바운드 규칙을 추가/수정 해주면 된다.

※ ES2 - 인스턴스 - 사용중인 인스턴스 ID 클릭 - 하단의 보안 - 보안그룹

※ 인바운드 규칙 - 인바운드 규칙 편집 - 규칙 추가

사용자 지정 TCP / 사용하는 포트(8080) / Anywhere-IPv4 를 입력해주면 위 그림 처럼 나온다. 그리고 하단에 규칙 저장을 하고 페이지를 새로고침하면 잘 나오는 것을 확인 할 수 있다.

docker-compose 사용

docker-compose를 사용하여 리눅스 & 스프링 연동하여 설치


참고 블로그

전체적인 docker 배포 하는 방법

https://lucas-owner.tistory.com/48

es2에 docker 설치

https://everydayyy.tistory.com/121

putty연결

https://bbeomgeun.tistory.com/73

0개의 댓글