[크래프톤 정글 3기] 1/10(수) TIL

ClassBinu·2024년 1월 10일
0

크래프톤 정글 3기 TIL

목록 보기
85/120

08:44 입실
Github actions 자동 배포 환경 변수 문제 해결해보기

도커

환경변수

환경 변수 미인식 문제는 파일 마운트가 아니라 환경변수를 컨테이너에 직접 주입하는 방식으로 해결된 듯

docker run -d -p 80:3009 --name junglepedia_ai_be --restart always --env-file /home/ec2-user/be/.env ${{ env.DOCKER_IMAGE }}:latest

우선 컨테이너는 실행된다.
환경변수는 이제 인식한다!!!
근데 DB 접속이 안됨.

네트워크 설정 문제거나, 환경변수 따옴표 문제 때문일까?

근데 하다보니까 도커 명령어도 손에 익긴 함.
생존의 타이핑이랄까..?

github actions runner

러너가 작업을 인식하려면 다음 명령어가 실행 중이거나, 백그라운드에서 실행되어야 함.

nohup ./run.sh &

자동 배포 성공!!!

배포 오류 복기

  1. 환경 변수 파일을 마운트 했더니 인식을 못함.
  2. 환경 변수는 --env-file로 주입했으나 .env를 디렉토리로 인식함.
  3. .env를 새로 생성하자 환경변수 파일 인식은 하지만 밸류가 따옴표로 감싸진 값은 인식 하지 못함.
  4. 환경변수 따옴표 제거하자 배포 성공

빌드 전 테스트 추가

  test:
    name: Run Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '20' # 프로젝트에 맞는 Node.js 버전으로 설정
      - name: Install dependencies
        run: npm install
      - name: Run Jest tests
        run: npx jest users.controller.spec.ts

하지만 현재 yaml에서는 각 단계가 독립적임.
needs: 로 전 단계 실패 시 워크플로우 중지되게 할 수 있음.

jobs:
  test:
    # 테스트 job 정의 ...

  build:
    needs: test
    # 빌드 job 정의 ...

  deploy:
    needs: build
    # 배포 job 정의 ...

최종 yaml

name: CI/CD Docker

# 트리거를 수행할 브랜치를 지정합니다.
on:
  push:
    branches: [main]

# 환경설정
env:
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/junglepedia-ai-be
  VERSION: ${{ github.sha }}
  NAME: junglepedia_ai_be

jobs:
  test:
    name: Run Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '20' # 프로젝트에 맞는 Node.js 버전으로 설정
      - name: Install dependencies
        run: npm install
      - name: Run Jest tests
        run: npx jest users.controller.spec.ts
  # 빌드 Job
  build:
    name: Build
    needs: test
    runs-on: ubuntu-latest
    steps:
      # github repository에서 checkout
      - uses: actions/checkout@v2
      # docker build 수행
      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      # GitHub 컨테이너 레지스트리에 로그인 후 빌드 & 푸시
      - name: Login to classbinu
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:latest
  # 배포 Job
  deploy:
    needs: build # build 후에 실행되도록 정의
    name: Deploy
    runs-on: [self-hosted, label-go] # AWS ./configure에서 사용할 label명
    steps:
      - name: Login to classbinu
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      # 3000 -> 80 포트로 수행하도록 지정
      - name: Docker run
        run: |
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          docker run -d -p 80:3009 --name junglepedia_ai_be --restart always --env-file /home/ec2-user/be/.env ${{ env.DOCKER_IMAGE }}:latest

액션 러너 등록

최초 설정할 때 라벨을 다 등록해야 함.
중간에 라벨 추가는 안 되고 설정을 다시 해야 함.

한 개의 리포지토리는 한 개의 러너에 대응되어야 함.
즉, 하나의 EC2 인스턴스에 여러 개의 리포지토리를 연결 할 때는 별개의 러너 디렉토리로 러너가 운영되어야 함.

EC2 용량 부족

2개의 컨테이너를 돌릴 만큼 용량이 크지 않나?
프론트엔드용 인스턴스 우선 하나 더 열었음.

최종 배포 완료

http://43.200.164.168/
(주소는 아마 조만간 닫힐 듯! 정식 배포는 아님!)

소소한 개선

삭제 옵션

포스트를 삭제하면 연관된 댓글과 좋아요/싫어요도 삭제
onDelete로 CASCADE를 지정하면 됨.

@ManyToOne(() => Post, { onDelete: 'CASCADE' })
post: Post;

발표 자료

타이머 켜 놓고 부지런히 했는데 정해진 시간 3분을 넘어서
3분 30초 함. 나만무 발표는 정말 많은 준비를 해야 할듯.
5~7분이라는데.. 흠..
말을 줄이는 게 참 어렵다.

프롬프트 엔지니어링

기본 규칙

  • 구체적 지시(Role, Task, Format)
  • 명확한 단어
  • 맥락 제공
  • 구조 형식화(다음 형식에 따라 만들어 주세요.)
  • 일관성 유지

1. Few Shot

예제(Shot)를 제공하는 것

  • Zero Shot: 예시 없음
  • One Shot: 하나의 예시
  • Few Shot: 두 개 이상의 예시

맥락을 통해 결과를 도출하는 것을 In-Context Learning

다음의 예시를 참고해서 같은 형식으로 알려주세요.

2. 역할 지정

페르소나 부여

당신은 지금부터 {}의 역할을 해야 하고,
모든 대답은 마치 {}가 하는 것처럼 해야 한다.
당신의 이름은 {} 이다.
나는 {}에게 '{}'라는 질문을 할 것이다.

3. 마크다운 활용

마크다운을 활용해서 GPT에게 이미지 출력을 지시할 수도 있다.

4. 후카츠 프롬프트

#명령문
당신은 {}입니다.
이하의 제약조건과 입력문을 토대로 최고의 {}를 출력해주세요.

#제약조건
-{}
-{}

#입력문
{}

#출력문

후카츠 씨의 원칙

  1. 챗GPT의 역할을 명확히 한다.
  2. 입력문에서 출력문을 만들 것임을 명확히 한다.
  3. 무엇을 출력할 것인지 명확히 한다.
  4. 마크업 언어를 이용하여 본문이 아닌 부분을 명확히 한다.
  5. 명령을 조목조목 명확하게 한다.
  6. 조건을 추가하여 챗GPT로부터의 출력을 제어한다.

5. 형식 지정

(기존 후카츠 템플링세 출력 형식을 추가)
...
#출력형식
{}

예시)
#출력 형식
[국가의 이름]([국가의 ISO코드]): [색상]([색상의 Hex코드])
다른 설명은 출력하지 마세요.

대괄호 영역 안에 구체적인 지시를 넣어주면, GPT는 그걸 채워서 출력함.

6. 슌스케 템플릿

변수를 설정함.

#콘텐츠의 상세
이 콘텐츠는 블로그 글입니다.

#변수
[독자] = 30대 남성
[키워드] = 애플워치
[흥미] = 애플워치 깨끗하게 쓰는 법

#커맨드
[C1] = [키워드]에 대한 [독자]의 [흥미]를 반영하여 [독자]를 대상으로 한 블로그 아웃라인을 작성해 주세요.
[C2] = 아웃라인을 따라 블로그 글을 최종 작성해 주세요.

#실행
$ run [C1][C2]

7. QnA

마치 인공지능이 답변한 것 같은 답변을 함께 제시(Few Shot)
인공지능에게 맥락을 부여하는 것.

다음 프롬프트를 추가하면 효과 높아짐.

아래 형식을 준수해서 Q&A의 형태로 답하세요.
아래 Q&A의 형식과 내용을 유지해서 다음 답변을 묘사해 주세요.

0개의 댓글