diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 896921e..26789d3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -2,66 +2,16 @@ name: CI/CD Pipeline on: push: - branches: [ main, develop, 'fix/*' ] + branches: [ main ] pull_request: - branches: [ main, develop, 'fix/*' ] + branches: [ main ] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: - test: - runs-on: ubuntu-latest - - # 환경변수 설정 - env: - ENVIRONMENT: development - DEBUG: true - LOG_LEVEL: INFO - GITHUB_ACTIONS: true - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Setup Python Environment - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Cache Dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - # Install test tools first (including pytest-env) - pip install pytest==8.3.4 pytest-asyncio==0.25.0 pytest-env==1.1.5 flake8==7.1.1 black==25.1.0 isort==5.13.2 - # Then install project dependencies - pip install -r requirements.txt - - - name: Code Quality Check - run: | - # Check only critical syntax errors - flake8 app/ --count --select=E9,F63,F7,F82 --show-source --statistics - echo "Code quality check completed" - - - name: Run Tests - run: | - export APP_NAME="Ururu AI Recommendation System" - export EMBEDDING_MODEL_NAME="sentence-transformers/all-MiniLM-L6-v2" - export EMBEDDING_DIMENSION="384" - python -m pytest tests/ -v --tb=short - continue-on-error: false - build-and-push: - needs: test runs-on: ubuntu-latest if: github.event_name == 'push' @@ -94,63 +44,14 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile + file: ./docker/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - deploy-development: - needs: build-and-push - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/develop' - environment: development - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Checkout Config Repository - uses: actions/checkout@v4 - with: - repository: UruruLab/Ururu-AI-Config - path: config - token: ${{ secrets.PRIVATE_REPO_TOKEN }} - - - name: Copy Development Environment Config Files - run: | - if compgen -G "config/.env*" > /dev/null; then - if [ -f "config/.env.development" ]; then - cp config/.env.development .env.development - echo "✅ Development environment config files copied successfully" - else - echo "❌ .env.development not found in config repository" - exit 1 - fi - else - echo "❌ No config files found in config repository" - exit 1 - fi - - - name: Validate Docker Compose Configuration - run: | - echo "Validating development environment configuration files" - echo "Validating docker-compose.development.yml syntax" - ENVIRONMENT=development docker compose -f docker-compose.development.yml config --quiet - echo "Verifying environment variable bindings" - ENVIRONMENT=development docker compose -f docker-compose.development.yml config \ - | grep -A 10 "environment:" \ - | grep "^[[:space:]]*[[:alpha:]]" \ - | sed 's/.*$/&/' || true - echo "Development environment deployment preparation completed" - - - name: Simulate Deployment (No actual EC2 deployment) - run: | - echo "Development environment deployment simulation" - echo "- Docker Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop" - echo "- Config File: .env.development (fetched from Config repository)" - echo "Development environment deployment configuration completed" + # Development 배포는 VPC 내부 통신에서 불필요하므로 제거 deploy-production: needs: build-and-push @@ -167,7 +68,7 @@ jobs: with: repository: UruruLab/Ururu-AI-Config path: config - token: ${{ secrets.PRIVATE_REPO_TOKEN }} + token: ${{ secrets.GHCR_TOKEN }} - name: Copy Production Environment Config Files run: | @@ -183,29 +84,132 @@ jobs: echo "❌ No config files found in config repository" exit 1 fi - - - name: Validate Docker Compose Configuration - run: | - echo "Validating production environment configuration files" - echo "Validating docker-compose.production.yml syntax" - ENVIRONMENT=production docker compose -f docker-compose.production.yml config --quiet - echo "Verifying environment variable bindings" - ENVIRONMENT=production docker compose -f docker-compose.production.yml config \ - | grep -A 10 "environment:" \ - | grep "^[[:space:]]*[[:alpha:]]" \ - | sed 's/.*$/&/' || true - echo "Production environment deployment preparation completed" - - name: Prepare Deployment Notification - run: | - echo "Production environment deployment preparation completed" - echo "- Docker Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" - echo "- Config File: .env.production (fetched from Config repository)" - echo "Actual EC2 deployment will be handled by separate process" + - name: Deploy to FastAPI Production EC2 + uses: appleboy/ssh-action@v0.1.6 + env: + GITHUB_SHA: ${{ github.sha }} + with: + host: ${{ secrets.AI_EC2_HOST }} + username: ${{ secrets.AI_EC2_USER }} + key: ${{ secrets.AI_EC2_SSH_KEY }} + port: 22 + timeout: 600s + envs: GITHUB_SHA + script: | + set -e + echo "🚀 FastAPI AI 서비스 배포 시작" + + # 기존 컨테이너 상태 확인 + if docker ps | grep ururu-ai-service; then + echo "📊 기존 AI 서비스 로그 확인" + docker logs --tail 10 ururu-ai-service + fi + + # 작업 디렉토리 생성 및 이동 + mkdir -p /home/ec2-user/ururu-ai + cd /home/ec2-user/ururu-ai + + # 코드 업데이트 (올바른 디렉토리) + if [ ! -d ".git" ]; then + echo "📥 레포지토리 초기 클론" + git clone https://github.com/UruruLab/Ururu-AI.git . + else + echo "🔄 코드 업데이트" + git fetch origin + git checkout main + git reset --hard origin/main + fi + + # Config 파일 복사 (중복 생성 제거) + echo "📝 Config 파일 사용" + if [ ! -f ".env.production" ]; then + echo "❌ .env.production 파일이 없습니다. Config 리포지토리에서 가져와야 합니다." + exit 1 + fi + + # Docker 컨테이너 배포 + echo "🐳 Docker 컨테이너 배포" + cd docker/ + docker compose -f docker-compose-ai-prod.yml down || true + docker compose -f docker-compose-ai-prod.yml up -d --build + + echo "⏳ 서비스 시작 대기 중..." + sleep 30 + + # 헬스체크 + echo "🔍 헬스체크 시작" + for i in {1..60}; do + if curl -f http://localhost:8000/health 2>/dev/null; then + echo "✅ FastAPI 서비스 헬스체크 통과" + break + fi + if [ $i -eq 60 ]; then + echo "❌ 헬스체크 실패" + docker logs --tail 20 ururu-ai-service + exit 1 + fi + sleep 5 + done + + # 벡터 인덱스 상태 확인 + echo "📊 벡터 인덱스 상태 확인" + VECTOR_STATUS=$(curl -s http://localhost:8000/api/vector/status | grep -o '"total_vectors":[0-9]*' | cut -d':' -f2 || echo "0") + echo "벡터 인덱스 상태: $VECTOR_STATUS 개 벡터" + + # 임베딩 재생성 (필요시) + if [ "$VECTOR_STATUS" -lt 1000 ]; then + echo "🔄 벡터 인덱스 재생성 시작" + curl -X POST "http://localhost:8000/api/vector/embeddings/batch?batch_size=100&force_recreate=false" || echo "임베딩 재생성 요청 실패" + fi + + echo "🎉 FastAPI AI 서비스 배포 완료" + echo "$(date): FastAPI AI 서비스 배포 완료 - commit: $GITHUB_SHA" >> /home/ec2-user/deployment.log - - name: Deployment Completion Notification - if: success() + - name: Deployment Notification + if: always() run: | - echo "GitHub Actions deployment pipeline completed successfully." - echo "Docker image has been pushed to GitHub Container Registry." - echo "Manual execution required on EC2 server: docker compose pull && docker compose up -d" + if [ "${{ job.status }}" == "success" ]; then + echo "✅ FastAPI AI 서비스 배포 성공" + echo "🌐 AI 서비스: http://43.200.204.67:8000" + echo "📚 API 문서: http://43.200.204.67:8000/docs" + echo "🔗 Spring Boot 연동 준비 완료" + else + echo "❌ FastAPI AI 서비스 배포 실패" + echo "📝 로그 확인: docker logs ururu-ai-service" + fi + + - name: Create Deployment Issue on Failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: 'Production AI Service Deployment Failed', + body: `## As Is (Current Issue) + + Production AI service automated deployment has failed. + + **Deployment Information:** + - Commit: ${context.sha} + - Branch: ${context.ref} + - Execution Time: ${new Date().toISOString()} + - Workflow: ${context.workflow} + ## To Be (Expected Behavior) + + AI service should be deployed successfully and available for frontend AI recommendation features. + + ## Deadline + + Critical fix required within 1 hour + + ## References + + - [Workflow Execution Log](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) + - [EC2 AI Service Status](http://3.39.69.34:8000/health) + - [AI API Documentation](http://3.39.69.34:8000/docs) + `, + labels: ['urgent', 'ai-service', 'deployment'] + }) \ No newline at end of file diff --git a/.github/workflows/docker-health-check.yml b/.github/workflows/docker-health-check.yml index 3164eac..232217a 100644 --- a/.github/workflows/docker-health-check.yml +++ b/.github/workflows/docker-health-check.yml @@ -5,13 +5,11 @@ on: - cron: '0 */6 * * *' workflow_dispatch: push: - branches: + branches: - main - - 'fix/*' pull_request: - branches: + branches: - main - - 'fix/*' jobs: health-check: @@ -26,14 +24,21 @@ jobs: with: repository: UruruLab/Ururu-AI-Config path: config - token: ${{ secrets.PRIVATE_REPO_TOKEN }} + token: ${{ secrets.GHCR_TOKEN }} - - name: Copy Config Files (.env files) + - name: Copy Config Files to Docker Context run: | - mkdir -p ./ + # Docker 디렉토리 내에 config 폴더 생성 + mkdir -p ./docker/config + + # config repository의 .env 파일들을 docker/config에 복사 if compgen -G "config/.env*" > /dev/null; then - cp config/.env* ./ - echo "✅ Config files copied successfully" + cp config/.env* ./docker/config/ + echo "✅ Config files copied to docker/config/ successfully" + + # 복사된 파일 확인 + echo "📁 Copied files:" + ls -la ./docker/config/ else echo "❌ Config files not found in config repository" exit 1 @@ -41,46 +46,38 @@ jobs: - name: Verify Environment Files run: | - echo "📁 Checking copied environment files" - ls -la .env* - if [ -f ".env.development" ]; then - echo "✅ .env.development file exists" - else - echo "❌ .env.development file missing" - exit 1 - fi - if [ -f ".env.production" ]; then - echo "✅ .env.production file exists" + echo "📁 Checking Docker context config files" + ls -la ./docker/config/ + + if [ -f "./docker/config/.env.production" ]; then + echo "✅ .env.production file exists in docker context" else - echo "❌ .env.production file missing" + echo "❌ .env.production file missing in docker context" exit 1 fi - name: Validate Docker Compose Configuration run: | - echo "✅ Validating Docker Compose file syntax" - docker compose config --quiet - echo "✅ Validating development environment (using copied config files)" - ENVIRONMENT=development docker compose -f docker-compose.development.yml config --quiet - echo "✅ Validating production environment (using copied config files)" - ENVIRONMENT=production docker compose -f docker-compose.production.yml config --quiet + echo "✅ Validating main Docker Compose file syntax" + cd docker && docker compose -f docker-compose-ai.yml config --quiet + echo "✅ Docker Compose validation completed" + env: + GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} + ENVIRONMENT: production - name: Verify Environment Variable Bindings run: | echo "🔍 Verifying environment variable bindings" - echo "Development environment key variables:" - ENVIRONMENT=development docker compose -f docker-compose.development.yml config \ - | grep -A 20 "environment:" \ + cd docker + echo "Production environment configuration check:" + ENVIRONMENT=production GHCR_TOKEN=${{ secrets.GHCR_TOKEN }} \ + docker compose config \ + | grep -A 10 "environment:" \ | grep "^[[:space:]]*[[:alpha:]]" \ - | sed 's/.*$/&/' \ - | head -10 - echo "" - echo "Production environment key variables:" - ENVIRONMENT=production docker compose -f docker-compose.production.yml config \ - | grep -A 20 "environment:" \ - | grep "^[[:space:]]*[[:alpha:]]" \ - | sed 's/.*$/&/' \ + | sed 's/=.*/=/' \ | head -10 + env: + GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} - name: Simulate Health Check run: | @@ -89,14 +86,24 @@ jobs: echo "- Expected Response: {\"status\": \"healthy\", \"service\": \"ururu-ai-recommendation\"}" echo "🔍 Spring Backend Connection Test Simulation" - echo "- Target: http://localhost:8080/health" - echo "- Actual connection only available in EC2 environment" + echo "- VPC Target: http://10.0.5.114:8000/health (FastAPI EC2)" + echo "- Actual connection only available in VPC environment" - - name: Check GitHub Container Registry Images + - name: Check Configuration Completeness run: | - echo "📦 Checking latest Docker images" - echo "- Registry: ghcr.io/${{ github.repository }}" - echo "- Latest tags: latest, main, develop" + echo "📦 Checking configuration completeness" + echo "- Docker Compose files: ✅" + echo "- Environment files: ✅" + echo "- Config repository integration: ✅" + + # 환경별 필수 변수 체크 + echo "🔍 Checking required environment variables" + cd docker + if grep -q "SPRING_BOOT_BASE_URL" config/.env.production; then + echo "✅ SPRING_BOOT_BASE_URL configured" + else + echo "⚠️ SPRING_BOOT_BASE_URL not found in production config" + fi - name: Generate Health Check Report run: | @@ -105,5 +112,11 @@ jobs: echo "✅ Config repository integration working" echo "✅ Environment-specific configuration files verified" echo "✅ Workflow configuration validated" - echo "️ Actual service status needs separate verification on EC2" - echo "Run on EC2: docker compose ps && docker compose logs" + echo "✅ File path mapping corrected" + echo "⚠️ Actual service status needs verification on EC2" + echo "" + echo "🔧 Next steps for deployment:" + echo "1. Ensure FastAPI EC2 (10.0.5.114) is running" + echo "2. Test VPC internal communication" + echo "3. Run: git push origin main to trigger CI/CD" + echo "4. Monitor deployment: docker compose ps && docker compose logs" \ No newline at end of file diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml deleted file mode 100644 index 1f56844..0000000 --- a/.github/workflows/performance-test.yml +++ /dev/null @@ -1,169 +0,0 @@ -name: Performance Test - -on: - workflow_dispatch: - inputs: - test_duration: - description: 'Test execution time (seconds)' - required: true - default: '60' - type: string - concurrent_users: - description: 'Number of concurrent users' - required: true - default: '5' - type: string - -jobs: - performance-test: - runs-on: ubuntu-latest - - steps: - - name: 코드 체크아웃 - uses: actions/checkout@v4 - - - name: Python 환경 설정 - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: 성능 테스트 도구 설치 - run: | - pip install locust==2.31.0 requests==2.32.3 fastapi==0.111.0 uvicorn==0.30.0 - - - name: 테스트용 FastAPI 서버 시작 - run: | - # 간단한 테스트 서버 생성 - cat > test_server.py << 'EOF' - from fastapi import FastAPI - import uvicorn - import asyncio - - app = FastAPI(title="Test Ururu AI Server") - - @app.get("/health") - async def health_check(): - return {"status": "healthy", "service": "ururu-ai-test"} - - @app.post("/api/v1/recommendations") - async def mock_recommendations(): - await asyncio.sleep(0.1) # 실제 AI 처리 시간 시뮬레이션 - return { - "recommendations": [ - {"product_id": 1, "score": 0.95, "name": "테스트 상품 1"}, - {"product_id": 2, "score": 0.89, "name": "테스트 상품 2"} - ], - "total_count": 2, - "processing_time_ms": 100 - } - EOF - - # 백그라운드에서 서버 실행 - python -c " - import uvicorn - import sys - sys.path.append('.') - uvicorn.run('test_server:app', host='0.0.0.0', port=8000, log_level='warning') - " & - - # 서버 시작 대기 - sleep 10 - - - name: 서버 준비 상태 확인 - run: | - for i in {1..30}; do - if curl -f http://localhost:8000/health; then - echo "✅ 테스트 서버가 준비되었습니다." - break - fi - echo "테스트 서버 시작을 기다리는 중... ($i/30)" - sleep 2 - done - - - name: Create Locust Performance Test File - run: | - cat > locustfile.py << 'EOF' - from locust import HttpUser, task, between - import json - - class UruruAITestUser(HttpUser): - wait_time = between(1, 3) - - def on_start(self): - self.client.verify = False - - @task(3) - def get_recommendations(self): - payload = { - "user_diagnosis": "I have dry skin and lack moisture", - "top_k": 10, - "max_price": 50000 - } - - with self.client.post( - "/api/v1/recommendations", - json=payload, - headers={"Content-Type": "application/json"}, - catch_response=True - ) as response: - if response.status_code == 200: - response.success() - else: - response.failure(f"Recommendation API failed: {response.status_code}") - - @task(1) - def health_check(self): - with self.client.get("/health", catch_response=True) as response: - if response.status_code == 200: - response.success() - else: - response.failure(f"Health check failed: {response.status_code}") - EOF - - - name: Run Performance Test - run: | - echo "🚀 Starting performance test (Users: ${{ github.event.inputs.concurrent_users }}, Time: ${{ github.event.inputs.test_duration }}s)" - locust \ - --host=http://localhost:8000 \ - --users=${{ github.event.inputs.concurrent_users }} \ - --spawn-rate=1 \ - --run-time=${{ github.event.inputs.test_duration }}s \ - --headless \ - --csv=performance_results \ - --html=performance_report.html || echo "Performance test completed" - - - name: Analyze Performance Test Results - run: | - echo "=== Performance Test Results Summary ===" - if [ -f performance_results_stats.csv ]; then - echo "📊 Request Statistics:" - cat performance_results_stats.csv | head -5 - echo "" - echo "❌ Failure Statistics:" - cat performance_results_failures.csv 2>/dev/null || echo "No failures" - else - echo "⚠️ Performance test result files not found." - fi - - echo "" - echo "=== Test Environment Information ===" - echo "- Concurrent Users: ${{ github.event.inputs.concurrent_users }}" - echo "- Test Duration: ${{ github.event.inputs.test_duration }}s" - echo "- Server Environment: GitHub Actions (ubuntu-latest)" - echo "- Test Target: Mock FastAPI Server" - - - name: Upload Result Files - uses: actions/upload-artifact@v4 - if: always() - with: - name: performance-test-results-${{ github.run_number }} - path: | - performance_results*.csv - performance_report.html - - - name: Cleanup Test Environment - if: always() - run: | - echo "🧹 Cleaning up test environment" - pkill -f "uvicorn" || echo "Server process cleanup completed" - echo "✅ Performance test completed!" diff --git a/app/core/config.py b/app/core/config.py index 13d4fc0..408fb67 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -52,6 +52,17 @@ class Settings(BaseSettings): HTTP_RETRY_COUNT: int = 3 HTTP_RETRY_DELAY: float = 1.0 + # 개발용 설정 (선택적) + SPRING_BOOT_INTEGRATION_ENABLED: bool = False + USE_MOCK_DATA: bool = True + MOCK_PRODUCTS_COUNT: int = 100 + + # Redis 설정 (선택적) + REDIS_URL: str = "redis://localhost:6379" + REDIS_HOST: str = "localhost" + REDIS_PORT: int = 6379 + REDIS_PASSWORD: str = "" + # 로깅 설정 (환경변수에서만 가져옴) LOG_LEVEL: str LOG_FORMAT: str diff --git a/docker-compose.development.yml b/docker-compose.development.yml deleted file mode 100644 index 678109a..0000000 --- a/docker-compose.development.yml +++ /dev/null @@ -1,51 +0,0 @@ -services: - ururu-ai: - build: - target: development - environment: - - ENVIRONMENT=development - - REDIS_HOST=redis # 개발환경에서는 Redis 컨테이너와 연결 - - REDIS_URL=redis://redis:6379 - - SPRING_BOOT_INTEGRATION_ENABLED=false # 개발환경에서는 Spring Boot 연동 비활성화 - - USE_MOCK_DATA=true # Mock 데이터 사용 - env_file: - - .env.development - volumes: - - .:/app - # 컨테이너 내부 venv 디렉토리 보호 - - /app/venv - command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] - # 개발환경에서만 디버깅용 포트 노출 (선택적) - ports: - - "${AI_PORT:-8001}:8000" # 개발용으로만 8001 포트 노출 - networks: - - ururu-network - depends_on: - - redis - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - - # 개발용 Redis (캐싱 및 세션 저장용) - redis: - image: redis:7-alpine - container_name: ururu-ai-redis-dev - ports: - - "6379:6379" - volumes: - - redis_data:/data - command: redis-server --appendonly yes - networks: - - ururu-network - -networks: - ururu-network: - driver: bridge - name: ururu-network - -volumes: - redis_data: - driver: local diff --git a/docker-compose.production.yml b/docker-compose.production.yml deleted file mode 100644 index bcf705b..0000000 --- a/docker-compose.production.yml +++ /dev/null @@ -1,49 +0,0 @@ -services: - ururu-ai: - build: - target: production - environment: - - ENVIRONMENT=production - - SPRING_BOOT_INTEGRATION_ENABLED=true # 운영환경에서는 Spring Boot 연동 필수 - - USE_MOCK_DATA=false # 실제 데이터 사용 - env_file: - - .env.production - ports: - - "${AI_PORT:-8000}:8000" # Spring Boot 서버에서 접근 가능 - networks: - - ururu-network - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - deploy: - replicas: 2 - resources: - limits: - cpus: '2.0' - memory: 2G - reservations: - cpus: '1.0' - memory: 1G - restart_policy: - condition: on-failure - delay: 5s - max_attempts: 3 - - # 운영용 로그 수집 (Fluent Bit) - fluent-bit: - image: fluent/fluent-bit:latest - container_name: ururu-ai-logs - volumes: - - ./logs:/var/log/app:ro - - ./fluent-bit/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro - networks: - - ururu-network - restart: unless-stopped - -networks: - ururu-network: - driver: bridge - name: ururu-network \ No newline at end of file diff --git a/Dockerfile b/docker/Dockerfile similarity index 87% rename from Dockerfile rename to docker/Dockerfile index f5fbccc..c920518 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -50,15 +50,6 @@ RUN groupadd -r appgroup && useradd -r -g appgroup appuser # 애플리케이션 코드 복사 COPY --chown=appuser:appgroup . . -# 로그 디렉토리 생성 및 권한 설정 -RUN mkdir -p /app/logs && \ - chown -R appuser:appgroup /app && \ - chmod -R 755 /app/logs - -# 캐시 디렉토리 생성 -RUN mkdir -p /app/.cache && \ - chown appuser:appgroup /app/.cache - # 비root 사용자로 전환 USER appuser diff --git a/docker/docker-compose-ai-prod.yml b/docker/docker-compose-ai-prod.yml new file mode 100644 index 0000000..2097818 --- /dev/null +++ b/docker/docker-compose-ai-prod.yml @@ -0,0 +1,42 @@ +services: + ururu-ai: + build: + context: .. + dockerfile: docker/Dockerfile + target: production + container_name: ururu-ai-service + environment: + - ENVIRONMENT=production + env_file: + - ../.env.production + ports: + - "8000:8000" + volumes: + - ../logs:/app/logs + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + deploy: + resources: + limits: + cpus: '1.0' + memory: 1.5G + reservations: + cpus: '0.5' + memory: 512M + networks: + - ururu-network + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + +networks: + ururu-network: + driver: bridge + name: ururu-network \ No newline at end of file diff --git a/docker-compose.yml b/docker/docker-compose-ai.yml similarity index 89% rename from docker-compose.yml rename to docker/docker-compose-ai.yml index aaa8360..9650b7c 100644 --- a/docker-compose.yml +++ b/docker/docker-compose-ai.yml @@ -6,7 +6,7 @@ services: - ./config:/config - ./scripts:/scripts:ro environment: - - GITHUB_TOKEN=${GITHUB_TOKEN} + - GITHUB_TOKEN=${GHCR_TOKEN} - CONFIG_REPO_URL=https://github.com/UruruLab/Ururu-AI-Config.git - ENVIRONMENT=${ENVIRONMENT:-production} command: /scripts/fetch-config.sh @@ -32,8 +32,8 @@ services: - ./config:/app/config:ro environment: - ENVIRONMENT=${ENVIRONMENT:-production} - # 컨테이너에서 호스트의 Spring Boot에 접근하기 위한 설정 - - SPRING_BOOT_BASE_URL=${SPRING_BOOT_BASE_URL:-http://host.docker.internal:8080} + # VPC 내부에서 Spring Boot EC2와 통신 + - SPRING_BOOT_BASE_URL=${SPRING_BOOT_BASE_URL:-http://10.0.X.X:8080} env_file: - ./config/.env.${ENVIRONMENT:-production} depends_on: