DevOps

[Spring Cloud] MSAํ™˜๊ฒฝ CI/CD ๊ตฌ์ถ•ํ•˜๊ธฐ

ddonghyeo 2024. 5. 24. 02:07
์ฐธ๊ณ 
Amazon Linux 2023 Red Hat Linux ๊ธฐ์ค€.

0. ์‹œ์ž‘

Spring Cloud ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ์˜ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•˜์˜€๋‹ค.

 

๊ธฐ์กด CI/CD์™€ ๋‹ค๋ฅธ ์ ์€ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋ฐฐํฌํ•ด์•ผ๋œ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

๋ณธ ํ”„๋กœ์ ํŠธ์˜ ์„œ๋น„์Šค๋Š” ์•„๋ž˜ ์„ธ๊ฐ€์ง€์˜€๋‹ค.

- noti-service

- weather-service

- user-service

 

๋‚˜๋จธ์ง€ ํ™˜๊ฒฝ์„ ์œ„ํ•œ ์„œ๋น„์Šค๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•˜๋‹ค.

- Eureka

- api-Gateway

- config-service

- Kakfa  & Zookeper

 

ํ•ด๋‹น ์„œ๋ฒ„๋“ค ๋ชจ๋‘ ์ง€์†์ ์ธ ๋ฐฐํฌ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ–ˆ๋‹ค.

 

์šฐ์„  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •ํ–ˆ๋‹ค.

 

- Eureka, config-service, kafka, zookeper ๋„ค ๊ฐ€์ง€๋Š” ์„œ๋น„์Šค ๋กœ์ง์ด ์ž˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ปจํ…Œ์ด๋„ˆ ์ตœ์‹ ํ™”๋ฅผ ํ•˜์ง„ ์•Š์•˜๋‹ค.

 

- ๋ฐ˜๋ฉด ๋‹ค๋ฅธ ์„œ๋น„์Šค๋“ค์€ ์„œ๋น„์Šค๋กœ์ง์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์‹ ํ™”๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

 

- ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ๋ณ€๊ฒฝ๋งˆ๋‹ค ๋ชจ๋“  ์„œ๋น„์Šค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ํ•„์š”๋Š” ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ, input์„ ๋ฐ›์•„ ํ•„์š”ํ•œ ์„œ๋น„์Šค๋งŒ ์ตœ์‹ ํ™”๋ฅผ ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

 

 

1. ์‰˜ ์Šคํฌ๋ฆฝํŠธ

 

์‰˜ ์Šคํฌ๋ฆฝํŠธ๋Š” 3๊ฐ€์ง€๋กœ ๋‚˜๋ˆด๋‹ค.

 

1-1. docker.sh

#!/bin/bash
#์…”๋ฑ…(shebang) : ์ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ Bash Shell ์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•จ์„ ๋‚˜ํƒ€๋ƒ„.

#Docker ๋ช…๋ น์–ด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•จ.
# -v ์˜ต์…˜ : ๋ช…๋ น์–ด ์‹คํ–‰ ์ „ ๋ช…๋ น์–ด์™€ ์ธ์ž ์ถœ๋ ฅ.
# &> ๋ช…๋ น์–ด ์ถœ๋ ฅ๊ณผ ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฆฌ๋‹ค์ด๋ ‰์…˜. /dev/null ๋””๋ฐ”์ด์Šค๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•จ.
# docker ๋ช…๋ น์–ด์˜ ๊ฒฝ๋กœ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ (stdout), ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€(stderr)์™€ ํ•จ๊ป˜ /dev/null ๋””๋ฐ”์ด์Šค๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜.
# /dev/null ์€ ํŠน์ˆ˜ํ•œ ๋””๋ฐ”์ด์Šค ํŒŒ์ผ. ์“ฐ๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„๋ฆผ.
# ์ฆ‰, ๋ช…๋ น์–ด์˜ ์ถœ๋ ฅ๊ณผ ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋ชจ๋‘ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Œ.
# ๊ฒฐ๋ก ์ ์œผ๋กœ ๋ช…๋ น์–ด์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ. ๋˜๋Š” ๋ช…๋ น์–ด ์‹คํ–‰ ๊ฒฐ๊ด„๋ฅด ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€๋งŒ ํ™•์ธํ•˜๊ฒŒ ๋จ.
if ! command -v docker &> /dev/null; then
    # docker ๋ช…๋ น์–ด๊ฐ€ ์‹คํŒจํ–ˆ์„ ๊ฒฝ์šฐ -> docker ๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์Œ. docker ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ•จ.
    echo "Docker is not installed..."
    echo "Docker install start..."
    sudo yum update -y
    # docker ์„ค์น˜
    sudo yum install -y docker
    # docker ๊ถŒํ•œ ์„ค์ •
    sudo usermod -aG docker ec2-user
    sudo systemctl enable --now docker
    echo "Docker install complete"
else
    # Docker ๋ช…๋ น์–ด๊ฐ€ ์„ฑ๊ณตํ–ˆ์„ ๊ฒฝ์šฐ. Docker ๊ฐ€ ์ด๋ฏธ ์„ค์น˜๋จ์„ ์ถœ๋ ฅ
    echo "Docker is already installed"
fi

# Docker-compose install
# Docker-compose ์„ค์น˜
if ! command -v docker-compose &> /dev/null; then
    echo "Docker-compose is not installed..."
    echo "Docker-compose install start..."

    #Docker compose plugin ์„ค์น˜ - Amazon Linux 2023
    sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose

    docker-compose version

    echo "Docker-compose install complete!"
else
    echo "Docker-compose is already installed"
fi

 

ํ•ด๋‹น CI/CD๊ฐ€ ์ƒˆ๋กœ์šด ํ™˜๊ฒฝ์—์„œ๋„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก Docker์™€ Docker-compose๋ฅผ ์„ค์น˜ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

 

Amazon Linux 2023 (Red Hat Linux) ๊ธฐ์ค€์ด๊ณ ,

ubuntu ์„œ๋ฒ„์ผ ์‹œ yum๋Œ€์‹  apt-get ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

 

1-2. common.sh

์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ "์„œ๋น„์Šค ๋กœ์ง์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”" ์„œ๋น„์Šค ์ปจํ…Œ์ด๋„ˆ๋“ค์„ ์‹คํ–‰ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์ด๋‹ค.

 

# ํ˜„์žฌ ์‹คํ–‰์ค‘์ธ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์ค‘ ๋‹จ์–ด๊ฐ€ ํฌํ•จ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฒ€์ƒ‰
RUNNING_EUREKA=$(docker ps | grep eureka)
RUNNING_CONFIG=$(docker ps | grep config)
RUNNING_ZOOKEEPER=$(docker ps | grep zookeeper)
RUNNING_KAFKA=$(docker ps | grep kafka)

# Eureka ๊ฒ€์ƒ‰
if [ -z "$RUNNING_EUREKA" ]; then
    echo "Starting Eureka ..."
    docker-compose -f /home/docker-compose.yml up -d eureka
    sleep 5 #Eureka ์‹คํ–‰ 5์ดˆ ๋Œ€๊ธฐ
else
    echo "Eureka is already running"
fi

# Config ๊ฒ€์ƒ‰
if [ -z "$RUNNING_CONFIG" ]; then
    echo "Starting Config Service ..."
    docker-compose -f /home/docker-compose.yml up -d config
    sleep 5 #Config ์‹คํ–‰ 5์ดˆ ๋Œ€๊ธฐ
else
    echo "Config Service is already running"
fi

# Zookeeper ๊ฒ€์ƒ‰
if [ -z "$RUNNING_ZOOKEEPER" ]; then
    echo "Starting Zookeeper ..."
    docker-compose -f /home/docker-compose.yml up -d zookeeper
else
    echo "Zookeeper is already running"
fi

# Kafka ๊ฒ€์ƒ‰
if [ -z "$RUNNING_ZOOKEEPER" ]; then
    echo "Starting Kafka ..."
    docker-compose -f /home/docker-compose.yml up -d kafka
else
    echo "Kafka is already running"
fi

 

bash ์˜ -z ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰์ค‘์ธ์ง€ ํ™•์ธํ•˜๊ณ , ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค๋ฉด docker-compose๋ฅผ ์ด์šฉํ•˜์—ฌ

ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.

 

 

1-3. service.sh

#!/bin/bash

# ์ž…๋ ฅ๋ฐ›์€ ์„œ๋น„์Šค ์ด๋ฆ„
SERVICE_NAME=$1

# ์„œ๋น„์Šค ์ด๋ฆ„์— ๋”ฐ๋ผ ๋ฐฐํฌํ•  ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„ ์„ค์ •
case "$SERVICE_NAME" in
  "api-gateway")
    TARGET_SERVICE="api-gateway"
    ;;
  "noti-service")
    TARGET_SERVICE="noti-service"
    ;;
  "user-service")
    TARGET_SERVICE="user-service"
    ;;
  "weather-service")
    TARGET_SERVICE="weather-service"
    ;;
  "all")
    TARGET_SERVICE="api-gateway noti-service user-service weather-service"
    ;;
  *)
    echo "Invalid service name: $SERVICE_NAME"
    exit 1
    ;;
esac

echo "$SERVICE_NAME service start..."
docker-compose -f /home/docker-compose.yml up -d $SERVICE_NAME

 

Github Action Input์œผ๋กœ ๋ฐ›์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ, ์–ด๋–ค ์„œ๋น„์Šค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ตœ์‹ ํ™”ํ• ์ง€ ์„ ํƒํ•œ๋‹ค. 

 

 

2. docker-compose.yml

 

version: '3'

services:

  api-gateway:
    container_name: api-gateway
    image: ${DOCKERHUB_USERNAME}/waither-gateway
    expose:
      - "8000"
    restart: always

    volumes:
      - /home/ec2-user/logs/api-gateway:/logs

  config:
    container_name: config
    image: ${DOCKERHUB_USERNAME}/waither-config
    expose:
      - "8888"
    environment:
      CONFIG_GIT_URI : ${CONFIG_GIT_URI}
      CONFIG_PASSPHRASE : ${CONFIG_PASSPHRASE}
	  CONFIG_PRIVATE_KEY : ${CONFIG_PRIVATE_KEY}
	restart: always

    volumes:
      - /home/ec2-user/logs/config:/logs

  eureka:
    container_name: eureka
    image: ${DOCKERHUB_USERNAME}/waither-eureka
    expose:
      - "8761"
    restart: always

    volumes:
      - /home/ec2-user/logs/eureka:/logs

  user-service:
    container_name: user-service
    image: ${DOCKERHUB_USERNAME}/waither-user
    expose:
      - "8080"
    restart: unless-stopped #์ˆ˜๋™์œผ๋กœ ์ค‘์ง€๋˜์ง€ ์•Š๋Š” ์ด์ƒ ํ•ญ์ƒ ์žฌ์‹คํ–‰
    volumes:
      - /home/ec2-user/logs/user-service:/logs

  weather-service:
    container_name: weather-service
    image: ${DOCKERHUB_USERNAME}/waither-weather
    expose:
      - "8081"
    restart: unless-stopped
    volumes:
      - /home/ec2-user/logs/weather-service:/logs

  noti-service:
    container_name: noti-service
    image: ${DOCKERHUB_USERNAME}/waither-noti
    expose:
      - "8082"
    restart: unless-stopped
    volumes:
      - /home/ec2-user/logs/noti-service:/logs
        
  zookeeper:
    image: wurstmeister/zookeeper:latest
    container_name: zookeeper
    ports:
      - "2181:2181"

  kafka:
    image: wurstmeister/kafka:latest
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

 

ํ•„์š”ํ•œ ์„œ๋น„์Šค๋“ค์„ ๋ชจ๋‘ ๊ธฐ์ž…ํ–ˆ๋‹ค.

 

ํ•„์š”ํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋“ค์€ Github Action Runner์—์„œ

export ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰๋œ๋‹ค.

 

 

3. ci.yml

Continuous Integration (์ง€์†์  ํ†ตํ•ฉ)์„ ์œ„ํ•œ ๊นƒํ—ˆ๋ธŒ ์•ก์…˜ ์›Œํฌํ”Œ๋กœ์ด๋‹ค.

name: Backend CI

on:
  pull_request:
    branches:
      - prod
      - develop

jobs:
  build-test:
    runs-on: ubuntu-latest

    steps:
      - name: action checkout
        uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: |
          chmod +x ./config-service/gradlew
          chmod +x ./noti-service/gradlew
          chmod +x ./user-service/gradlew
          chmod +x ./weather-service/gradlew

      - name: Build with Gradle - config
        run: |
          cd config-service
          ./gradlew clean build -x test 
        env:
          CONFIG_GIT_URI: ${{ secrets.CONFIG_GIT_URI }}
          CONFIG_PASSPHRASE: ${{ secrets.CONFIG_PASSPHRASE }}
          CONFIG_PRIVATE_KEY: ${{ secrets.CONFIG_PRIVATE_KEY }}
        
      - name: Run config-service
        run: |
          ./gradlew bootRun &
          cd ..

      - name: Wait for config-service to start
        run: sleep 5
  
      - name: Build with Gradle - noti-service
        run: |
          cd noti-service
          ./gradlew clean build -x test 
          cd ..
  
      - name: Build with Gradle - user-service
        run: |
          cd user-service
          ./gradlew clean build -x test 
          cd ..
  
      - name: Build with Gradle - weather-service
        run: |
          cd weather-service
          ./gradlew clean build -x test 
          cd ..

 

๋‹ค๋ฅธ ์„œ๋น„์Šค๋“ค์ด ๋นŒ๋“œ๋˜๊ธฐ ์œ„ํ•ด์„  Config-Service๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—

 

Config-Service๋ฅผ ๋จผ์ € ๋นŒ๋“œ & ์‹คํ–‰ํ•˜๊ฒŒ๋œ๋‹ค.

 

Config-Service ๋Š” private key๋กœ ์„ค์ • ํŒŒ์ผ๋“ค์„ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— 5์ดˆ๋งŒํผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‹ค์Œ ์„œ๋น„์Šค๋“ค์„ ๋นŒ๋“œํ•œ๋‹ค.

 

 

 

4. cd.yml

์ตœ์ข…์ ์œผ๋กœ Continuous Deploy ๋ฅผ ์œ„ํ•œ ๊นƒํ—ˆ๋ธŒ ์•ก์…˜ ์›Œํฌํ”Œ๋กœ์ด๋‹ค.

name: Backend CI/CD with Gradle

on:
   workflow_dispatch:
     inputs:
       service:
         description: 'Choose Service to deploy. Default is all.'
         required: true
         default: 'all'
         type: choice
         options:
         - all
         - api-gateway
         - noti-service
         - user-service
         - weather-service

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      #Setting JDK
      - name: Set up JDK 17
        uses: actions/setup-java@v2
        with:
          java-version: '17'
          distribution: 'temurin'

      #gradlew chmod
      - name: Grant execute permission for gradlew
        run: |
          chmod +x ./apiGateway-service/gradlew
          chmod +x ./config-service/gradlew
          chmod +x ./Eureka/gradlew
          chmod +x ./noti-service/gradlew
          chmod +x ./user-service/gradlew
          chmod +x ./weather-service/gradlew
      
      # DockerHub Login
      - name: Docker Hub Login
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      #Config-Service Build & Docker Push
      - name: Build with Gradle - config
        run: |
          cd config-service
          ./gradlew clean build -x test
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-config .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-config
        env:
          CONFIG_GIT_URI: ${{ secrets.CONFIG_GIT_URI }}
          CONFIG_PASSPHRASE: ${{ secrets.CONFIG_PASSPHRASE }}
          CONFIG_PRIVATE_KEY: ${{ secrets.CONFIG_PRIVATE_KEY }}

      #Config-Service Run
      - name: Run config-service
        run: |
          ./gradlew bootRun &
          cd ..
      #Wait 5 sec
      - name: Wait for config-service to start
        run: sleep 5

      #apiGateway-Service Build & Docker Push
      - name: Build with Gradle - apiGateway
        run: |
          cd apiGateway-service
          ./gradlew clean build -x test
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-gateway .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-gateway
          cd ..
          
      #Eureka Build & Docker Push
      - name: Build with Gradle - Eureka
        run: |
          cd Eureka
          ./gradlew clean build -x test 
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-eureka .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-eureka
          cd ..

      #Noti-Service Build & Docker Push
      - name: Build with Gradle - noti-service
        run: |
          cd noti-service
          ./gradlew clean build -x test 
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-noti .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-noti
          cd ..

      #User-Service Build & Docker Push
      - name: Build with Gradle - user-service
        run: |
          cd user-service
          ./gradlew clean build -x test 
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-user .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-user
          cd ..

      #Weather-Service Build & Docker Push
      - name: Build with Gradle - weather-service
        run: |
          cd weather-service
          ./gradlew clean build -x test 
          docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/waither-weather .
          docker push ${{ secrets.DOCKERHUB_USERNAME }}/waither-weather
          cd ..
  
  deploy:
    name : Connect to EC2 and re-run container
    needs : build
    runs-on : ubuntu-latest
    steps:
      - name: Deploy to Server
        uses: appleboy/ssh-action@v0.1.6
        env:
          SERVICE_NAME: ${{ github.event.inputs.service }}
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          password: ${{ secrets.EC2_PASSWORD }}
          port: ${{ secrets.EC2_SSH_PORT }}
          timeout: 60s
          script: |
            export CONFIG_GIT_URI=${{ secrets.CONFIG_GIT_URI }}
            export CONFIG_PASSPHRASE=${{ secrets.CONFIG_PASSPHRASE }}
            export DOCKERHUB_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}
            export CONFIG_PRIVATE_KEY=${{ secrets.CONFIG_PRIVATE_KEY }}

            bash /home/docker.sh
            bash /home/common.sh
            bash /home/service.sh

 

์ฒ˜์Œ์—” workflow_dispatch๋ฅผ ์ด์šฉํ•˜์—ฌ ์žฌ๋ฐฐํฌํ•œ ์„œ๋น„์Šค๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.

 

workflow_dispatch๋ฅผ ์ด์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ๋ธŒ๋žœ์น˜๊ฐ€ ๊ธฐ๋ณธ ๋ธŒ๋žœ์น˜์— ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

- build ์ž‘์—…

 

ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ gradle ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , docker image ๋นŒ๋“œ ํ›„ pushํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.

 

 

 

- deploy ์ž‘์—…

 

AWS EC2์— ์ ‘์† ํ›„, ํ•„์š”ํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋“ค์„ ์„ค์ •ํ•˜๊ณ 

 

๋ฏธ๋ฆฌ ์ž‘์„ฑํ•ด ๋‘์—ˆ๋˜ ์Šคํฌ๋ฆฝํŠธ ์„ธ๊ฐ€์ง€๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

 

 

 

docker -> common -> service ์ˆœ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ์ง€ ์„œ๋น„์Šค๊ฐ€ ์˜ค๋ฅ˜ ์—†์ด ๋™์ž‘ํ•œ๋‹ค.

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ ์ปจํ…Œ์ด๋„ˆ 7๊ฐœ๊ฐ€ ์‹คํ–‰๋˜๋Š”๋ฐ,

 

์ฒ˜์Œ์—” EC2 ํ”„๋ฆฌํ‹ฐ์–ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ CPU 1๊ฐœ์ธ t2.micro๋กœ ์ฒ˜์Œ์— ์‹คํ–‰ํ–ˆ์„ ๋• ์„œ๋ฒ„๊ฐ€ ๊ณผ๋ถ€ํ™”๋˜๊ณ  ๋จนํ†ต์ด ๋๋‹ค....

์ƒ๊ฐ๋ณด๋‹ค ์•ฝํ•œ t2.micro

 

t2.medium๊นŒ์ง€๋Š” ๋™์ž‘ํ–ˆ๋‹ค.