• ABOUT
  • POSTS
  • GUESTBOOK

ยฉ 2025 BlueCool12 All rights reserved.

2025.09.17ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

๐Ÿž CI/CD ์˜ค๋ฅ˜: GHCR์„ ์ด์šฉํ•œ GitHub Actions ์ตœ์ ํ™” ๋ฐฐํฌ

[๋ฌธ์ œ ์š”์•ฝ] 

  • ์ฆ์ƒ: GitHub Actions๋ฅผ ํ†ตํ•œ ๋ฐฐํฌ ์ค‘ Connection timeout ๋ฐœ์ƒ
  • ์›์ธ: ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ ์ฆ๊ฐ€๋กœ ํ™ˆ์„œ๋ฒ„์—์„œ ์ง์ ‘ Docker ๋นŒ๋“œ๊ฐ€ ์˜ค๋ž˜ ๊ฑธ๋ ค SSH ์„ธ์…˜/์ž‘์—… ์ œํ•œ ์‹œ๊ฐ„์„ ์ดˆ๊ณผ
  • ํ•ด๊ฒฐ: GitHub Actions์—์„œ GHCR(GitHub Container Registry)๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œยทํ‘ธ์‹œ, ์„œ๋ฒ„๋Š” ์ด๋ฏธ์ง€ pull ํ›„ ์žฌ๋ฐฐํฌ 

 



๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ GitHub Actions ๊ตฌ์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•˜๋‹ค. 
 

name: Deploy to Raspberry Pi 

on:
push:
branches: [ main ]

jobs:
deploy:
name: Deploy via SSH
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup SSH
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

- name: SSH and deploy to Raspberry Pi
run: |
ssh -p ${{ secrets.RASPBERRY_PORT }} -o StrictHostKeyCheking=no ${{ secrets.RASPBERRY_USER }}@${{ secrets.RASPBERRY_HOST }} << 'EOF'
set -euo pipefail

cd /home/${{ secrets.RASPBERRY_USER }}/docker-compose/bluecool/blue
git fetch --all --prune
git reset --hard origin/main
git config core.ignorecase false

docker compose build --no-cache blue
docker compose up -d --force-recreate blue

docker image prune -f || true
EOF


ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ž‘์„๋•Œ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์ง€๋งŒ ์ ์  ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์„œ๋ฒ„ ์ธก์—์„œ docker compose build --no-cache ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋นŒ๋“œ ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•˜์—ฌ ํƒ€์ž„์•„์›ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค. 

๋”ฐ๋ผ์„œ CI์—์„œ ์ด๋ฏธ์ง€๋ฅผ GHCR์— ๋นŒ๋“œยทํ‘ธ์‹œํ•˜๊ณ  ์„œ๋ฒ„๋Š” ๋นŒ๋“œ ์—†์ด pull๋งŒ ํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ๋‹ค. ๋ณ€๊ฒฝ๋œ ์„ค์ •์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 
 

name: Build & Deploy to Raspberry Pi

on:
push:
branches: [ main ]

concurrency:
group: blue-deploy-${{ github.ref }}
cancel-in-progress: true

env:
IMAGE_NAME: ghcr.io/bluecool12/blue

jobs:
build:
name: Build & Push (GHCR)
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build & Push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/arm64
push: true
tags: |
${{ env.IMAGE_NAME }}:latest
${{ env.IMAGE_NAME }}:${{ github.sha }}
cache-from: type-gha
cache-to: type-gha,mode=max
build-args: |
NEXT_PUBLIC_API_BASE_URL=${{ vars.NEXT_PUBLIC_API_BASE_URL }}
PUBLIC_API_BASE_URL=${{ vars.PUBLIC_API_BASE_URL }}

deploy:
name: Deploy via SSH (pull & up)
runs-on: ubuntu-latest
needs: build
steps:
- name: Setup SSH
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

- name: Add host key (known_hosts)
run: |
mkdir -p ~/.ssh
ssh-keyscan -p "${{ secrets.RASPBERRY_PORT }}" -H "${{ secrets.RASPBERRY_HOST }}" >> ~/.ssh/known_hosts
chmod 700 ~/.ssh
chmod 644 ~/.ssh/known_hosts

- name: SSH and deploy to Raspberry Pi
run: |
ssh -p ${{ secrets.RASPBERRY_PORT }} \
-o ServerAliveInterval-30 -o ServerAliveCountMax=10 \
${{ secrets.RASPBERRY_USER }}@${{ secrets.RASPBERRY_HOST }} << 'EOF'
set -Eeuo pipefail

cd /home/${{ secrets.RASPBERRY_USER }}/docker-compose/bluecool/blue

git fetch --all --prune || true
git reset --hard origin/main || true
git config core.ignorecase false || true

docker compose pull blue
docker compose up -d blue
doccker image prune -f || true
EOF


๊ธฐ์กด์˜ Dockerfile์„ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋กœ ์˜ฎ๊ธฐ๊ณ  GitHub Actions์—์„œ GHCR๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œยทํ‘ธ์‹œํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์˜€๊ณ  Buildx ์บ์‹œ๋ฅผ ํ™œ์šฉํ•ด ๋นŒ๋“œ ์†๋„๊นŒ์ง€ ์ตœ์ ํ™” ํ•˜์˜€๋‹ค. 

ํ™ˆ์„œ๋ฒ„์—์„œ๋Š” docker-compose.yml์ด ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ์ˆ˜์ •ํ•˜๊ณ  ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋˜ํ•œ GitHub Variables๋ฅผ ํ†ตํ•ด ์ฃผ์ž…ํ•˜์˜€๋‹ค. 

๋˜ํ•œ SSH ์ ‘์† ์‹œ ํ˜ธ์ŠคํŠธ ์ธ์ฆ์„ ์ƒ๋žตํ•˜์ง€ ์•Š๊ณ  known_hosts์— ํ‚ค๋ฅผ ๋ฏธ๋ฆฌ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜์˜€๋‹ค. 
 

์ด์ „ ๊ธ€
๐Ÿ” chownยทchmod๋กœ ๋ฐฐ์šฐ๋Š” ๋ฆฌ๋ˆ…์Šค ํŒŒ์ผ ๊ถŒํ•œ ๊ด€๋ฆฌ
๋‹ค์Œ ๊ธ€
๐Ÿ“ก ์ธํ„ฐ๋„ท ํ†ต์‹ ์˜ ํ•ต์‹ฌ - TCP, IP ๊ทธ๋ฆฌ๊ณ  UDP ์ดํ•ดํ•˜๊ธฐ
์žฅ์‹์šฉ ๋กœ๊ณ