Docker 컨테이너 액션 만들기

Docker 컨테이너 액션 만들기

이 튜토리얼에서는 Docker 컨테이너 액션을 직접 만드는 방법을 알려드릴게요. 패키징된 Docker 컨테이너 액션을 만들고 사용하는 데 필요한 기본 구성 요소를 배울 수 있어요.

출처: 문서

본문

Introduction

이 가이드에서는 패키징된 Docker 컨테이너 액션을 만들고 사용하는 데 필요한 기본 구성 요소를 배우게 돼요. 이 가이드는 액션을 패키징하는 데 필요한 구성 요소에 초점을 맞추기 때문에 액션 코드의 기능은 최소한으로 유지해요. 이 액션은 로그에 "Hello World"를 출력하거나 사용자 지정 이름을 제공하면 "Hello [who-to-greet]"을 출력해요.

이 프로젝트를 완료하면 Docker 컨테이너 액션을 직접 만들고 워크플로우에서 테스트하는 방법을 이해할 수 있게 돼요.

자체 호스팅 러너는 Docker 컨테이너 액션을 실행하려면 Linux 운영 체제를 사용해야 하고 Docker가 설치되어 있어야 해요. 자체 호스팅 러너 요구사항에 대한 자세한 내용은 Self-hosted runners reference 문서를 참고하세요.

[!WARNING] 워크플로우와 액션을 만들 때는 항상 코드가 잠재적인 공격자의 신뢰할 수 없는 입력을 실행할 수 있는지 고려해야 해요. 특정 컨텍스트는 신뢰할 수 없는 입력으로 취급해야 해요. 공격자가 자신의 악성 콘텐츠를 삽입할 수 있기 때문이에요. 자세한 내용은 Secure use reference 문서를 참고하세요.

Prerequisites

Creating a Dockerfile

hello-world-docker-action 디렉터리에 새 Dockerfile 파일을 만드세요. 문제가 있다면 파일 이름이 올바르게 대문자로 시작하는지 확인하세요(대문자 D를 사용하되 대문자 f는 사용하지 마세요). 자세한 내용은 Dockerfile support for GitHub Actions 문서를 참고하세요.

Dockerfile

# Container image that runs your code
FROM alpine:3.10

# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh

# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]

Creating an action metadata file

위에서 만든 hello-world-docker-action 디렉터리에 새 action.yml 파일을 만드세요. 자세한 내용은 Metadata syntax reference 문서를 참고하세요.

action.yml

# action.yml
name: 'Hello World'
description: 'Greet someone and record the time'
inputs:
  who-to-greet:  # id of input
    description: 'Who to greet'
    required: true
    default: 'World'
outputs:
  time: # id of output
    description: 'The time we greeted you'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.who-to-greet }}

이 메타데이터는 하나의 who-to-greet 입력과 하나의 time 출력 매개변수를 정의해요. 입력을 Docker 컨테이너에 전달하려면 inputs를 사용해서 입력을 선언하고 args 키워드에서 입력을 전달해야 해요. args에 포함하는 모든 것은 컨테이너에 전달되지만, 액션 사용자에게 더 나은 검색 가능성을 위해 입력을 사용하는 것이 좋아요.

GitHub는 Dockerfile에서 이미지를 빌드하고, 이 이미지를 사용해서 새 컨테이너에서 명령을 실행해요.

Writing the action code

기본 Docker 이미지와, 따라서 액션의 언어를 자유롭게 선택할 수 있어요. 다음 셸 스크립트 예시는 who-to-greet 입력 변수를 사용해서 로그 파일에 "Hello [who-to-greet]"을 출력해요.

다음으로 스크립트는 현재 시간을 가져와서 job의 이후 단계에서 실행되는 액션이 사용할 수 있는 출력 변수로 설정해요. GitHub가 출력 변수를 인식하려면 이를 $GITHUB_OUTPUT 환경 파일에 기록해야 해요: echo "<output name>=<value>" >> $GITHUB_OUTPUT. 자세한 내용은 Workflow commands for GitHub Actions 문서를 참고하세요.

  1. hello-world-docker-action 디렉터리에 새 entrypoint.sh 파일을 만드세요.

  2. entrypoint.sh 파일에 다음 코드를 추가하세요.

    entrypoint.sh

    #!/bin/sh -l
    
    echo "Hello $1"
    time=$(date)
    echo "time=$time" >> $GITHUB_OUTPUT
    
    

    entrypoint.sh가 오류 없이 실행되면 액션 상태는 success로 설정돼요. 액션의 코드에서 종료 코드를 명시적으로 설정해서 액션의 상태를 제공할 수도 있어요. 자세한 내용은 Setting exit codes for actions 문서를 참고하세요.

  3. entrypoint.sh 파일을 실행 가능하게 만드세요. Git은 복제/포크할 때마다 리셋되지 않도록 파일의 권한 모드를 명시적으로 변경하는 방법을 제공해요.

    git add entrypoint.sh
    git update-index --chmod=+x entrypoint.sh
    
  4. 선택적으로, git 인덱스에서 파일의 권한 모드를 확인하려면 다음 명령을 실행하세요.

    git ls-files --stage entrypoint.sh
    

    100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 entrypoint.sh 같은 출력은 파일에 실행 권한이 있다는 것을 의미해요. 이 예시에서 755는 실행 권한을 나타내요.

Creating a README

사람들이 액션을 사용하는 방법을 알 수 있도록 README 파일을 만들 수 있어요. README는 액션을 공개적으로 공유할 계획이 있을 때 가장 유용하지만, 여러분이나 팀에게 액션 사용 방법을 상기시켜 주는 훌륭한 방법이기도 해요.

hello-world-docker-action 디렉터리에 다음 정보를 명시하는 README.md 파일을 만드세요.

  • 액션이 수행하는 작업에 대한 상세 설명.
  • 필수 입력 및 출력 인수.
  • 선택적 입력 및 출력 인수.
  • 액션이 사용하는 secret.
  • 액션이 사용하는 환경 변수.
  • 워크플로우에서 액션을 사용하는 예시.

README.md

# Hello world docker action

This action prints "Hello World" or "Hello" + the name of a person to greet to the log.

## Inputs

## `who-to-greet`

**Required** The name of the person to greet. Default `"World"`.

## Outputs

## `time`

The time we greeted you.

## Example usage

uses: actions/hello-world-docker-action@v2
with:
  who-to-greet: 'Mona the Octocat'

Commit, tag, and push your action

터미널에서 action.yml, entrypoint.sh, Dockerfile, README.md 파일을 커밋하세요.

액션 릴리스에 버전 태그를 추가하는 것도 모범 사례예요. 액션 버전 관리에 대한 자세한 내용은 Managing custom actions 문서를 참고하세요.

git add action.yml entrypoint.sh Dockerfile README.md
git commit -m "My first action is ready"
git tag -a -m "My first action release" v1
git push --follow-tags

Testing out your action in a workflow

이제 워크플로우에서 액션을 테스트할 준비가 됐어요.

  • 액션이 비공개 저장소에 있을 때는 누가 접근할 수 있는지 제어할 수 있어요. 자세한 내용은 Managing GitHub Actions settings for a repository 문서를 참고하세요.
  • 액션이 내부 저장소에 있을 때는 같은 저장소의 워크플로우에서만 사용할 수 있어요.
  • 공개 액션은 어떤 저장소의 워크플로우에서든 사용할 수 있어요.

Example using a public action

다음 워크플로우 코드는 공개 actions/hello-world-docker-action 저장소의 완성된 hello world 액션을 사용해요. 다음 워크플로우 예시 코드를 .github/workflows/main.yml 파일에 복사하되, actions/hello-world-docker-action을 여러분의 저장소와 액션 이름으로 바꾸세요. who-to-greet 입력도 자신의 이름으로 바꿀 수 있어요. 공개 액션은 GitHub Marketplace에 게시되지 않았더라도 사용할 수 있어요. 자세한 내용은 Publishing actions in GitHub Marketplace 문서를 참고하세요.

.github/workflows/main.yml

on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      - name: Hello world action step
        id: hello
        uses: actions/hello-world-docker-action@v2
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"

Example using a private action

다음 예시 워크플로우 코드를 액션 저장소의 .github/workflows/main.yml 파일에 복사하세요. who-to-greet 입력도 자신의 이름으로 바꿀 수 있어요. 이 비공개 액션은 GitHub Marketplace에 게시할 수 없고 이 저장소에서만 사용할 수 있어요.

.github/workflows/main.yml

on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      # To use this repository's private action,
      # you must check out the repository
      - name: Checkout
        uses: actions/checkout@v6
      - name: Hello world action step
        uses: ./ # Uses an action in the root directory
        id: hello
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"

저장소에서 Actions 탭을 클릭하고 가장 최근 워크플로우 실행을 선택하세요. Jobs 아래 또는 시각화 그래프에서 A job to say hello를 클릭하세요.

Hello world action step을 클릭하면 로그에 "Hello Mona the Octocat" 또는 who-to-greet 입력에 사용한 이름이 출력되는 것을 볼 수 있어요. 타임스탬프를 보려면 Get the output time을 클릭하세요.

Accessing files created by a container action

컨테이너 액션이 실행되면 러너의 기본 작업 디렉터리(GITHUB_WORKSPACE)를 컨테이너의 /github/workspace 디렉터리에 자동으로 매핑해요. 컨테이너의 이 디렉터리에 추가된 모든 파일은 같은 job의 후속 단계에서 사용할 수 있어요. 예를 들어 프로젝트를 빌드하는 컨테이너 액션이 있고 빌드 출력을 아티팩트로 업로드하려면 다음 단계를 사용할 수 있어요.

workflow.yml

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      # Output build artifacts to /github/workspace on the container.
      - name: Containerized Build
        uses: ./.github/actions/my-container-action

      - name: Upload Build Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: workspace_artifacts
          path: ${{ github.workspace }}

빌드 출력을 아티팩트로 업로드하는 방법에 대한 자세한 내용은 Store and share data with workflow artifacts 문서를 참고하세요.

Example Docker container actions on GitHub.com

GitHub.com에서 Docker 컨테이너 액션의 많은 예시를 찾을 수 있어요.

더 알아보기 (Learn more)