728x90
반응형
1. 액세스 토큰 생성
Personal Access Tokens (Classic) (github.com) 에서 패키지에 대한 권한을 가진 토큰을 생성한다.
생성되는 토큰 값을 저장한 뒤 원하는 곳에 txt 파일로 만들어두고, 아래 명령어 중 하나로 로그인 가능하다.
$ docker login https://ghcr.io -u outsideris // 입력 후 패스워드 토큰값 입력
$ cat TOKEN.txt | docker login https://ghcr.io -u outsideris --password-stdin
2. self_host runner를 만들고 등록해준다.
About self-hosted runners - GitHub Docs
3. workflow를 만들어준다.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
name: Workflow
permissions:
contents: read
packages: write
checks: write
# 어떤 이벤트가 발생하면 workflow 실행할 지 명시
on:
# main 브랜치에 pull_request 발생 시
pull_request:
branches:
- main
# 위 이벤트 발생 시 실행될 작업들
jobs:
# 빌드 후 Container Registry에 image 등록
push_to_registry:
# VM의실행 환경 지정 => self-hosted
runs-on: self-hosted
# 실행될 jobs 순서 대로 명시
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Postgres Start
env:
ENV_FILE: ${{ secrets.ENV_FILE }}
run: echo "$ENV_FILE" > ./.env &&
docker image prune &&
docker rm -f $(docker ps -qa) &&
docker compose up db -d
# JDK 17 설치
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Gradle Build를 위한 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
# Gradle Build
- name: Build with Gradle
run: ./gradlew clean build
# 테스트 결과를 PR에 코멘트로 달아줌
- name: Publish test result
uses: EnricoMi/publish-unit-test-result-action@v2.15.1
if: always()
with:
files: '**/build/test-results/test/*.xml'
# 테스트 실패 시 해당 코드 라인에 코멘트 달아줌.
- name: When test fail, a comment is registered in the error code line.
uses: mikepenz/action-junit-report@v4.1.0
if: always()
with:
report_paths: '**/build/test-results/test/*.xml'
# GitHub Container Registry 로그인
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ secrets.GHUB_USERNAME }}
password: ${{ secrets.GHUB_TOKEN }}
# Docker image 빌드 및 push
- name: Server Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./server/Dockerfile.prod
push: true
tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/server:${{ secrets.RELEASE_VERSION }}
- name: Client Build and push
uses: docker/build-push-action@v5
with:
context: ./client
file: ./client/Dockerfile.prod
push: true
tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/client:${{ secrets.RELEASE_VERSION }}
- name: Nginx Build and push
uses: docker/build-push-action@v5
with:
context: ./docker/nginx
push: true
build-args: BUILD_ENV=prod
tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/nginx:${{ secrets.RELEASE_VERSION }}
- name: DB Build and push
uses: docker/build-push-action@v5
with:
context: ./docker/postgres
push: true
tags: ghcr.io/${{ secrets.GHUB_USERNAME }}/db:${{ secrets.RELEASE_VERSION }}
# 서버에 배포
deploy_via_ssh:
needs: push_to_registry
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v4
# Env 추가
- name: Add Env
env:
ENV_FILE: ${{ secrets.ENV_FILE }}
GHUB_USERNAME: ${{ secrets.GHUB_USERNAME }}
RELEASE_VERSION: ${{ secrets.RELEASE_VERSION }}
run: echo "$ENV_FILE" > ./.env &&
echo -e "GHUB_USERNAME=$GHUB_USERNAME \nRELEASE_VERSION=$RELEASE_VERSION" >> ./.env
# .env, docker-compose.prod.yml 파일 scp로 서버에 전송
- name: copy files to target server via scp
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USERNAME }}
key: ${{ secrets.DEPLOY_KEY }}
port: ${{ secrets.DEPLOY_PORT }}
source: ./docker-compose.prod.yml, ./.env
target: /home
# 원격으로 docker compose up 실행
- name: remote docker-compose up via ssh
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USERNAME }}
key: ${{ secrets.DEPLOY_KEY }}
port: ${{ secrets.DEPLOY_PORT }}
envs: APPTOKEN,USERNAME
script: |
echo ${{ secrets.GHUB_TOKEN }} | sudo docker login ghcr.io --username ${{ secrets.GHUB_USERNAME }} --password-stdin &&
cd /home &&
sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/server:${{ secrets.RELEASE_VERSION }} &&
sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/client:${{ secrets.RELEASE_VERSION }} &&
sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/db:${{ secrets.RELEASE_VERSION }} &&
sudo docker pull ghcr.io/${{ secrets.GHUB_USERNAME }}/nginx:${{ secrets.RELEASE_VERSION }}
4. Dockefile
ghcr(컨테이너 레지스트리)에서 image를 pull 하므로 배포용 Docker 파일을 다음과같이 바꿔야 한다.
app:
image: ghcr.io/${IMAGE_REPO}:${RELEASE_VERSION}
5. secrets
github repository -> Settings -> Secrets and variables에서 secrets 항목들을 추가해준다.
참고로 github username은 반드시 소문자로 해야된다.
self-hosted 로 사용할 경우 서버의 사용자에 Docker 권한을 부여해주어야 한다.
How to fix docker: Got permission denied issue - Stack Overflow
참고
GitHub Action Docker Compose deployments via SSH (servicestack.net)
728x90
반응형
'DevOps > Git' 카테고리의 다른 글
Git | Github Actions | Auto Labeling workflow ( PR 라벨링 자동화 ) (0) | 2024.05.02 |
---|---|
Git | Github Actions | Auto Labeling with Pull Request (0) | 2024.04.30 |
Git | Github Actions CI/CD 파이프라인 구축 (0) | 2023.09.19 |
Git | 깃허브 commit 되돌리기( reset, revert ) (0) | 2022.11.11 |
Git | .gitignore 기본 세팅 (0) | 2022.08.02 |