Project/9uin

spring boot 사이드 프로젝트: DockerFile, docker-compose.yml 작성 및 클라우드 세팅(GCP) 1

attlet 2023. 10. 30. 19:30

프로젝트 작성이 거진 다 끝나고, 테스트와 기능 개선 과제, 그리고 배포 정도의 과제가 남았다. 이제 로컬로 개발서버를 여는 것 뿐 아니라 클라우드 인스턴스에 24시간 배포를 시작해보려 한다.

 

 

클라우드 서비스는 가장 대중적인 아마존의 AWS, 마이크로소프트의 Azure, 구글의 GCP 등등 여러가지가 존재하는데, 나는 여기서 GCP를 선택했다. 이유는 단순하게도 무료로 이용이 가능해서(...) 이다. 다른 서비스는 무료를 더 이상 쓸 수 없는 상황..

 

 

당장 복잡한 클라우드 아키텍처를 설계하지는 않았다. 일단 가볍게 다음과 같은 구조를 생각했다.

 

 

 

GCP인스턴스 하나를 실행해서 그 안에 도커를 이용해 3개의 컨테이너를 띄운다. 8080으로 요청을 보내면 설정을 통해 스프링 부트 애플리케이션이 실행중인 컨테이너의 8080포트로 보내도록 포워딩을 한다.

 

 

 

 

왜 docker를 사용했는가??


 

 

인스턴스에 직접 프로젝트를 실행하는 방법을 하지 않고 도커 컨테이너를 선택한 것은,  도커 컨테이너를 사용하지 않으면 프로젝트를 위해 설치하고 설정하는 것들이 여럿 필요하기 때문이다. 자바를 위한 jdk는 물론이며, DB관리를 위한 DBMS들도 gcp 인스턴스안에 설치해야할 것이고, 만약 프로젝트 규모가 커지면 그 외에 더 필요한 것들이 많아진다.

 

인스턴스 하나에만 해도 설치해야할 것들이 이렇게 여럿 존재하는데, 만약 서버를 증설해야 한다면 이 과정을 더 반복해야한다. 참으로 귀찮은 일이 아닐 수 없다. 만약 설치하는 과정에서 몇몇 과정을 빼먹거나 순서를 틀려먹는다면? 상상만 해도 짜증이 몰아친다.

 

 

 

이런 불편한 과정들을 docker만 설치하면 쉽게 스킵할 수 있다. 도커에는 우리 프로젝트를 이미지화할 수 있고, 그 이미지를 실행해서 컨테이너로 동작하게 할 수 있는 기술이 있다. 컨테이너에는 이 프로젝트에 필요한 설정들이 이미 설치되어 실행되도록 할 수 있기에, 환경이나 설정에 대해서 걱정할 필요가 없다.

 

 

클라우드는 우분투 운영체제 기반이기에 이 환경에서 docker를 설치하는 방법을 알아야한다. 이 과정은 아래 링크에서 확인할 수 있다.

 

https://haengsin.tistory.com/128

 

Ubuntu 에 Docker 설치

실행환경 Ubuntu 22.04 Docker 설치방법 1. 우분투 시스템 패키지 업데이트 sudo apt-get update 2. 필요한 패키지 설치 sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 3. Docker의

haengsin.tistory.com

 

 

이런 과정을 위해 DockerFile을 작성했다. DockerFile을 통해 우리 팀의 spring boot 프로젝트를 도커 이미지화 시킬 수 있다.

 

 

DockerFile

#자바 17 베이스 이미지
FROM openjdk:17

#인자를 설정한다. argument.
ARG JAR_FILE=build/libs/*.jar

#이미지 생성할 때 파일을 복사한다. 위의 jar_file을 app.jar로 복사해서 이미지로 가져온다.
COPY ${JAR_FILE} app.jar

#컨테이너를 시작할 때 실행할 명령어.
ENTRYPOINT ["java", "-jar", "app.jar"]

 

이 파일은 프로젝트 폴더상에서 백엔드 코드 가장 상위에 위치한다. (build.gradle이 있는 곳을 생각하면 된다.)

 

FROM을 통해 이 이미지를 만들 때 베이스로 할 이미지를 선택한다. 우리 프로젝트는 자바 17을 기반으로 한다.

 

ARG는 없어도 되는 부분인데, 쉽게 말해 이름을 지정한 것이다. 와일드 카드 문자 *를 통해 build/libs/안에 생성되어있는 jar파일을 JAR_FILE이라는 이름으로 지정한 것이다. 이렇게 해서 jar파일 이름이 어떻든, 확장자가 jar기만 하면 되는 것이다.

 

만약 이걸 없이 한다면 build를 통해 생성되는 jar파일 이름 그대로 가져와야 할 것이다.

 

COPY를 통해 위에서 지정한 그 jar파일을 app.jar라는 이름으로 이미지에 복사한다. 

 

ENTRYPOINT를 통해 java -jar app.jar를 컨테이너가 이 이미지를 기반으로 실행될 때 자동으로 실행되도록 하는데, 이는 jar파일을 통해 배포하는 코드이다. 즉 컨테이너가 시작되면 이 프로젝트 코드가 배포를 시작한다는 것이다.

 

 

 

DockerFile과 같이 사용할 도구로, docker-compose가 있다. 한 인스턴스 안에서 여러 컨테이너가 실행될 때, 이것들을 묶어서 관리하기 편하게 해주는 도구다. 

 

 

docker compose를 사용하기로 결정한 것은, spring boot 애플리케이션 말고도 여러 컨테이너 실행이 필요해졌기 때문이다. 

 

 

docker-compose를 이용하려면 docker-compose.yml파일을 DockerFile와 동일한 위치에 만들어주면 된다. 

 

docker-compose.yml

version: '3'

services:
  spring-app:
#    build:
#      context: .
#      dockerfile: Dockerfile
    image: tlsdbstjd124/9uin-server    #이 이미지를 기반으로 컨테이너 실행할 것.
    ports:
      - "8080:8080"          #로컬에서 8080포트요청은 이 컨테이너의 8080으로 보내기.
    depends_on: 
      - maria-db            #이 두 컨테이너 먼저 실행할 것.        
      - redis
    environment:       #환경 설정. 
      SPRING_DATASOURCE_URL: jdbc:mariadb://maria-db:3306/springboot
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 1234
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PORT: 6379
    networks:
      - backendNetwork

  maria-db:
    image: mariadb:latest
    environment:
      MYSQL_DATABASE: springboot
      MYSQL_ROOT_PASSWORD: 1234
    ports:
      - "3306:3306"
    networks:
      - backendNetwork

  redis:
    image: redis:latest
    ports:
      - "6379:6379"
    networks:
      - backendNetwork

networks:
  backendNetwork:

 

 

spring-app과 mariadb, redis라는 3개의 컨테이너를 실행하도록 한다. 각 컨테이너 실행 기반 이미지들을 image라는 필드로 설정하고, ports를 통해 포트 포워딩하며, environment로 필요한 환경을 지정한다. 

 

 

 

 

GCP 세팅


 

두 파일 작성을 끝냈다면, 클라우드 인스턴스 세팅을 해보도록 하자. GCP 홈페이지에 접속한다.

 

 

 

https://cloud.google.com/free?utm_source=google&utm_medium=cpc&utm_campaign=japac-KR-all-en-dr-BKWS-all-core-trial-EXA-dr-1605216&utm_content=text-ad-none-none-DEV_c-CRE_668690472449-ADGP_Hybrid%20%7C%20BKWS%20-%20EXA%20%7C%20Txt%20~%20GCP_General_core%20brand_main-KWID_43700077514871058-kwd-87853815&userloc_1009839-network_g&utm_term=KW_gcp&gclid=Cj0KCQjwqP2pBhDMARIsAJQ0CzoRXnQjE8N0HIzQ7ZA2dHPIA7Hs5xtASTixsS2u9p9qsEOAQ59aRV8aAnF9EALw_wcB&gclsrc=aw.ds&hl=ko

 

무료 체험판 및 무료 등급  |  Google Cloud

$300의 무료 크레딧과 월별 한도까지 무료로 사용할 수 있는 Compute Engine, Cloud Storage 등 20여 개의 제품으로 Google Cloud에서 빌드하세요.

cloud.google.com

 

 

무료로 사용하기를 눌러 한 번 프로젝트를 생성해보도록 하자. GCP같은 경우 처음 생성하면 90일의 무료기간과 300크레딧을 제공한다.

 

 

 

 

생성한 프로젝트에 들어간다.

 

 

 

 

 

메뉴에서 compute engine -> vm 인스턴스로 들어간다. 

 

 

 

 

나 같은 경우 이렇게 미리 인스턴스가 만들어져있다. 인스턴스 만들 때 중요한 점은, 비용의 문제 때문에 무료 사용을 위해서는 몇몇 조건에 따라 인스턴스를 생성해야 한다는 점이다. 

 

https://cloud.google.com/free/docs/free-cloud-features?hl=ko#compute

 

Google Cloud 무료 프로그램

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 의견 보내기 Google Cloud 무료 프로그램 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Goog

cloud.google.com

 

 

여기 들어가면 자세한 조건이 나온다. 다음 부분을 참고하자.

 

 

 

여기를 보고 만들면 된다. e2-micro로 지정해야 하고, 가장 놓치기 쉬운 '표준 영구 디스크' 부분을 꼭 지정해야만 한다.

 

 

 

이제 인스턴스에 접속하기 위한 ssh키 발급을 준비해보자.

 

 

사실 윈도우에서 그냥 접속이 가능하도록 되어있다.

 

 

 

 

 

인스턴스 정보창에서 가장 오른쪽에 클릭하면 바로 ssh접속할 수 있도록 되어있다.

 

 

 

이렇게 브라우저에서 접속할 수 있다. 물론 이럴 수도 있고 다른 터미널에서 ssh를 이용해 접속할 수도 있다. 

 

 

 

먼저 접속하고자 하는 우분투/리눅스 운영체제의 컴퓨터에서 ssh키를 생성한다.

 

 

$ ssh-keygen -t rsa -f ~/.ssh/[KEY_FILE_NAME] -C [USERNAME]

 

 

 

ssh-keygen명령어가 ssh키 페어를 생성하는 명령어이다. -t rsa옵션을 통해 키의 유형을 정한다. rsa 암호화 알고리즘을 이용한다는 뜻이다.

 

-f   ~/.ssh 옵션을 통해 키 페어 생성 위치를 정한다.   -C를 통해 키에 주석을 다는데, 굳이 안 써도 된다.

 

 

이 때 두 개의 키가 생성되는데, 각각 개인키, 공개키가 되겠다.

 

개인키는 로컬에 놔두고, gcp 인스턴스에 공개키를 등록해두는 방식이다. 이렇게 하면 로컬에서 개인키를 이용해 gcp에 접속을 시도하면 gcp에 등록된 공개키를 이용해 검증해서 접속을 허가하는 것이다.

 

자세한 ssh 과정은 이 글의 주제를 벗어나니, 설명은 생략할 것이다.

 

 

 

 

이제 gcp에 ssh 공개키를 등록해보자. 물론 로컬에서 공개키를 전송하는 방법도 있지만, gcp 자체적으로 지원하는 걸 이용했다.

 

 

 

 

메뉴에 메타데이터 탭에 들어간다.

 

 

 

 

 

여기에 이렇게 공개키를 등록하면, ssh 접속 시도가 들어올 때 이 공개키로 검증하게 된다.

 

 

 

 

글이 길어져 2편으로 진행된다.