GitHub Actions, Private Registry를 활용한 CI/CD 파이프라인 구축하기

KYEONGMIN CHO
cloudtype
Published in
22 min readJun 14, 2023

안녕하세요, 클라우드타입 입니다👋

컨테이너 방식으로 어플리케이션을 실행하고 CI/CD 파이프라인을 구축하는 것과 관련하여 다양한 콘텐츠를 블로그에 연재하였는데요. 이번에는 GitHub Actions를 활용하여 외부의 Private Registry로 부터 이미지를 불러와 클라우드타입에서 어플리케이션을 실행하는 방법에 대해 다루고자 합니다.

현재 여러 글로벌 테크 기업은 엔터프라이즈 및 개인 작업 환경에 적합한 이미지 레지스트리를 Private 형태로 활용할 수 있도록 제공하고 있습니다. 대표적으로는 Docker 社 에서 제공하는 Docker Hub가 있으며 AWS ECR, GCP Artifact Registry, GitHub Container Registry 등 다양한 선택지가 있어 각자의 환경에 맞게 취사선택하면 되겠죠. 이번 포스트에서는 각 서비스 제공자 별 레지스트리를 GitHub Actions와 연동하고 어플리케이션을 배포하는 과정에 대해 알아봅시다.

Docker Hub

Docker Hub는 Docker 社에서 운영하는 레지스트리 서비스입니다. Docker가 설치된 환경에서 기본적으로 참조하는 레지스트리이며, 대부분의 오픈소스 이미지가 업로드되어 있습니다. 회원가입을 진행하면 Personal이라고 하는 무료 플랜으로 시작하게 되는데 2023년 6월 현재 기준, 공개 저장소는 무한, 비공개 저장소는 1개를 생성할 수 있습니다.

1. Access Token 발급

Docker Hub 계정을 만든 후 우측 상단의 계정명이 있는 버튼을 클릭합니다. 이어 Account Settings-Security 메뉴로 접속한 후에 New Access Token 버튼을 클릭합니다.

Access Token Description 필드에 토큰의 용도나 역할을 구분할 수 있는 문구를 작성하고 Access permissionsRead & Write 값을 선택합니다.

생성된 토큰 값을 안전한 위치에 보관합니다. 토큰은 생성 당시 최초 1회에 한해 조회할 수 있으며, 팝업창을 닫으면 다시 조회가 불가능합니다.

2. 클라우드타입에 Access Token 등록

클라우드타입에 로그인 후, 환경설정의 통합 기능 페이지로 접속합니다. 이어 컨테이너 저장소 항목의 컨테이너 저장소 연결하기 버튼을 누릅니다.

레지스트리는 Docker Hub를 선택하고 유저명에는 Docker Hub에 가입 당시 설정한 username, 비밀번호에는 Access Token 값을 입력하고 연결하기 버튼을 누릅니다.

3. 클라우드타입 API 키 발급

클라우드타입 환경설정의 인증 페이지로 접속합니다. 이어 API 키 항목의 새로운 API 키 생성버튼을 누릅니다.

생성된 API 키 값을 안전한 곳에 보관합니다. 토큰은 생성 당시 최초 1회에 한해 조회할 수 있으며, 팝업창을 닫으면 다시 조회가 불가능합니다.

4. Docker Hub 이미지 저장소 생성

Docker Hub 로그인 후 초기 페이지에서 Create repository 버튼을 누릅니다.

Repository Name은 이미지명으로 활용되며, 희망하는 이름을 작성하면 됩니다. 하단의 Visibility는 Private으로 설정합니다.

이미지 저장소가 알맞게 생성되었는지 확인합니다.

5. GitHub Actions Workflows 세팅

GitHub Actions와 Docker Hub를 연동하기 위해서는 workflow 명세에서 Docker Hub 계정명과 토큰값을 참조할 수 있도록 GitHub 저장소에 secret을 등록해야 합니다. Settings-Secrets and variables-Actions 페이지로 접속 후 New repository secret 버튼을 클릭합니다.

등록해야할 secret은 다음과 같습니다.

  • DOCKERHUB_USERNAME: Docker Hub 계정명
  • DOCKERHUB_TOKEN: Docker Hub 계정 Access Token 값
  • CLOUDTYPE_TOKEN: 클라우드타입 API 키 값
name: Create and publish a Docker image to Docker Hub, Deploy to Cloudtype

on:
push:
branches:
- main

env:
IMAGE_NAME: [이미지명(저장소명)]

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=sha

- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Deploy to Cloudtype
uses: cloudtype-github-actions/deploy@v1
with:
token: ${{ secrets.CLOUDTYPE_TOKEN }}
project: [스페이스명]/[프로젝트명]
stage: main
yaml: |
name: [서비스명]
app: container
options:
ports: [포트번호]
image: ${{ steps.meta.outputs.tags }}

배포하고자 하는 GitHub 저장소에 위와 같이 GitHub Actions Workflows 명세를 세팅합니다. 다음의 항목은 환경에 맞게 변경하여 적용해야 합니다.

  • 이미지명
  • 스페이스명
  • 프로젝트명
  • 서비스명
  • 포트번호

workflows 명세를 GitHub 저장소에 커밋하면 GitHub Actions가 실행됩니다. 저장소의 Actions 탭으로 들어가 해당 Jobs가 잘 실행되었는지 확인합니다.

GitHub Actions를 통해 빌드된 이미지가 위와 같이 Docker Hub에 잘 반영된 것을 볼 수 있습니다.

workflows에서 설정한 클라우드타입 스페이스 내 프로젝트에 접속하면 해당 어플리케이션이 정상 배포되었음을 확인할 수 있습니다.

AWS ECR

AWS ECR은 AWS에서 제공하는 레지스트리 서비스이며, 이미지 스캔 및 암호화 등을 지원하고 1년 동안 제공되는 프리티어 계정에서 매월 500MB의 Private 저장소를 무료로 사용할 수 있습니다.

1. AWS IAM 생성 및 Access Key 발급

AWS의 IAM 콘솔에서 액세스 관리-사용자 페이지에 접속한 후 사용자 추가 버튼을 누릅니다.

희망하는 사용자 이름을 작성 후 다음으로 넘어갑니다.

권한 옵션에서 직접 정책 연결을 선택하고 AmazonEC2ContainerRegistryFullAccess를 검색하여 체크박스에 체크한 후 다음으로 넘어갑니다.

별도 설정 없이 사용자 생성 버튼을 누릅니다.

생성된 사용자 페이지에서 콘솔 로그인의 콘솔 로그인 활성화 버튼을 누릅니다.

콘솔 엑세스 항목에서 활성화를 선택하고 암호 설정에서 사용자 지정 암호를 선택한 후 사용할 암호를 입력합니다.

표시된 콘솔 로그인 URL은 추후 실제 컨테이너 레지스트리를 생성할 때 사용되므로 잘 저장해놓습니다.

다음은 해당 사용자에 대한 액세스 키를 발급하도록 하겠습니다. 액세스 키 만들기 버튼을 클릭합니다.

AWS 외부에서 실행되는 애플리케이션을 선택합니다.

적당한 설명 태그 값을 작성 후 액세스 키 만들기 버튼을 누릅니다.

발급된 액세스 키와 비밀 액세스 키를 안전한 곳에 저장합니다.

2. AWS ECR 저장소 생성 및 접속 토큰 발급

콘솔 로그인 URL을 통해 생성했던 사용자 계정으로 로그인합니다.

리포지토리 생성 화면에서 표시 여부를 프라이빗으로 선택하고 적절한 이름의 리포지토리 이름을 작성한 후 리포지토리 생성 버튼을 누릅니다.

표시한 URI에서 ‘/’ 이하를 제외한 [ID].dkr.ecr.ap-northeast-2.amazonaws.com 부분을 기록해놓습니다.

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

저장소 접근을 위한 토큰 발급을 위해 위 명령어를 터미널에 입력하여 AWS CLI를 설치합니다.

aws configure

위 명령어를 입력하여 액세스 키, 시크릿 액세스 키, 리전을 세팅합니다.

aws ecr get-login-password --region ap-northeast-2 

명령어를 입력하여 ECR 리포지토리 URI에 접근하기 위한 토큰을 발급하고 이를 안전한 곳에 저장합니다.

3. 클라우드타입에 접속 주소 및 Access Key 등록

클라우드타입에 로그인 후, 환경설정의 통합 기능 페이지로 접속합니다. 이어 컨테이너 저장소 항목의 컨테이너 저장소 연결하기 버튼을 누릅니다.

레지스트리는 AWS Elastic Container Registry를 선택하고 접속주소에는 이전 단계에서 기록해두었던 ECR URI를, 비밀번호에는 ‘aws ecr get-login-password…’ 명령어로 발행한 토큰 값을 입력하고 연결하기 버튼을 누릅니다.

4. 클라우드타입 API 키 발급

클라우드타입 환경설정의 인증 페이지로 접속합니다. 이어 API 키 항목의 새로운 API 키 생성버튼을 누릅니다.

생성된 API 키 값을 안전한 곳에 보관합니다. 토큰은 생성 당시 최초 1회에 한해 조회할 수 있으며, 팝업창을 닫으면 다시 조회가 불가능합니다.

5. GitHub Actions Workflows 세팅

GitHub Actions와 AWS ECR을 연동하기 위해서는 workflow 명세에서 AWS 계정 정보를 참조할 수 있도록 GitHub 저장소 secret을 등록해야 합니다. Settings-Secrets and variables-Actions 페이지로 접속 후 New repository secret 버튼을 클릭합니다. 등록해야할 secret은 다음과 같습니다.

  • AWS_ACCOUNT_NUMBER: AWS 계정 번호
  • AWS_REGION: AWS 리전
  • AWS_ACCESS_KEY_ID: AWS 액세스 키 ID
  • AWS_SECRET_ACCESS_KEY: AWS 시크릿 액세스 키
  • CLOUDTYPE_TOKEN: 클라우드타입 API 키
name: Create and publish a Docker image to AWS ECR, Deploy to Cloudtype

on:
push:
branches:
- main

env:
REGISTRY: ${{ secrets.AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
IMAGE_NAME: [이미지명]

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Deploy to Cloudtype
uses: cloudtype-github-actions/deploy@v1
with:
token: ${{ secrets.CLOUDTYPE_TOKEN }}
project: [스페이스명]/[프로젝트명]
stage: main
yaml: |
name: [서비스명]
app: container
options:
ports: [포트번호]
image: ${{ steps.meta.outputs.tags }}

배포하고자 하는 GitHub 저장소에 위와 같이 GitHub Actions Workflows 명세를 세팅합니다. 다음의 항목은 환경에 맞게 변경하여 적용해야 합니다.

  • 이미지명
  • 스페이스명
  • 프로젝트명
  • 서비스명
  • 포트번호

workflows 명세를 GitHub 저장소에 커밋하면 GitHub Actions가 실행됩니다. 저장소의 Actions 탭으로 들어가 해당 Jobs가 잘 실행되었는지 확인합니다.

GitHub Actions를 통해 빌드된 이미지가 위와 같이 ECR 리포지토리에 잘 반영된 것을 볼 수 있습니다.

workflows에서 설정한 클라우드타입 스페이스 내 프로젝트에 접속하면 해당 어플리케이션이 정상 배포되었음을 확인할 수 있습니다.

GCP Artifact Registry

GCP Artifact Registry는 Google Cloud Platform에서 제공하는 레지스트리 서비스이며, AWS와 같이 이미지 스캔 및 암호화 등을 지원하며, 90일 동안 사용할 수 있는 300 달러의 크레딧 범위 안에서 자유롭게 사용할 수 있습니다. AWS ECR과 달리 컨테이너 이미지 뿐만 아니라 다양한 언어로 개발된 어플리케이션의 빌드 산출물도 저장할 수 있는 것이 특징입니다.

1. GCP Artifact Registry 저장소 생성

GCP 콘솔에서 Artifact Registry 서비스에 접속한 후 저장소 만들기 버튼을 누릅니다.

형식 항목에서 Docker를 선택하고 리전은 상황에 맞게 희망하는 옵션을 선택합니다. 이번 포스트에서는 asia-northeast3(서울)을 선택하였습니다.

생성된 저장소 페이지에서 표시된 경로 오른쪽 끝 복사 아이콘을 누릅니다. 붙여넣기를 하면 asia-northeast3-docker.pkg.dev/[GCP 프로젝트 ID]/test 와 같은 경로를 확인할 수 있으며, 추후 사용을 위해 안전한 곳에 잘 기록해둡니다.

2. 서비스 계정 생성 및 JSON KEY 발급

GCP 콘솔의 IAM 및 관리자 페이지에 접속한 후 서비스 계정 만들기 버튼을 누릅니다.

식별할 수 있는 서비스 계정 이름을 작성한 후 만들고 계속하기 버튼을 클릭합니다.

역할 선택 창에서 Artifact Registry 관리자 항목을 선택합니다. 이어 완료 버튼을 누릅니다.

생성된 서비스 계정의 작업 중 키 관리를 선택합니다.

키 추가-새 키 만들기를 클릭합니다.

키 유형에서 JSON을 선택하고 만들기 버튼을 누릅니다. 이후 자동으로 JSON 키가 파일 형태로 다운로드 됩니다. 공유 드라이브나 공개된 장소에 업로드 되지 않도록 각별히 유의합니다.

3. 클라우드타입에 접속 주소 및 Access Key 등록

클라우드타입에 로그인 후, 환경설정의 통합 기능 페이지로 접속합니다. 이어 컨테이너 저장소 항목의 컨테이너 저장소 연결하기 버튼을 누릅니다.

레지스트리는 Google Cloud Artifact Registry를 선택하고 접속주소에는 이전 단계에서 기록해두었던 Artifact Registry 주소를, 키 파일에는 다운로드된 GCP 서비스 계정 JSON 키 값을 입력하고 연결하기 버튼을 누릅니다.

4. 클라우드타입 API 키 발급

클라우드타입 환경설정의 인증 페이지로 접속합니다. 이어 API 키 항목의 새로운 API 키 생성버튼을 누릅니다.

생성된 API 키 값을 안전한 곳에 보관합니다. 토큰은 생성 당시 최초 1회에 한해 조회할 수 있으며, 팝업창을 닫으면 다시 조회가 불가능합니다.

5. GitHub Actions Workflows 세팅

GitHub Actions와 GCP Artifact Registry를 연동하기 위해서는 workflow 명세에서 GCP 계정 정보를 참조할 수 있도록 GitHub 저장소 secret을 등록해야 합니다. Settings-Secrets and variables-Actions 페이지로 접속 후 New repository secret 버튼을 클릭합니다. 등록해야할 secret은 다음과 같습니다.

  • GCP_LOCATION: GCP 리전
  • GCP_PROJECT_ID: GCP 프로젝트 ID
  • GAR_REPOSITORY: Artifact Registry 저장소명
  • GAR_JSON_KEY: Artifact Registry 서비스 계정 JSON KEY
  • CLOUDTYPE_TOKEN: 클라우드타입 API 키
name: Create and publish a Docker image to GCP Artifact Registry, Deploy to Cloudtype

on:
push:
branches:
- main

env:
REGISTRY: ${{ secrets.GCP_LOCATION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.GAR_REPOSITORY }}
IMAGE_NAME: [이미지명]

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log in to the Container registry
uses: docker/login-action@v2
with:
registry: ${{ secrets.GCP_LOCATION }}-docker.pkg.dev
username: _json_key
password: ${{ secrets.GAR_JSON_KEY }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Deploy to Cloudtype
uses: cloudtype-github-actions/deploy@v1
with:
token: ${{ secrets.CLOUDTYPE_TOKEN }}
project: [스페이스명]/[프로젝트명]
stage: main
yaml: |
name: [서비스명]
app: container
options:
ports: [포트번호]
image: ${{ steps.meta.outputs.tags }}

배포하고자 하는 GitHub 저장소에 위와 같이 GitHub Actions Workflows 명세를 세팅합니다. 다음의 항목은 환경에 맞게 변경하여 적용해야 합니다.

  • 이미지명
  • 스페이스명
  • 프로젝트명
  • 서비스명
  • 포트번호

workflows 명세를 GitHub 저장소에 커밋하면 GitHub Actions가 실행됩니다. 저장소의 Actions 탭으로 들어가 해당 Jobs가 잘 실행되었는지 확인합니다.

GitHub Actions를 통해 빌드된 이미지가 위와 같이 Artifact Repository 저장소에 잘 반영된 것을 볼 수 있습니다.

workflows에서 설정한 클라우드타입 스페이스 내 프로젝트에 접속하면 해당 어플리케이션이 정상 배포되었음을 확인할 수 있습니다.

--

--