일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 큐시즘
- js
- 원격 저장소
- spring
- time slice
- 생활코딩
- 파이썬
- 멘토링 후기
- OOAD
- flab
- Cold Publisher
- CLI
- 버전관리
- RxJava
- 디프만
- Hot Publish
- spring boot
- github
- Git
- OS
- Round Robin
- Depromeet
- js 개발자라면 알아야하는 핵심 컨셉
- Hot Publisher
- 에프랩
- 건국대학교
- Observable
- 자바스크립트
- 마블 다이어그램
- CPU Scheduling
- Today
- Total
글쓰는 개발자
[#4] Docker를 이용해 스프링부트 앱 배포하기 본문
진행하고 있던 프로젝트가 기능 요구 사항을 어느 정도 구현하여서, 드디어 애플리케이션을
Dockerize 하여 Google Cloud Platform에 배포하였습니다. 축하해주세요! 🥳
이번 프로젝트에서 Docker를 처음 써보아서 힘든 점이 참 많았지만, 다양한 자료를 참고하여
성공적으로 배포하였고, 그 과정에서 겪었던 시행착오를 공유하고자 합니다.
제 글이 도움이 되어 더 빠르게 완성하시길 기원합니다!
※ 배포 환경
패키징: Windows 10, openjdk 10
배포: Google Cloud Platform, Cent OS 7
목차
- Overall Structure
- 프로젝트 배포용 파일 생성
- Docker Desktop 설치 및 Dockerfile 작성
- Docker 이미지 생성 및 Docker hub에 push 하기
- Docker hub로부터 배포 서버에 Docker 이미지 내려받기
- Docker 이미지 구동
Overall Structure
전반적인 애플리케이션의 배포는 위의 사진에 나타난 과정을 따라 진행합니다.
먼저 애플리케이션을 Dockerize 하기 위해 Dockerfile을 작성하고, Dockerfile을 기반으로 프로젝트를 빌드하여 Docker image화한 후에, 이것을 Docker hub에 push & 배포 서버(Google Cloud Platform. GCP)에서 pull 하여
Docker image를 컨테이너화하면 배포가 완료됩니다.
프로젝트 배포용 파일 생성
프로젝트 배포를 위해, 그간 구현한 프로젝트를 패키징 해주어야 합니다.
먼저, 기존에 생성되어 충돌을 일으킬 수 있는 target 파일을 제거하기 위해 mvn clean을 실행합니다.
IntelliJ의 Maven 탭 -> Lifecycle에서 clean을 더블클릭하면, 별도의 명령어 없이 mvn clean을 수행할 수 있습니다. 갓텔리제이...
정상적으로 target 파일들이 삭제된 것을 확인한 후, 같은 탭의 package를 더블클릭 해주시면 아래와 같이 프로젝트가 패키징 됩니다.
Docker Desktop 설치 및 Dockerfile 작성
정상적으로 패키징을 했다면, 패키징 한 파일을 Dockerize 해야 합니다.
Dockerize에 대한 간략한 설명을 더보기에서 확인하실 수 있습니다.
Dockerize란, Docker build를 통해 프로젝트 파일을 Docker image화 한 것을 말합니다.
프로젝트가 Docker image화 되면, 해당 파일을 Docker hub에 push 하여 docker가 설치된 어떤 환경에서도 동일하게 실행할 수 있습니다.
Dockerize를 위해, 먼저 Docker desktop을 설치합니다. (※ Docker Desktop 설치를 위해 wsl2가 PC에 설치되어 있어야 합니다)
Docker 설치를 완료하고 커맨드 라인에서 docker를 입력했을 때, 아래와 같이 명령어 소개 페이지가 나온다면 정상적으로 설치된 것입니다.
Docker가 정상적으로 설치되었다면, Spring Boot with Docker 페이지를 참고하여 Dockerfile을 프로젝트 루트 디렉토리에 작성합니다.
프로젝트의 버전에 따라 https://hub.docker.com/_/openjdk를 참고하여 자신에게 필요한 jdk 버전을 FROM ~ 부분에 작성합니다. 저는 openjdk:11-jdk 버전으로 Dockerfile을 작성하였습니다.
Docker 이미지 생성 및 Docker hub에 push 하기
Dockerfile을 작성하였으니, 프로젝트를 빌드 및 이미지화 하여 Docker hub에 push 해야 합니다.
Docker hub 공식 페이지에 접속하여 계정을 생성하고, 이미지를 업로드할 Repository를 생성합니다.
포스팅을 위해 test-repo Repository를 생성하였습니다.
적당한 이름의 Repository를 생성하였다면, 다시 프로젝트로 돌아가 프로젝트를 빌드(이미지화)합니다.
Dockerfile이 위치한 프로젝트 루트 폴더에서 터미널을 실행한 후, 아래 명령어를 입력하면, 도커 이미지가 생성됩니다.
// docker build -t {docker hub 계정명}/{docker hub repository명} .
docker build -t souljit1/test-repo .
도커 이미지가 정상적으로 생성되었다면, docker push 명령어를 통해 생성한 Repository로 이미지를 push 합니다.
// docker push {docker hub 계정명}/{docker hub repository명}:{tagname(optional)}
docker push souljit1/test-repo
Docker hub로부터 배포 서버에 Docker 이미지 내려받기
Docker 이미지를 Docker hub에 업로드하였으니, 배포 서버에서 해당 이미지를 내려받아야 합니다.
프로젝트 배포 서버는 CentOS 7 환경이므로, 이에 맞는 명령어를 사용하여 진행합니다.
먼저, 배포 서버 내에 아래 명령어를 통해 docker를 설치합니다.
$ sudo yum install docker
Docker가 정상적으로 설치되면, 아래의 명령어로 도커를 실행하고, 실행 상태를 확인합니다.
$ sudo systemctl start docker # docker 실행
$ sudo systemctl status docker # docker 상태 확인
아래와 같이 초록색 글씨 active(running)가 보인다면, docker가 정상적으로 실행된 것입니다.
Docker가 정상적으로 실행되었으니, 아래의 명령어로 Docker hub에 업로드 해 둔 Docker 이미지 파일을 내려받도록 합시다.
$ # sudo docker pull {계정명}/{repository명}
$ sudo docker pull souljit1/test-repo
Docker 이미지 구동
프로젝트 이미지를 내려받았으니, 아래의 명령어로 이를 실행하여 컨테이너화 하고, 정상적으로 실행되었는지 확인합니다.
$ # sudo nohup docker run -p {host 포트}/{container 포트} {docker hub 계정명}/{docker hub repository명} > nohup.out 2>&1 &
$ sudo nohup docker run -p 8081:8080 souljit1/test-repo > nohup.out 2>&1 &
$ sudo docker ps # 도커 컨테이너 목록 확인
※ -p 옵션에 대한 설명은 아래의 더보기를 참고하시기 바랍니다.
docker run 명령어의 -p 옵션에서, host 포트와 container 포트를 지정합니다.
위와 같이 -p 8081:8080으로 지정한 경우, 컨테이너를 실행한 host의 8081 포트에 포워딩되며, 내부 컨테이너의 8080 포트에 포워딩됩니다.
따라서 외부에서 배포된 서버에 접속하기 위해서는, {host ip}:{host port}로 접근하면 해당 요청을 host가 container에 바인딩하여 접속하는 형태입니다.
위와 같이, 컨테이너 목록에 등록했던 이미지가 발견되면 정상적으로 컨테이너가 구동된 것입니다.
앱을 백그라운드로 띄우고, 로그를 nohup.out에서 확인하도록 하였으니 nohup.out의 내용을 확인하면 서버에서 남긴 로그를 확인할 수 있습니다.
$ cat nohup.out
이상으로, 프로그램을 패키징 및 이미지화하고
GCP 인스턴스에 배포하는 과정을 진행하였습니다.
다음으로는, 배포된 앱을 대상으로 nGrinder를 통해 스트레스 테스트를 진행하며
서버가 어느 정도까지의 부하를 견디는지 확인하고,
서버를 scale-out 하여 인스턴스를 증가시키면서
어떠한 변화가 생기는지 직접 확인하는 작업을 계획하고 있습니다.
다시금 유의미한 지표를 발견했을 때,
좋은 글로 공유할 수 있도록 노력하겠습니다!
이미지 출처 및 참고 강의: 대기업 개발자 푸와 함께하는 백엔드 시스템 실무
프로젝트 URL: https://github.com/f-lab-edu/sell-everything
'Project > Sell-everything' 카테고리의 다른 글
[#3] 그래서 DispatcherServlet이 대체 뭐하는 녀석이죠? (0) | 2021.09.14 |
---|---|
[#2] Redis 캐시를 통해 읽기 성능 향상하기 (3) | 2021.09.07 |
[#1] 분산 서버 환경의 세션 정합성 관리 (2) | 2021.06.28 |