[Docker] Springboot + postgreSQL 프로젝트 Docker로 AWS EC2에 배포하기

winluck·2024년 2월 12일
0

Docker

목록 보기
1/3
post-thumbnail

처음으로 Docker를 활용해 토이 프로젝트를 원격 서버에 배포해보았고, 쉽지 않았기에 따로 정리해두려고 한다.

Docker-Compose 방식도 있었는데, 일단 초입부인 만큼 기본적인 것만 다루어보자.

2월 동안 Docker 환경에 대한 기본적인 적응 및 CI/CD를 적용해보는 것이 내 목표이다.

Docker란?

  • 소프트웨어 개발과 배포를 간소화하고 자동화하는 데 사용되는 오픈 소스 플랫폼
  • 애플리케이션 및 관련 의존성을 <컨테이너>라고 하는 격리된 환경에 패키징하여 신속하게 애플리케이션을 배포 및 확장할 수 있다.
  • 컨테이너는 가벼우며, 어느 환경에서나 동일하게 실행될 수 있도록 설계되었기에 서버가 돌아가는 환경에 크게 영향을 받지 않는다.

환경

  • 프로젝트 개발 환경: Macbook M1 Pro
  • 서버 배포 환경: AWS EC2 Ubuntu Server 20.04 LTS (HVM) x86
  • Springboot 환경: Gradle + Java 17 + Springboot 3.2.2
  • 데이터베이스: postgreSQL
  • 편의상 M1을 <내 컴퓨터>로, EC2를 <원격 컴퓨터>로 표현하겠다.

Dockerhub 로그인

Dockerhub 아이디가 없으면 새로 만들어야 한다.

위와 같이 Dockerhub 개인 화면에 접속했다면, 닉네임 및 비밀번호를 기억해두어야 한다.

이제 배포하려는 프로젝트의 루트 파일에 Dockerfile를 작성해야 한다.

Dockerfile 작성 및 빌드


# 기본 이미지는 jdk 17
FROM openjdk:17 

#빌드 시점에 사용될 변수를 정의 
#JAR_FILE은 빌드 컨텍스트 내의 jar 파일 경로를 지정하는 데 사용
ARG JAR_FILE=build/libs/*.jar 

# ARG에서 정의한 JAR_FILE 경로의 jar 파일을 컨테이너 내 app.jar로 복사
COPY ${JAR_FILE} app.jar

# 컨테이너가 시작될 때 실행될 명령어 정의
ENTRYPOINT ["java","-Dspring.profiles.active=docker", "-jar","app.jar"]

Dockerfile을 다 작성했다면, Springboot 프로젝트의 Terminal을 켜고 아래와 같은 명령어를 입력한다.

./gradlew clean build -x test
Springboot 프로젝트를 Gradle 기반으로 빌드한다. 단 테스트 코드는 배제한다.

docker login
dockerhub에 username 및 password로 로그인한다.

docker build --platform linux/amd64 -t [사용자ID]/[파일명] .
docker 파일을 특정 파일명으로 빌드하되, 플랫폼은 linux/amd64이다.
참고로 M1에서 EC2 Ubuntu x86로 Docker 프로젝트를 배포할 경우 반드시 플랫폼 관련 명령어가 존재해야 한다. 그렇지 않으면 에러가 발생한다.

docker push [사용자ID]/[파일명]
빌드한 Dockerfile을 Dockerhub에 Push한다.

application.properties

spring.datasource.url=jdbc:postgresql://[Docker host IP주소]:5432/[DB명]
spring.datasource.username=postgres
spring.datasource.password=[비밀번호]
spring.datasource.driver-class-name=org.postgresql.Driver

# JPA
spring.jpa.hibernate.ddl-auto=create # 기존에 존재하던 데이터가 있다면 create X
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.database=postgresql

우리는 EC2 Docker에 진입하여 Docker를 활성화한 후 PostgreSQL에게 할당되는 IP Address를 알아야 한다.
기본적인 상황이라 username이 postgres지만, 필요에 따라 다양한 권한을 가진 DB 유저를 구축해야 할 수도 있다.

원격 컴퓨터에서 Docker 빌드

Dockerfile이 성공적으로 빌드 및 Push되었다면 EC2 Ubuntu로 이동한다.

ssh -i [키 페어 파일명] ubuntu@[할당받은 탄력적 IP]
EC2 인스턴스 생성 시 내려받은 키페어 파일명 및 탄력적 IP를 활용해
원격 컴퓨터에 접속한다. 인바운드 설정 등은 생략한다. (8080 포트)

sudo apt update
sudo apt install docker.io
원격 컴퓨터 Ubuntu를 업데이트하고 docker를 설치한다.

docker run --name [postgresql 컨테이너명] \
-p 5432:5432 \
-e TZ=Asia/Seoul \
-e POSTGRES_PASSWORD=[비밀번호] \
-d postgres

postgreSQL 이미지를 설정대로 다운로드받은 후 컨테이너화한다.
비밀번호는 application.properties(yaml)에 존재하는 spring.datasource.password과 동일해야 한다.

postgreSQL 컨테이너화가 성공했다면 추가적인 정보를 얻어야 한다.
나는 ddl-auto create이기 때문에 postgreSQL 컨테이너에 진입하여 데이터베이스를 새로 생성해주었다.

docker exec -it [컨테이너 ID] bash
psql -U postgres
exec 명령어로 외부에서 컨테이너로 진입하고, 위에서 설정한 비밀번호를 입력한 뒤 create database [데이터베이스명]으로 DB를 새로 생성한다.

postgreSQL 컨테이너에게 할당된 Docker Host IP주소를 확보하자.

docker inspect [postgresql 컨테이너명] | grep IPAddress
inspect 명령어를 통해 컨테이너의 상세 정보 중 컨테이너에게 도커가 할당해준 Host IP주소를 확인하고, 해당 값을 application.properties(yaml)의 spring.datasource.url에 채워넣는다.

docker run -d --name [Springboot 컨테이너명] -p 8080:8080 [사용자ID]/[파일명]
Docker Repository에서 Docker Image를 pull하여 내려받고 이를 통해 Springboot 프로젝트를 실행(컨테이너화)한다.
-d를 통해 백그라운드에서 실행하게 하여 터미널이 다른 작업을 수행할 수 있게 하고,
--name을 통해 자체적인 별명을 부여한다.
-p를 통해 포트를 부여한다. (8080)

참고로 최초 run을 실행했다면 그 다음부터는 run이 아니라 <docker start [컨테이너명]> 으로 컨테이너를 실행해야 한다. 그렇지 않으면 Docker 내부에 같은 내용을 담은 컨테이너가 창궐(?)하게 된다.

다음은 관련 작업 시 필요한 기본적인 Docker 명령어이다.
여기를 참고하여 작성하였다.

docker attach [컨테이너명]
컨테이너 실행 시 사용한다. (직접 컨테이너 내부를 실시간으로 들여다본다.)
Ctrl + P + Q로 쉘을 빠져나올 수 있다.

docker start(stop) [컨테이너명]
컨테이너를 실행하거나, 실행되던 컨테이너를 중단시킨다.

docker logs [컨테이너명]
해당 컨테이너가 생성하는 로그를 조회할 수 있다.

docker ps (-a)
현재 실행중인 컨테이너의 목록을 조회할 수 있다.
-a를 통해 모든 컨테이너를 조회할 수도 있다.

docker rmi [이미지id]
pull이나 run으로 내려받은 docker 이미지를 삭제한다.

docker rm -f [컨테이너id]
해당 docker 컨테이너를 (강제로) 삭제한다.

참고로, Got permission denied while trying to connect to the Docker daemon~으로 시작하는 에러는 아래와 같이 해결했다.

sudo chmod 666 /var/run/docker.sock
sudo usermod -aG docker ${USER}

다음에는 CI/CD도 도전해볼 계획이다.
여담으로, 에러가 정말 많이 나서(특히 postgreSQL 연동 관련) 굉장히 당혹스러웠다.

profile
Discover Tomorrow

0개의 댓글