Search
🌎

Docker+GCP로 Springboot 배포 총정리(AWS EC2,RDS 대신 GCP VM,cloud SQL을 써보아요)

작성일자
2023/02/15
태그
DEVOPS
HIGHLIGHT
프로젝트
BeachCombine
책 종류
1 more property

1. 서론

Google Solution Challenge에 출품할 프로젝트를 제작 중 구글 기술을 쓰면 가점이 있다길래 시작한 GCP(Google Cloud Platform) 사용이었는데, 써보니 생각보다 괜찮았습니다. 서칭하는 과정에서 GCP 배포 관련한 포스팅이 적음에, 전체 과정이 통합된 포스팅이 없음에 불편함을 느껴 글을 작성합니다. 제 글을 보고 쭉 따라하시면 배포 익숙하지 않으신 분들도 성공적으로 배포하실 수 있게 A부터 Z까지 최대한 상세하게 작성해보겠습니다!
기존에 AWS로만 배포를 해봤었는데, 그 과정을 이번 GCP를 이용한 배포 과정과 비교하며 설명하겠습니다. GCP를 처음 접해보시는 분들이 보고 도움을 받길 바랍니다 또, 함께 Google Solution Challenge에 나가는 다른 분들도 도움이 되셨으면 좋겠습니다!

2. GCP vs AWS

우선 AWS의 각 용어들을 GCP에서 사용하는 용어들과 매핑시켜 보겠습니다.
AWS
GCP
Comment
EC2 인스턴스
VM 인스턴스
가상머신
탄력적 ip
외부 ip
고정 ip
보안 그룹 규칙
방화벽 규칙
포트 허용
RDS
Cloud SQL
데이터베이스
S3
Cloud Storage
스토리지

3. Docker + GCP 활용한 배포 과정 (AWS와 비교)

[1] GCP 환경 설정

1) VM 인스턴스 생성 (= AWS EC2 인스턴스 생성)

2.
프로젝트 만들기
원하는 이름으로 프로젝트를 만들어주세요. 프로젝트 생성 후에 프로젝트 내에서 VM 인스턴스를 생성/사용합니다.
3.
인스턴스 만들기
저는 아래와 같이 설정해줬습니다.
참고

2) 외부 ip 할당 (= AWS 탄력적 ip 할당)

1.
VPC 네트워크의 IP 주소 메뉴로 이동
AWS는 고정 IP를 탄력적 IP라고 하는데, GCP에선 외부 IP라고 합니다. 고정 IP를 쓰는 이유는, 여러 가지가 있지만 저는 인스턴스를 중지했다가 재시작했을 때, IP주소가 변경되는 걸 방지하기 위해 꼭 쓰는 편입니다. (예전 프로젝트에서 안 써봤다가 제대로 애먹었습니다,,,)
2.
외부 IP 주소 할당
a.
외부 고정 주소 예약 클릭
default로 2개 IP주소가 나와 있을 텐데, 이는 임시 유형이라 새로 만들어줘야 합니다.
b.
아래와 같이 설정해 예약 클릭
결과적으로 아까 임시 유형이 아래와 같이 고정 유형으로 바뀐 걸 확인하실 수 있습니다.
주의할 점은 꼭 VM(전 beach-combine에 연결했습니다)에 연결해주세요! 고정 IP를 할당만 하고 사용하지 않으면 요금이 부과됩니다. 안 쓰는 고정 IP는 고정주소해제로 삭제해 주심 됩니다.
참고

3) 방화벽 설정 (= AWS 보안 그룹 설정)

1.
VPC 네트워크의 방화벽 메뉴로 이동
방화벽 설정을 하여 특정 프로토콜과 포트를 허용해줍니다. 외부망에서 GCP로 접속하는 Inbound는 TCP/UDP/ICMP 프로토콜과 80/443/22/3389 포트만 허용하고 있습니다. 포트가 허용되지 않으면, 나중에 배포 후 테스트해보실 때 접속이 안될 수 있어요! 저는 8080번 포트를 허용해줄 겁니다.
2.
방화벽 규칙 만들기
저는 8080번 포트를 허용해주고 싶어서 아래와 같이 설정했습니다.
동일한 방법으로 IPv6도 만들어줬습니다.
참고

4) Cloud SQL 생성 및 사용 (= AWS RDS)

1.
SQL 메뉴로 이동
2.
인스턴스 만들기
저는 데이터베이스 엔진으로 MySQL을 선택한 후, 아래와 같이 설정해줬습니다.
3.
로컬에서 Cloud SQL 접속 테스트
인스턴스가 생성되셨다면 아래 공개 IP 주소에 쓰여있는 IP 주소를 이용해 RDS에 접속하실 수 있습니다! 로컬에서 돌리고 계신 스프링 프로젝트에서 테스트로 Cloud SQL에 접속해보겠습니다.
a.
먼저, 프로젝트의 application.yml의 url, username, password를 방금 만든 Cloud SQL의 것으로 교체해줍니다.
url의 경우 jdbc:mysql://localhost:3306/beachcombine?serverTimezone=Asia/Seoullocalhost:3306공개 IP 주소:3306으로 바꿔주시면 됩니다!
username은 root로 해주심 됩니다.
b.
프로젝트를 실행해 만든 API를 테스트해보고 정상적으로 데이터가 들어왔는지 DB를 확인해봅니다. 저는 MySQL을 써서 MySQL Workbench를 이용했습니다. + 버튼 눌러서 Hostname에 공개 IP 주소 넣어주심 됩니다! 혹시 에러가 난다면, MySQL에서 데이터베이스 생성 후, API 다시 테스트해보세요! 테스트가 다 끝나고선, application.yml의 url, username, password를 다시 원래대로 돌리는 것 잊지 마세요:)
참고

[2] Docker로 배포하기

환경 설정 하느라 고생하셨습니다! 이제 실질적인 배포를 해보겠습니다. Docker를 쓰기 때문에 굉장히 간단하고 쉽습니다.

1) 로컬에 Docker 설치

Docker 써본 적 없으신 분들은 먼저 컴퓨터에 Docker를 설치해주세요. Window 쓰시는 분들은 아래 블로그 글 보고 따라해 주심 됩니다.

2) Dockerfile 생성

프로젝트 루트 폴더에 Dockerfile을 생성하고 아래 내용을 넣어주세요.
FROM openjdk:11-jdk-slim-buster COPY build/libs/backend-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar"]
Plain Text
복사

3) Docker hub 리포지토리 생성

Docker hub에 회원가입 후, 리포지토리를 생성해주세요. 저는 리포지토리 이름을 저희 프로젝트 이름인 beach_combine으로 했습니다:)
주의할 점!
도커 허브 리포지토리는 꼭 Private으로 생성해주세요!
만일 public으로 생성하고 싶으시다면, github secret을 사용하지 않고 docker secret을 적용해줘야 하는 데 해당 블로그는 그 부분 내용까지 포함하고 있지 않습니다.

4) 서버에 Docker 설치

1.
인스턴스 접속
저희가 일전에 만들어 둔 VM 인스턴스로 돌아와서, SSH를 클릭합니다. 옆의 삼각형 모양을 클릭하고 브라우저 창에서 열기 버튼을 누르면 SSH로 접속하실 수 있습니다.
2.
Docker 설치
공식 문서에 나온 대로 Docker 설치해주심 됩니다. 마지막에 버전명이 나오면 설치 성공입니다.
$ sudo apt-get update $ sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release $ sudo mkdir -m 0755 -p /etc/apt/keyrings $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg $ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin $ sudo docker --version
Java
복사

5) Docker-compose.yml 생성

1.
인스턴스에서 아래 명령어를 입력해 Docker-compose.yml 파일을 생성합니다.
t01053604256@beach-combine:~$ pwd /home/t01053604256 t01053604256@beach-combine:~$ cd .. t01053604256@beach-combine:/home$ cd .. t01053604256@beach-combine:/$ ls bin initrd.img lib64 mnt root snap tmp vmlinuz boot etc initrd.img.old lost+found opt run srv usr vmlinuz.old dev home lib media proc sbin sys var t01053604256@beach-combine:/$ vim docker-compose.yml
SQL
복사
2.
docker-compose.yml 파일에 아래와 같이 입력하고 저장하고 나옵니다(esc + :wq)
SPRING_DATASOURCE 내용엔 일전에 만든 Cloud SQL의 내용을 넣어주시면 됩니다.

6) 마지막! 배포하기

[로컬]
1.
jar 빌드
다른 방법들도 있지만 인텔리제이에서 bootJar 클릭해서 빌드하시는 걸 추천드립니다! 편해서요,,
2.
이미지 생성
docker login → 혹시 안된다면 Docker Desktop을 실행시키고 다시 해보세요!
docker build -t 계정명/리포지토리명 ./ → ex) docker build -t choo000407/beach_combine ./
터미널에서 프로젝트 루트 경로로 이동한 후 위 명령어를 입력해주세요.
(전 그냥 인텔리제이 아래 뜨는 터미널 쓰는 걸 추천드립니다,, 경로가 들어가져있어서 편해서요,,)
3.
도커 허브로 push
 docker push 계정명/리포지토리명 → ex) docker push choo000407/beach_combine ./
[서버]
1.
도커 로그인
sudo docker login
2.
도커 허브에서 pull
SSH로 인스턴스 접속해주시고, 아래 명령어 입력해주세요.
sudo docker pull 계정명/리포지토리명
sudo docker images → 도커 허브에서 pull 해온 이미지 잘 들어왔는지 확인
3.
도커 yml에 설정한 이미지 생성
sudo docker tag pull한이미지 만들이미지 beachcombine_spring
이미지 이름을 변경해준다 생각하심 편합니다.
→ 이미지 이름을 계정명/리포지토리명에서
docker-compose.yml에서 application.image에 지정해둔 걸(beachcombine_spirng)로 변경
4.
도커 컴포즈 실행
sudo docker-compose up

4. 결론

배포 성공적으로 하셨길 바랍니다. 수고하셨습니다
배포 base url은 http://VM인스턴스외부IP:8080/ 입니다.
이 과정을 자동화하는 CI/CD 내용은 아래 포스팅으로 올려두었습니다.
기본적인 docker 명령어 관련한 내용은 아래의 포스팅에 올려두었습니다.