Github Actions CI-CD구축(NCP, Docker, SpringBoot)

dh·2023년 3월 4일
1
post-thumbnail

github actions를 이용해 spring boot프로젝트를 네이버클라우드 서버와 연동하는 CI-CD를 구축하려고 합니다.

NCP서버 생성


위 스펙으로 서버 생성을 했고 서버이름 설정, 인증키 생성, default-acg를 선택해서 서버 생성.
저는 numble 프로젝트를 신청해 네이버클라우드 크레딧을 지원 받아서 사용했습니다.

서버 접속 방법

putty설치 -> Host Name: 서버 접속용 공인 IP, port: 포트포워딩에서 설정한 외부 포트 입력 -> open -> 사용자 :root 비번은 아래에서 서버 만들때 생성한 인증키 파일을 이용해 확인 가능

Container Registry, Object Storage 생성

container registry에 도커 컨테이너 이미지를 저장할 수 있는 Docker Hub?같은 개념임.
Container Registry를 사용하기 위해서는 프라이빗 도커 컨테이너 이미지를 저장하기 위한 Object Storage(AWS의 S3같은 개념?)를 먼저 생성해야 한다고함.
Object Storage의 버킷에 Docker 컨테이너 이미지가 저장되고 레지스트리로 이미지를 pull, push가 가능하다.

Github Actions


저는 maven프로젝트라 maven으로 build를 진행했습니다.

name: Java CI-CD with Maven

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build_dockerpush:
    runs-on: ubuntu-latest
    env :
      APPLICATION: ${{ secrets.APPLICATION }}
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: maven
        
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
      
    - name: make application.properties
      if: true 
      run: |
       touch ./src/main/resources/application.properties
       echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
            
    - name: Build with Maven
      run: mvn -B package --file pom.xml

    - name: Login to NCP Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ secrets.NCP_CONTAINER_REGISTRY }}
        username: ${{ secrets.NCP_ACCESS_KEY }}
        password: ${{ secrets.NCP_SECRET_KEY }} 
    - name: build and push
      uses: docker/build-push-action@v3
      with:
        context: .
        file: ./Dockerfile
        push: true
        tags: ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name:latest
        cache-from: type=registry,ref=${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name:latest
        cache-to: type=inline


  pull_deploy:
    name: Connect server ssh and pull from container registry
    needs: build_dockerpush
    runs-on: ubuntu-latest
    steps:
      - name: connect ssh
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.DEPLOYMENT_HOST }}
          username: ${{ secrets.DEPLOYMENT_USERNAME }}
          password: ${{ secrets.DEPLOYMENT_PASSWORD }}
          port: ${{ secrets.DEPLOYMENT_PORT }}
          script: |
            docker pull ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name
            docker stop $(docker ps -a -q)
            docker rm $(docker ps -a -q)
            docker run -d -p 8080:80 ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name
            docker image prune -f

build & docker image build push

build_dockerpush:
    runs-on: ubuntu-latest
    env :
      APPLICATION: ${{ secrets.APPLICATION }}
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: maven

Java with Maven에 있는 기본 내용으로 실행환경 ubuntu환경에서 실행, JDK 설치
uses: actions/checkout@v3는 브랜치에서 코드를 가져오는 건데 빌드후에 밑에 또 이게 있었는데 이거 때매 빌드한 target폴더가 날아가서 /target: no such file or directory가 계속 떴다.(이것 때매 삽질을 엄청했다..😢)

 - name: make application.properties
      if: true # branch가 develop일 때
      run: |
       touch ./src/main/resources/application.properties
       echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
 - name: Build with Maven
      run: mvn -B package --file pom.xml

applicatino.properties에 db 비밀번호 등 민감한 정보를 설정하고 보통 gitignore에 등록하는데 이것 때문에 빌드하는데
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.가 떴다.
빌드가 실패하거나 페이지를 못찾는 등 계속 실패했다(github action에는 다 초록색 체크로 떠서 빌드가 성공한줄 알았는데 세부적으로 보니 빌드실패가 되있었다. 이게 2차삽질..😭)
따라서 properties 내용을 깃헙 secret에 등록 해주고 build할 때 정보를 꼭 써야 된다.

- name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

주로 intel기반 x86 CPU를 사용하는데 멀티 아키텍처 플랫폼(amd64(x86_64), arm64/v8)을 지원하는 이미지를 만들때 사용한다고 함
도커 이미지도 빌드하는 환경에 맞는 이미지가 만들어진다고 함..

 - name: Login to NCP Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ secrets.NCP_CONTAINER_REGISTRY }}
        username: ${{ secrets.NCP_ACCESS_KEY }}
        password: ${{ secrets.NCP_SECRET_KEY }} 

NCP container registry에 로그인
registry : Public Endpoint(Container Registry페이지에서 확인가능)
username : access key ID(계정관리의 인증키 관리에서 확인)
password : secret key(계정관리의 인증키 관리에서 확인)

 - name: build and push
      uses: docker/build-push-action@v3
      with:
        context: .
        file: ./Dockerfile
        push: true
        tags: ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name:latest
        cache-from: type=registry,ref=${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name:latest
        cache-to: type=inline

Dockerfile기반으로 이미지를 생성하여 registry에 push 한다.
원래 jar로 빌드 했는데 나중에 배포하고 보니 404가 뜸
spring boot jar가 jsp를 지원 하지 않는다고 한다.
그래서 war로 빌드 했다.

Dockerfile(프로젝트 최상위에 생성시키면 됨)

FROM adoptopenjdk/openjdk11
ARG JAR_FILE=target/*.war
COPY ${JAR_FILE} /app.war
ENTRYPOINT ["java","-jar","/app.war"]
EXPOSE 8080

Docker image pull & Deploy

pull_deploy:
    name: Connect server ssh and pull from container registry
    needs:  build_dockerpush
    runs-on: ubuntu-latest
    steps:
      - name: connect ssh
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.DEPLOYMENT_HOST }}
          username: ${{ secrets.DEPLOYMENT_USERNAME }}
          password: ${{ secrets.DEPLOYMENT_PASSWORD }}
          port: ${{ secrets.DEPLOYMENT_PORT }}
          script: |
            docker pull ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name
            docker stop $(docker ps -a -q)
            docker rm $(docker ps -a -q)
            docker run -d -p 8080:80 ${{ secrets.NCP_CONTAINER_REGISTRY }}/tag-name
            docker image prune -f

레지스트리에서 이미지를 받아 실행하는 부분이다.
putty로 서버 접속할 때 정보를 secret으로 등록해서 사용하면 된다.
host : 서버접속용 공인ip
username : 서버접속할 때 user
password : 서버접속할 때 비번
port : 외부포트

결과

페이지 수정하고 깃헙에 push하면 서버에 자동으로 배포되고, 공인ip:8080으로 접속한 결과 페이지가 잘 나온다!! (이부분은 ACG설정에서 8080포트를 열어줘야 한다.)

0개의 댓글