아티팩트 빌드

GitBeginner
지금 연습하기

소개

이전 실습에서는 "품질 관리"(CI) 에 대해 배웠습니다. 이제 다음 단계인 패키징으로 넘어갑니다.

소프트웨어를 공장에서 생산하는 제품이라고 생각해 보겠습니다. 모든 품질 검사를 통과한 제품은 고객에게 배송하기 전에 상자에 넣고, 밀봉하고, 라벨을 붙여야 합니다. 소프트웨어 세계에서 이 "상자" 역할을 하는 것이 바로 Docker 컨테이너입니다.

이렇게 패키징된 결과물을 아티팩트라고 합니다. 빌드가 완료된 아티팩트는 레지스트리에 저장해야 이후 배포 단계에서 동일한 빌드 결과물을 가져올 수 있습니다.

이러한 재현성이 핵심입니다. 배포할 때는 대상 시스템마다 코드를 다르게 다시 빌드하는 대신, 이미 확인된 빌드 결과물을 사용해야 합니다.

GitHub 는 GitHub Container Registry(GHCR) 라는 레지스트리를 제공합니다.

이 실습에서는 로봇 도우미가 다음 작업을 수행하도록 설정합니다.

  • 애플리케이션을 Docker 컨테이너로 패키징합니다.
  • 버전 태그로 라벨을 지정합니다.
  • GitHub 저장소에 자동으로 전송(푸시) 합니다.

사전 요구 사항

계속해서 github-actions-basics 저장소를 사용합니다.

Dockerfile 만들기

로봇이 애플리케이션을 패키징하려면 먼저 지침이 필요합니다. Docker 에서는 이 지침을 Dockerfile이라는 특수한 파일에 작성합니다.

프로젝트 디렉터리로 이동합니다.

cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics

참고: your-username을 실제 GitHub 사용자 이름으로 바꾸세요.

다음 내용으로 Dockerfile이라는 파일을 만듭니다. 파일 이름의 첫 글자는 대문자 D이고 확장자는 없습니다.

cat > Dockerfile << EOF
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
EOF

이 패키징 지침은 로봇에게 다음 작업을 수행하도록 지시합니다.

  • FROM node:16-alpine: Node.js 가 이미 설치된 경량 기본 시스템에서 시작합니다.
  • WORKDIR /app: 컨테이너 안에 작업 디렉터리를 만듭니다.
  • COPY ...: 프로젝트 파일을 컨테이너 안으로 복사합니다.
  • RUN npm install: 컨테이너 안에 필요한 종속 항목을 설치합니다.
  • CMD ...: 누군가 이 컨테이너를 실행하면 애플리케이션을 시작합니다.

이제 파일을 저장소에 추가하고 GitHub 에 푸시합니다.

git add Dockerfile
git commit -m "Add Dockerfile"
git push

게시 워크플로 만들기

이제 패키징과 전송을 처리할 새 워크플로를 만듭니다. 워크플로 이름은 docker-publish.yml로 지정합니다.

파일을 만듭니다.

touch .github/workflows/docker-publish.yml

nano로 파일을 엽니다.

nano .github/workflows/docker-publish.yml

다음 설정을 추가합니다. 여기서는 permissions라는 새로운 개념을 사용합니다.

name: Docker Publish

on:
  push:
    branches: ["master", "main"]

permissions:
  contents: read
  packages: write

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

권한이 필요한 이유

보안을 위해 로봇은 기본적으로 제한된 접근 권한만 가집니다. 로봇이 GitHub 계정의 "packages" 영역에 항목을 업로드하도록 하려면 레지스트리에 접근할 수 있는 키를 명시적으로 제공해야 합니다. packages: write가 바로 그 역할을 합니다.

이는 파이프라인 설계에서 최소 권한 원칙을 보여 주는 좋은 예입니다. 워크플로에는 수행할 작업에 필요한 권한만 부여해야 합니다.

nano에서 저장하고 종료합니다 (Ctrl+X, Y, Enter).

빌드 및 푸시 단계 추가하기

이제 가장 중요한 부분인 실제 빌드와 푸시를 확인합니다.

Docker 에서 제공하는 공식 도구 (action) 두 가지를 사용합니다.

  1. docker/login-action: 레지스트리에 로그인합니다.
  2. docker/build-push-action: 컨테이너를 빌드하고 전송합니다.

이 단계는 CI 와 전달 과정을 연결합니다. 테스트가 통과하면 파이프라인이 버전이 지정된 아티팩트를 만들고, 다른 시스템은 소스에서 다시 빌드하지 않고 나중에 이 아티팩트를 배포할 수 있습니다.

.github/workflows/docker-publish.yml을 다시 엽니다.

nano .github/workflows/docker-publish.yml

build-and-push 작업에 다음 단계를 추가합니다.

- name: Log in to the Container registry
  uses: docker/login-action@v2
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
  uses: docker/build-push-action@v4
  with:
    context: .
    push: true
    tags: ghcr.io/${{ github.repository }}/app:latest

특수 변수 이해하기

  • ghcr.io: GitHub "레지스트리"의 주소입니다.
  • ${{ github.actor }}: GitHub 사용자 이름을 자동으로 입력하는 변수입니다.
  • ${{ secrets.GITHUB_TOKEN }}: GitHub 가 로봇을 위해 생성하는 특별한 임시 비밀번호입니다. 별도로 할 일 없이 자동으로 작동합니다. 이 토큰을 사용하면 비밀번호를 직접 입력하지 않고도 로봇이 안전하게 로그인할 수 있습니다.
  • tags: 컨테이너에 붙일 라벨을 만듭니다. 형식은 레지스트리 주소 / 사용자 이름 / 저장소 이름 / 애플리케이션 이름 : 버전입니다.

nano에서 저장하고 종료합니다.

이제 이 워크플로를 GitHub 에 푸시하여 프로세스를 시작합니다.

git add .
git commit -m "Add Docker publishing workflow"
git push

아티팩트 확인하기

이제 로봇이 작업을 시작합니다. 서버를 설정하고, 로그인하고, 컨테이너를 빌드한 다음 업로드합니다.

  1. GitHub 에서 저장소로 이동합니다.
  2. Actions 탭을 클릭합니다.
  3. "Docker Publish" 워크플로 실행을 클릭합니다.
  4. 각 단계가 녹색으로 바뀌는지 확인합니다.

Docker Publish

"Build and push Docker image" 단계가 성공적으로 완료되면 패키지가 레지스트리에 저장된 것입니다. 이제 패키지를 확인합니다.

  1. 저장소의 기본 페이지 (Code 탭) 로 이동합니다.
  2. 오른쪽 사이드바를 확인합니다. Packages 섹션이 표시되어야 합니다.
  3. 해당 섹션에 새 패키지가 표시됩니다.

패키지 이름을 클릭하면 세부 정보를 확인할 수 있습니다. 이것이 완성된 아티팩트입니다. 저장소에 접근할 수 있는 사용자 또는 저장소가 공개된 경우 모든 사용자가 이 이미지를 사용해 애플리케이션을 다운로드하고 실행할 수 있습니다.

GitHub Packages

요약

이 실습에서는 완전한 전달 파이프라인을 구축했습니다.

다음 내용을 배웠습니다.

  • 패키징: Dockerfile을 작성해 애플리케이션을 컨테이너에 넣는 방법
  • 권한: 워크플로에 패키지 쓰기 권한을 부여하는 방법
  • 레지스트리 저장: GitHub Container Registry(GHCR) 를 사용해 이미지를 저장하는 방법
  • 자동화: 표준 action 을 사용해 코드를 자동으로 빌드하고 전송하는 방법

이제 로봇 도우미가 코드 확인 (CI) 과 코드 전송 (아티팩트) 을 수행할 수 있습니다. 다음 실습에서는 비밀번호와 같은 민감한 정보를 안전하게 처리하는 방법을 살펴봅니다.