Skip to content

Docker Build & Deploy #15

Docker Build & Deploy

Docker Build & Deploy #15

Workflow file for this run

name: Docker Build & Deploy
on:
workflow_run:
workflows: ["CI Test (Pre-deployment)"]
types: [completed]
branches: [main]
# 중복 배포 방지 (한 번에 하나만 실행)
concurrency:
group: deploy-production
cancel-in-progress: true
jobs:
build-and-deploy:
name: Docker 빌드 & EC2 배포
# CI Test 성공 시에만 배포
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: GitHub Container Registry 로그인
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_PAT }}
- name: Docker 이미지 빌드 & 푸시
working-directory: ai_server
run: |
IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/onsikgu-ai-server
IMAGE_TAG=${{ github.sha }}
# 빌드
docker build -t $IMAGE_NAME:$IMAGE_TAG .
docker tag $IMAGE_NAME:$IMAGE_TAG $IMAGE_NAME:latest
# GHCR에 푸시
docker push $IMAGE_NAME:$IMAGE_TAG
docker push $IMAGE_NAME:latest
- name: EC2 디렉토리 준비 & docker-compose.yml 생성
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
script: |
# 디렉토리 생성
mkdir -p ~/onsikgu_ai
mkdir -p ~/onsikgu_data/chroma
# docker-compose.yml 생성
cat > ~/onsikgu_ai/docker-compose.yml << 'EOF'
version: '3.8'
services:
ai-server:
container_name: onsikgu-ai-server
image: ghcr.io/${{ github.repository_owner }}/onsikgu-ai-server:latest
ports:
- "8000:8000"
volumes:
- ~/onsikgu_data/chroma:/data/chroma
env_file:
- .env
environment:
- CHROMA_PERSIST_DIRECTORY=/data/chroma
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
EOF
- name: EC2에서 컨테이너 배포
uses: appleboy/ssh-action@master
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LANGCHAIN_API_KEY: ${{ secrets.LANGCHAIN_API_KEY }}
LANGCHAIN_PROJECT: ${{ secrets.LANGCHAIN_PROJECT }}
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
port: 22
timeout: 10m
envs: OPENAI_API_KEY,LANGCHAIN_API_KEY,LANGCHAIN_PROJECT
script: |
#!/bin/bash
set -e
echo "=========================================="
echo "🐳 Docker 배포 시작"
echo "시간: $(date)"
echo "=========================================="
# 1. Docker 정리 (디스크 공간 확보)
echo "🧹 Docker 정리 중..."
sudo docker system prune -af --volumes || true
echo " ✅ 정리 완료"
# 2. 작업 디렉토리
cd ~/onsikgu_ai
# 3. GHCR 로그인
echo "🔐 GitHub Container Registry 로그인..."
echo "${{ secrets.GHCR_PAT }}" | sudo docker login ghcr.io -u ${{ github.actor }} --password-stdin
# 4. 최신 이미지 Pull
echo "📥 최신 이미지 다운로드 중..."
sudo docker pull ghcr.io/${{ github.repository_owner }}/onsikgu-ai-server:latest
echo " ✅ 이미지 다운로드 완료"
# 5. .env 파일 생성
echo "📝 환경변수 설정 중..."
cat > .env << EOF
# OpenAI API
OPENAI_API_KEY=${OPENAI_API_KEY}
# Langsmith
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=${LANGCHAIN_API_KEY}
LANGCHAIN_PROJECT=${LANGCHAIN_PROJECT}
# ChromaDB
CHROMA_PERSIST_DIRECTORY=/data/chroma
CHROMA_COLLECTION_NAME=qa_history
CHROMA_DATA_PATH=${HOME}/onsikgu_data/chroma
# Server
ENVIRONMENT=production
EOF
echo " ✅ .env 파일 생성 완료"
# 6. Docker 설치 확인
if ! command -v docker &> /dev/null; then
echo "🐳 Docker 설치 중..."
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker ubuntu
newgrp docker
fi
# 7. Docker Compose 설치 확인
if ! command -v docker-compose &> /dev/null; then
echo "🐳 Docker Compose 설치 중..."
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
fi
# 8. 이전 컨테이너 중지 및 정리
echo "🛑 이전 컨테이너 중지 중..."
sudo docker-compose down || true
# 9. 컨테이너 시작 (빌드 없이 이미지 사용)
echo "🚀 컨테이너 시작 중..."
sudo docker-compose up -d
# 10. Health Check
echo "🏥 Health Check 중..."
sleep 10
for i in {1..10}; do
if curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ Health Check 성공!"
break
fi
echo " 시도 $i/10 실패, 5초 후 재시도..."
sleep 5
done
# 11. 상태 확인
echo "📊 컨테이너 상태:"
sudo docker-compose ps
echo "=========================================="
echo "✅ 배포 완료!"
echo "=========================================="
- name: 배포 실패 시 알림
if: failure()
run: |
echo "❌ 배포 실패!"
echo "원인: Docker 빌드 또는 Health Check 실패"