Application Repository 에 새로운 push 가 발생하면 작성한 Dockerfile 을 이용해 새로운 Image 를 build 하고 Github image Registry 에 생성한 image 를 올린다.
생성한 image 를 github organization 혹은 personal account 내에 저장시켜, repository 에서 image 에 접근할 수 있도록 한다.
Image 를 생성한 후 저장,공유하고 생성될 경우 접근할 수 있는 곳이 필요하다. local 에서 image 를 생성한 후 image registry 에 push 하고, 그것을 k8s
환경에서 registry 를 통해 받아올 수 있다. 따라서 image registry 는 CI/CD
workflow 에서 중요한 역할을 한다.
repository 의 접근 허용 범위를 그대로 따르게 할수도 있고, 독립적으로 container registry 에 대한 접근을 설정할 수 있다.
Docker
image 또는 OCI
image 를 저장할 수 있고, 저장공간의 namespace
는 https://ghcr.io
이다.
public image 에 대해서 무료이고, beta 기간동안 private image 또한 무료이다.
workflow 에서 Container registry 에 접근해 image 를 build & push 하기 위해
GITHUB_TOKEN
을 사용한다.
GITHUB_TOKEN
은 packages 를 read/write
하는 권한을 가진다.Personal Access Token
을 생성해 image registry 에 인증하기 위해 사용한다면 read:packages
, write packages
, delete:pacakges
권한을 설정해 등록한다.GITHUB_TOKEN
을 생성한다. 이 GITHUB_TOKEN
을 사용해 workflow 내부에서 인증 시 사용할 수 있다.GITHUB_TOKEN
이 가진 권한 외에 다른 권한이 필요할 경우 자신의 Personal access Token
을 생성한 후 , 해당 workflow 가 존재하는 repository 에 Repository Secret
으로 등록해 ${{secrets.SECRET_NAME}}
으로 불러와 사용할 수 있다.새로운 push 발생시 , image build 후 registry로 push 한다.
name: Create and publish a Docker image
on:
push:
branches: ['release'] # release branch 로 push 발생할 경우
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Docker login-action
, metadata-action
그리고 build-push-action
를 사용해서 Docker 이미지를 build 하고 build 성공 시 Github Packages
로 생성된 이미지를 push 한다.
checkout
: CI 서버에서 branch 를 checkout 해 repository 의 code 를 받아오고 workflow 내의 동작을 시작할 수 있도록 한다.
login-action
: Github Image registry 에 인증해 로그인한다.
ghcr.io
${{ github.actor }}
workflow 가 run 하도록 trigger 한 사용자의 username 을 자동으로 사용할 수 있다.GITHUB_TOKEN
또는 알맞은 권한을 가진 personal access token
을 사용할 수 있다.metadata-action
: image 를 build 하기 위한 tag
, label
의 정보를 추출한다.
build-push-action
: 추출한 tag
, label
을 달아 Dockerfile
를 사용해 image 를 build 하고 registry 로 push 한다.
true
로 설정할 경우 image가 성공적으로 build 될 경우 registry로 push 된다.metadata-action
의 결과물unique 한 tag 를 생성한 image 에 달아, 이미지 배포 후 오류가 발생했을시 , 기존에 잘 동작하는 image 를 tag 로 찾아 다시 되돌리는데 용이하다.
contexts information 에서 unique 한 값을 사용해서 tag 를 생성할 수 있다.
github.run_number
: 특정 workflow 실행 시 고유 숫자로 1부터 시작해 새 실행마다 1씩 증가한다. 워크플로우 run 한 결과를 다시 re-run 할 경우 숫자는 변경되지 않는다.
github.run_id
: 레포지토리 내에서 실행되는 각workflow의 고유한 숫자이다. 워크플로의 run 을 re-run 하는 경우 변경되지 않는다.
github.run_attempt
: 특정한 workflow가 run 한 횟수 1부터 시작한다.
=> github.run_attempt
로 고유한 값 생성 가능
앞선 예제와 같이 workflow 를 생성한다면, 해당 값을 metadata-action
의 tag type=raw
의 value 값으로 적어 사용할 수 있다.
이전의 commit 순서를 기억하는 Hash 값을 사용해, 온/오프라인 상태에 상관없이 바로 commit 할 수 있기 때문에 Git 은 commit id 로 hash 값을 사용한다.
commit id 를 추출해 tag 로 붙인다면, 어떤 commit 에서 생성되었던 이미지인지 추적하기도 용이하다.
metadata-action
의 tag option
사용 : type=sha
를 사용한다.workflow test 를 편하게 하기 위해 새로운 push 가 발생하지 않더라도, workflow 를 실행시킬 수 있는 수동 버튼을 생성한다.
수동으로 workflow 를 trigger 하기 위해 workflow_dispatch
event 를 사용한다.
on:
workflow_dispatch:
name: Create and publish a Docker image
on:
push: # PUSH & PR merge 될 경우
branches: ["main"] # juya branch 로 push 발생할 경우
# workflow trigger button
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# 가장 최신 image 에 latest tag 달기
# flavor: |
# latest=true
# Git short commit, use git version tag
tags: |
type=sha
- name: Build and push Docker image
id: build
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
file: Dockerfile # repository 기준 도커파일 위치
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}