Github Action을 활용한 자동화 적용

김도형·2023년 11월 3일
0

CI/CD를 적용해보자

목록 보기
1/2
post-thumbnail

준비해야하는 내용들입니다.

  • AWS( EC2, RDS )
  • DockerHub
  • Github

프로젝트 yml 분리

application.yml

spring:
  profiles:
    #active:
      #local {서버를 시작할 때 적용할 yml명}
    group:
      local-env:
        - local
      dev-env:
        - dev
      prod-env:
        - prod

application-dev.yml

spring:
  config:
    activate:
      on-profile: dev

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://{EndPoint}:{Port}/{DB_name}?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: {DB_username}
    password: {DB_password}

  jpa:
    open-in-view: true
    hibernate:
      ddl-auto: create
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    properties:
      hibernate:
        format_sql: true
    defer-datasource-initialization: true

logging:
  level:
    '[org.springframework.boot.web]': INFO

Dockerfile 생성

Dockerfile

FROM openjdk:17-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

docker-compose.yml 생성

docker-compose.yml

version: '3'

services:
  springboot:
    container_name: spring-dev # ec2내에서 동작하는 컨테이너명
    image: {docker-username}/{docker_repo}:latest
    ports:
      - 8080:8080
    environment:
      SPRING_PROFILES_ACTIVE : dev-env # 사용할 profile
    networks:
      - my_network

networks:
  my_network:
    driver: bridge

파일 생성 위치


Github Action yml 생성

Repository Actions 탭에서 Java with Gradle 선택

name: {github action명}

on:
  push:
    branches: [ "{브랜치명}" ]
  pull_request:
    branches: [ "{브랜치명}" ]

jobs:
  develop:
    # 실행 환경
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v3

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

      # Gradle Caching
      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      
      # application-dev.yml
      - name: Copy dev Secret
        env:
          DEV_SECRET: ${{ secrets.APPLICATION_DEV_YML }}
          DEV_SECRET_DIR: src/main/resources
          DEV_SECRET_DIR_FILE_NAME: application-dev.yml
        run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME

      # application-jwt.yml
      # - name: Copy jwt Secret
      #   env:
      #     DEV_SECRET: ${{ secrets.APPLICATION_JWT_YML }}
      #     DEV_SECRET_DIR: src/main/resources
      #     DEV_SECRET_DIR_FILE_NAME: application-jwt.yml
      #   run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME

      # ./gradlew 권한 설정
      - name: ./gradlew 권한 설정
        run: chmod +x ./gradlew

      # Gradle Build (Test 제외)
      - name: Build with Gradle
        run: ./gradlew build -x test

      # Docker Build하고 DockerHub에 Push
      - name: Docker Build & Push to DockerHub
        run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest .
          docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest
      
      # GitHub IP를 요청
      - name: Get GitHub IP 
        id: ip
        uses: haythem/public-ip@v1.2

      # AWS 세팅
      - name: AWS Setting
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
          aws-region: ap-northeast-2

      # GitHub IP를 AWS에 추가
      - name: Add GitHub IP to AWS
        run: |
          aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
      
       # docker-compose.yml 파일 EC2로 복사
      - name: Copy docker-compose.yml to EC2
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.KEY }}
          port: 22
          source : "./docker-compose.yml"
          target : "./{EC2에 생성할 디렉토리명}"

      # SSH Key로 서버에 접속하고 docker-compose image를 pull 받고 실행하기
      - name: Access Server with SSH Key, pull and execute docker-compose image
        uses: appleboy/ssh-action@v0.1.6
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.KEY }}
          port: 22
          script: |
            cd {EC2에 생성할 디렉토리명}
            sudo docker-compose down
            sudo docker-compose pull
            sudo docker-compose up -d
            sudo docker image prune -f
            
      # Security Group에서 Github IP를 삭제
      - name: Remove Github IP From Security Group
        run: |
          aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

위 내용에서 아래의 내용만 수정해주시면 됩니다.
{github action명} : 저는 deploy로 설정했습니다.
{브랜치명} : 저는 개발 브랜치인 dev로 설정했습니다.
{EC2에 생성할 디렉토리명} : 저는 제 프로젝트 서비스명으로 설정했습니다. ex) youtube


Github Action Secrets 생성

아래 형식으로 secret을 추가하면 됩니다.
APPLICATION_DEV_YML : application-dev.yml 내용을 base64로 인코딩
APPLICATION_JWT_YML : application-jwt.yml 내용을 base64로 인코딩
DOCKER_USERNAME : dockerhub 사용자명
DOCKER_PASSWORD : dockerhub 비밀번호
DOCKER_REPO : dockerhub 레포지토리명
AWS_ACCESS_KEY : IAM access key
AWS_SECRET_KEY : IAM access secret key
AWS_SG_ID : EC2 보안 그룹의 id
EC2_HOST : EC2 인스턴스의 public IPv4 DNS
EC2_USERNAME : ubuntu ( EC2 인스턴스의 사용자명 )
KEY : pem key 텍스트 내용 ( BEGIN부터 END까지 모두)

발생했던 문제

AWS_SG_ID (보안 그룹 ID)를 가져오기 위해 IAM 키를 발급했다.
근데 사용자 그룹의 권한을 설정하지 않아서 254 에러코드가 발생했었다.

0개의 댓글

관련 채용 정보