GitHub Actions와 Docker 소개

GitHub Actions와 Docker 소개

GitHub Actions로 이미지 빌드와 푸시를 자동화하는 방법을 배워볼게요.

출처: 문서

본문

이 가이드는 Docker와 GitHub Actions를 사용해 CI 파이프라인을 구축하는 방법을 소개해요. Docker의 공식 GitHub Actions를 사용해 어플리케이션을 Docker 이미지로 빌드하고 Docker Hub에 푸시하는 방법을 배우게 돼요. 가이드가 끝나면 Docker 빌드용으로 작동하는 간단한 GitHub Actions 구성을 갖게 돼요. 그대로 사용하거나 필요에 맞게 확장할 수 있어요.

사전 요구사항

가이드를 따라 하려면 다음이 필요해요:

  • 확인된 Docker 계정.
  • Dockerfile에 대한 익숙함.

이 가이드는 Docker 개념의 기본 지식을 가정하지만 GitHub Actions 워크플로에서 Docker를 사용하는 방법에 대한 설명은 제공해요.

샘플 앱 가져오기

이 가이드는 프로젝트에 구애받지 않으며 Dockerfile이 있는 어플리케이션이 있다고 가정해요.

함께 따라 할 샘플 프로젝트가 필요하다면 이 샘플 어플리케이션 을 사용할 수 있어요. 이 샘플은 앱의 컨테이너화된 버전을 빌드하기 위한 Dockerfile을 포함해요. 또는 내 GitHub 프로젝트를 사용하거나 템플릿에서 새 리포지토리를 만들 수 있어요.

# syntax=docker/dockerfile:1
# builder installs dependencies and builds the node app
FROM node:lts-alpine AS builder
WORKDIR /src
RUN --mount=src=package.json,target=package.json \
  --mount=src=package-lock.json,target=package-lock.json \
  --mount=type=cache,target=/root/.npm \
  npm ci
COPY . .
RUN --mount=type=cache,target=/root/.npm \
  npm run build
# release creates the runtime image
FROM node:lts-alpine AS release
WORKDIR /app
COPY --from=builder /src/build .
EXPOSE 3000
CMD ["node", "."]

GitHub 리포지토리 구성하기

이 가이드의 워크플로는 빌드한 이미지를 Docker Hub에 푸시해요. 그러려면 GitHub Actions 워크플로의 일부로 Docker 자격 증명(사용자 이름과 액세스 토큰)으로 인증해야 해요.

Docker 액세스 토큰을 만드는 방법은 액세스 토큰 생성 및 관리 를 참고하세요.

Docker 자격 증명이 준비되면 GitHub Actions에서 사용할 수 있도록 GitHub 리포지토리에 추가해주세요:

  1. 리포지토리의 Settings 를 엽니다.
  2. Security 아래에서 Secrets and variables > Actions 로 이동합니다.
  3. Secrets 아래에서 Docker 액세스 토큰을 담는 DOCKER_PASSWORD 라는 새 리포지토리 시크릿을 만듭니다.
  4. 다음으로 Variables 아래에서 Docker Hub 사용자 이름을 담는 DOCKER_USERNAME 리포지토리 변수를 만듭니다.

GitHub Actions 워크플로 설정하기

GitHub Actions 워크플로는 커밋이나 풀 리퀘스트 같은 트리거에 응답해 Docker 이미지 빌드·푸시 같은 작업을 자동화하는 일련의 단계를 정의해요. 이 가이드에서 워크플로는 Docker 빌드와 테스트 자동화에 초점을 맞춰, 게시하기 전에 컨테이너화된 어플리케이션이 올바르게 작동하는지 보장해요.

리포지토리의 .github/workflows/ 디렉터리에 docker-ci.yml 이라는 파일을 만들어주세요. 기본 워크플로 구성으로 시작해주세요:

name: Build and Push Docker Image
on:
  push:
    branches:
      - main
  pull_request:

이 구성은 main 브랜치로의 푸시와 풀 리퀘스트에서 워크플로를 실행해요. 두 트리거를 모두 포함하면 병합 전에 풀 리퀘스트에서 이미지가 올바르게 빌드되는지 보장할 수 있어요.

태그와 어노테이션용 메타데이터 추출

워크플로의 첫 단계에서는 docker/metadata-action 을 사용해 이미지용 메타데이터를 생성해주세요. 이 액션은 브랜치 이름과 커밋 SHA 같은 깃 리포지토리 정보를 추출하고 태그와 어노테이션 같은 이미지 메타데이터를 생성해요.

워크플로 파일에 다음 YAML을 추가해주세요:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
      - name: Extract Docker image metadata
        id: meta
        uses: docker/metadata-action@v6
        with:
          images: ${{ vars.DOCKER_USERNAME }}/my-image

이 단계들은 빌드 및 푸시 과정에서 이미지에 태그를 달고 어노테이션을 붙일 메타데이터를 준비해요.

  • Checkout 단계는 Git 리포지토리를 클론해요.
  • Extract Docker image metadata 단계는 Git 메타데이터를 추출하고 Docker 빌드용 이미지 태그와 어노테이션을 생성해요.

레지스트리에 인증하기

이미지를 빌드하기 전에 레지스트리에 인증해 빌드한 이미지를 레지스트리에 푸시할 수 있는지 보장해주세요.

Docker Hub에 인증하려면 워크플로에 다음 단계를 추가해주세요:

      - name: Log in to Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ vars.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

이 단계는 리포지토리 설정 에서 구성한 Docker 자격 증명을 사용해요.

이미지 빌드 및 푸시

마지막으로 최종 프로덕션 이미지를 빌드하고 레지스트리에 푸시해주세요. 다음 구성은 이미지를 빌드하고 레지스트리에 직접 푸시해요.

      - name: Build and push Docker image
        uses: docker/build-push-action@v7
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}

이 구성에서:

  • push: ${{ github.event_name != 'pull_request' }} 은 이벤트가 풀 리퀘스트가 아닐 때만 이미지가 푸시되게 보장해요. 이렇게 하면 워크플로가 풀 리퀘스트용 이미지를 빌드·테스트하지만 main 브랜치로의 커밋에 대해서만 이미지를 푸시해요.
  • tags 와 annotations 는 메타데이터 액션의 출력을 사용해 일관된 태그와 어노테이션 을 이미지에 자동으로 적용해요.

증명(Attestations)

SBOM(Software Bill of Materials)과 provenance 증명은 보안과 추적성을 향상시켜 이미지가 현대 소프트웨어 공급망 요구사항을 충족하게 보장해요.

약간의 추가 구성으로 docker/build-push-action 이 빌드 시점에 이미지용 SBOM과 provenance 증명을 생성하도록 구성할 수 있어요.

이 추가 메타데이터를 생성하려면 워크플로를 두 가지 변경해야 해요:

  1. 빌드 단계 전에 docker/setup-buildx-action 을 사용하는 단계를 추가해주세요. 이 액션은 기본 클라이언트가 지원하지 않는 추가 기능으로 내 Docker 빌드 클라이언트를 구성해요.
  2. 그런 다음 Build and push Docker image 단계를 업데이트해 SBOM과 provenance 증명도 활성화해주세요.

다음은 업데이트된 스니펫이에요:

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4
      - name: Build and push Docker image
        uses: docker/build-push-action@v7
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}
          provenance: true
          sbom: true

증명에 대한 자세한 내용은 문서 를 참고하세요.

결론

이전 섹션에서 설명한 모든 단계를 포함한 전체 워크플로 구성:

name: Build and Push Docker Image
on:
  push:
    branches:
      - main
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
      - name: Extract Docker image metadata
        id: meta
        uses: docker/metadata-action@v6
        with:
          images: ${{ vars.DOCKER_USERNAME }}/my-image
      - name: Log in to Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ vars.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4
      - name: Build and push Docker image
        uses: docker/build-push-action@v7
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          annotations: ${{ steps.meta.outputs.annotations }}
          provenance: true
          sbom: true

이 워크플로는 GitHub Actions로 Docker 이미지를 빌드·푸시하는 모범 사례를 구현해요. 이 구성은 그대로 사용하거나 멀티 플랫폼 같은 프로젝트 요구사항에 따라 추가 기능으로 확장할 수 있어요.

추가 자료

  • Docker Build GitHub Actions 섹션 에서 고급 구성과 예제를 자세히 알아보세요.
  • 더 복잡한 빌드 설정에는 Bake 를 고려할 수 있어요. (Mastering Buildx Bake 가이드 도 참고하세요.)
  • 더 빠르고 멀티 플랫폼 빌드를 위해 설계된 Docker의 관리형 빌드 서비스에 대해 알아보려면 Docker Build Cloud 를 참고하세요.

더 알아보기 (Learn more)

  • GitHub Actions
  • Docker Build GitHub Actions
  • Docker Build Cloud