본문 바로가기
Programming

CI/CD #5 배포 구성하기 Github Actions EC2 Docker .env 생성하기 [추가자료]

by 개발자 염상진 2023. 1. 20.
이전글

CI/CD #1 배포 구성하기 Node.js 빌드
CI/CD #2 배포 구성하기 Dockerfile
CI/CD #3 배포 구성하기 Github Actions
CI/CD #4 배포 구성하기 AWS EC2 [최종]

 

 

 

 

Github Actions 배포

 

Github Actions를 통해 CI/CD 파이프라인을 구성해서 배포하는 방법까지 알아보았는데요, 추가로 환경변수를 사용해 프로젝트 완성도를 높여보도록 하겠습니다.

 

실제 프로젝트에서 JWT Token Secret이나 DB URL등은 secret 하게 관리해야 하는 변수들입니다. 따라서 .env 파일을 생성해서 환경변수를 관리하게 됩니다. 

 

 

 

 

 

하지만 git repository에는 .gitignore에 .env 파일을 추가해서 repo에 업로드하기 때문에 Github Actions를 통해 배포를 진행하면 원격 서버 컴퓨터에서는 .env 파일을 가져올 수 없습니다. 그렇다고 배포할 때 마다 원격 PC에 접속해서 .env 파일을 생성할 수도 없는 노릇이죠.

 

 

Github Actions .env 생성하는 법

 

ghcr 사용

아래 코드는 Github Runner로 ghcr(Github Container Registry)에 로그인 한 후 Docker로 빌드한 이미지를 업로드하는 build 파이프라인입니다.

name: CI/CD pipeline 

# 트리거를 셋팅합니다.
on:
  push:
    # main 브랜치에서 push가 되었을 때 작동합니다.
    branches: [main]

# 도커 이미지 빌드
env:
  # 환경변수 설정(Github Context)
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/pipeline-ghcr-image
  VERSION: ${{ github.sha }}
  NAME: go_cicd

# 세부 작업 설정
jobs:
  build:
    name: Build
    # runner 실행환경을 ubuntu로 설정합니다.
    runs-on: ubuntu-latest
    # step에 따라 아래 과정이 수행됩니다.
    steps:
      # github.com/actions/checkout 코드 사용
      - uses: actions/checkout@v2

      # github.com/docker/setup-buildx-action 코드 사용
      - 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-
            
      # 환경변수를 생성합니다.
      - name: Generate .env
        run: |
          echo "MONGO_URL=$MONGO_URL" >> ./.env
          echo "PORT=$PORT" >> ./.env
        env:
          MONGO_URL: ${{ secrets.MONGO_URL }}
          PORT: 7777
      
      # ghcr에 로그인 합니다.
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
          
      # Dockerfile 빌드 && ghcr push          
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          # path context 반드시 지정(./ : 현재 위치)
          context : ./
          # Dockerfile 위치 지정
          file : .//Dockerfile
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:latest
  # 배포 Job
  deploy:
    # build 후에 실행되도록 정의
    needs: build 
    name: Deploy
    # runner가 돌아갈 환경이 self-hosted 환경
    runs-on: [self-hosted] 
    
    # ghcr 로그인
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
      # docker image를 실행합니다.
      - name: Docker run
        run: |
          # 기존 Docker Container 삭제
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          # Server에서 80번 포트에 접속 -> Docker 7777번 포트로 접속됨
          docker run -d -p 80:7777 --name go_cicd --restart always ${{ env.DOCKER_IMAGE }}:latest

 

 

 

 

-name : Generate .env 부분이 .env 파일을 생성하는 로직입니다. echo 명령어를 사용하구요, 하위에 env 태그를 삽입해서 변수로 사용할 수 있습니다.

중요한 부분은 가장 하위에 있는 Build and push 부분입니다. codespace에 있는 docker/build-push-action을 사용합니다.

 

.env 파일을 생성하려고 하는데 막상 서버 PC에는 env파일이 생성되지 않는 문제는 path context가 지정되어 있지 않기 때문입니다. Docker Build를 할 때 어디서 시작해야 하는지, Dockerfile은 어디에 위치해있는지 위치를 지정해주지 않으면 정상적으로 Dockerfile 빌드가 불가능합니다. 

 

DockerHub 사용

코드를 배포할 저장소로 DockerHub를 사용하신다면 Deploy 파이프라인에서 Docker Image를 pull 해주시면 됩니다. 

name: CI/CD pipeline

on:
  push:
    branches: [main]

env:
  DOCKER_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/pipeline-image
  VERSION: ${{ github.sha }}
  NAME: go_cicd

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      
      # DockerHub 로그인        
      - name: Login to DockerHub
        uses: docker/login-action@v1
        # Repository > Setting > Secret에서 환경변수 추가하세요
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      
      - name: Generate .env
        run: |
          echo "MONGO_URL=$MONGO_URL" >> ./.env
          echo "PORT=$PORT" >> ./.env
        env:
          MONGO_URL: ${{ secrets.MONGO_URL }}
          PORT: 7777

      # DockerHub에 Image push
      - name: Build And Push
        uses: docker/build-push-action@v2
        with:
          context: ./
          file: .//Dockerfile
          platforms: linux/amd64
          push: true
          tags: ${{ env.DOCKER_IMAGE }}
  
  deploy:
    needs: build 
    name: Deploy
    runs-on: [self-hosted] 
    steps:
      
      # docker image를 실행합니다.
      - name: Docker run
        run: |
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
			
          # DockerHub에서 Docker Image를 가져옴
          docker pull ${{ env.DOCKER_IMAGE }}:latest 

          docker run -d -p 80:7777 --name ${{ env.NAME }} --restart always ${{ env.DOCKER_IMAGE }}:latest

 

 

 

 

 

Github Actions .env 파일 정리

 

Github Actions은 Github에서 작은 깡통 컴퓨터를 한대 임대해주는 개념입니다. 이 컴퓨터의 이름은 runner입니다. 이 컴퓨터를 처음 실행하면 정말 아무것도 없기 때문에 DockerHub에 로그인한다거나, 우리가 push한 코드를 runner에서 사용하기 위해서는 누군가가 만들어서 배포해준 actions/checkout@2 같은 repo가 필요하게 됩니다.

 

 

 

 

 

.env 파일이 생성되지 않으시는 분들은 Dockerfile을 빌드하는 스텝에서 아래 2줄을 삽입해서 문제를 해결하시기 바랍니다. .//은 현재 디렉토리 하위에 계층 상관없이 후손 요소 중 Dockerfile을 사용하겠다는 path syntac입니다. 

context: ./
file: .//Dockerfile

 

build context는 Dockerfile을 빌드할 때 사용됩니다. 명령문 끝에 적은 점(.)이 build context가 됩니다. 

$ docker build --tag image:1.0.0 .

path context(build context)에 대해 더 알아보고 싶으신 분들은 아래 사이트 참고 하시면 되겠습니다.

https://docs.docker.com/build/building/context/

 

🚀️ 도움이 되셨다면 구독좋아요 부탁드립니다 👍️

 

 

Reference

https://docs.docker.com/build/ci/github-actions/examples/#local-registry

댓글