Skip to content

[FE]피드백 모달 수정 (#325) #29

[FE]피드백 모달 수정 (#325)

[FE]피드백 모달 수정 (#325) #29

name: Build & Deploy Prod (SSH & Tag-based)
on:
push:
tags:
- "v*" # ⬅ v1.0.0 이런 태그 push 시에만 빌드+배포
concurrency:
group: deploy-prod
cancel-in-progress: true
env:
REGISTRY: ghcr.io
IMAGE_BACK: ghcr.io/sisc-it/sisc-web-back
IMAGE_FRONT: ghcr.io/sisc-it/sisc-web-front # 프론트 이미지 추가
jobs:
# -----------------------------
# 1) 백엔드 Docker 빌드 + GHCR 푸시 (S3 대신 Docker 이미지로 빌드)
# -----------------------------
build-back:
runs-on: ubuntu-latest
environment: production
permissions: { contents: read, packages: write }
#defaults: # 직접 셸 명령어를 칠 때 기본 경로를 잡아주는 역할
#run:
#working-directory: backend
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & Push (backend)
uses: docker/build-push-action@v6
with:
context: ./backend
push: true
tags: |
${{ env.IMAGE_BACK }}:${{ github.ref_name }}
${{ env.IMAGE_BACK }}:latest
#cache-from: type=gha
#cache-to: type=gha,mode=max
# -----------------------------
# 2) 프론트
# -----------------------------
build-front:
runs-on: ubuntu-latest
environment: production
permissions: { contents: read, packages: write }
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-buildx-action@v3
- name: Build & Push (frontend)
uses: docker/build-push-action@v6
with:
context: ./frontend
push: true
platforms: linux/amd64
tags: |
${{ env.IMAGE_FRONT }}:${{ github.ref_name }}
${{ env.IMAGE_FRONT }}:latest
build-args: |
VITE_API_URL=${{ secrets.SPRING_API_URL }}
cache-from: type=gha
cache-to: type=gha,mode=max
# -----------------------------
# 3) 배포: 백엔드, 프론트
# -----------------------------
deploy:
needs: [build-back, build-front]
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Make .env file for Prod
run: |
echo "SPRING_PROFILES_ACTIVE=prod" > .env
echo "TAG=${{ github.ref_name }}" >> .env # ⬅ docker-compose에서 사용할 태그 버전
# DB & 기타 시크릿 (production 환경에 등록된 값을 자동으로 불러옴)
echo "DB_URL=${{ secrets.DB_URL }}" >> .env
echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> .env
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> .env
echo "SPRING_API_URL=${{ secrets.SPRING_API_URL }}" >> .env
echo "FRONTEND_URL=${{ secrets.FRONTEND_URL }}" >> .env
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
echo "MAIL_USERNAME=${{ secrets.MAIL_USERNAME }}" >> .env
echo "MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }}" >> .env
echo "SBA_ADMIN_NAME=${{ secrets.SBA_ADMIN_NAME }}" >> .env
echo "SBA_ADMIN_PASSWORD=${{ secrets.SBA_ADMIN_PASSWORD }}" >> .env
- name: SCP Transfer (docker-compose.yml & .env)
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
source: "docker-compose.yml, .env"
target: "/home/${{ secrets.SSH_USER }}/app/sisc-web/"
- name: SSH Deploy
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
script_stop: true
script: |
set -euo pipefail
# 필수 폴더 생성 및 DB 권한(UID 70) 부여. 운영 서버에 HDD가 마운트된 경로(/mnt/storage)가 있는지 확인 필요. (완료되어 주석처리)
# sudo mkdir -p /mnt/storage/pg_ai_data /mnt/storage/logs /mnt/storage/uploads ./data/postgres
# sudo chown -R 70:70 /mnt/storage/pg_ai_data ./data/postgres
cd ~/app/sisc-web
# GHCR 로그인
echo "${{ secrets.GHCR_READ_TOKEN }}" | docker login ghcr.io -u ${{ secrets.GHCR_READ_USER }} --password-stdin
# 컨테이너 기동
docker compose pull api web redis npm
docker compose up -d --remove-orphans api web redis npm db
docker image prune -f
# 서버 헬스체크
if docker ps --format '{{.Names}}' | grep -q "^api$"; then
echo "Waiting for api to be healthy..."
for i in {1..30}; do
status=$(docker inspect --format='{{json .State.Health.Status}}' api 2>/dev/null || echo '"none"')
if echo "$status" | grep -q healthy; then
echo "=== 운영 서버 정상 작동 확인 ==="; break
fi
sleep 2
done
fi
# 도커 용량 최적화
- name: Cleanup Docker
run: |
# 빌드 과정에서 생긴 모든 캐시 삭제 (-a 옵션이 핵심)
docker builder prune -a -f
# 태그가 없어진 이미지 삭제
docker image prune -f