Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: workflow.yml
on:
push:
branches: [ main ]

jobs:

build:
name: Build Image
runs-on: ubuntu-24.04

steps:
- name: Check out code
uses: actions/checkout@v2

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ap-northeast-2

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Build, tag, and push image to Amazon ECR
run: |
docker build -t dearbelly-cv .
docker tag dearbelly-cv:latest ${{ secrets.ECR_URI }}/dearbelly-cv
docker push ${{ secrets.ECR_URI }}/dearbelly-cv:latest

transfer:
runs-on: ubuntu-24.04
needs: build
steps:
- name: Checkout Code
uses: actions/checkout@v4


deploy:
name: Deploy
runs-on: ubuntu-24.04
needs: transfer
steps:
- name: SSH into EC2 server and Deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
# 1. cd
mkdir -p ~/dearbelly
cd ~/dearbelly

# 2. .env file
echo "${{ secrets.ENV }}" > .env
sudo chmod 600 .env

# 3. aws login
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ secrets.ECR_URI }}

# 4. export env
export ECR_URI=${{ secrets.ECR_URI }}

# 5. pull Image
docker pull ${{ secrets.ECR_URI }}/dearbelly-cv:latest

# 6. docker start
# TODO : 스크립트 작성
docker run -d --name app-blue -p 8000:8000 ${{ secrets.ECR_URI }}/dearbelly-cv:latest
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM nvidia/cuda:12.6.0-runtime-ubuntu24.04

WORKDIR /app

RUN apt-get update && \
apt-get install -y python3 python3-pip git && \
ln -s /usr/bin/python3 /usr/bin/python && \
pip install --upgrade pip && \
apt-get clean && rm -rf /var/lib/apt/lists/*

COPY . .

RUN pip install --no-cache-dir -r app/requirements.txt

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
21 changes: 14 additions & 7 deletions app/core/config.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
from pydantic_settings import BaseSettings
import os
from dotenv import load_dotenv

load_dotenv()

redis_url = os.getenv("REDIS_SERVER_URL")
bucket_name = os.getenv("BUCKET_NAME")
s3_region = os.getenv("S3_REGION")


class Settings(BaseSettings):
REDIS_URL: str = os.environ.get("REDIS_SERVER_URL", "redis://localhost:6379")
S3_REGION: str = os.environ.get("S3_REGION", "ap-northeast-2")
S3_ENDPOINT_URL: str | None = os.environ.get("S3_ENDPOINT_URL")
BUCKET_NAME: str = os.environ.get("BUCKET_NAME")
REDIS_URL: str = redis_url
S3_REGION: str = bucket_name
BUCKET_NAME: str = s3_region

STREAM_JOB: str = "image.jobs"
STREAM_RESULT: str = "image.results"
GROUP_NAME: str = "fastapi-workers"
STREAM_JOB: str = "image.jobs" # SpringBoot에서 job 발행 (FastAPI에서 listen)
STREAM_RESULT: str = "image.results" # FastAPI에서 결과 발행 (SpringBoot에서 listen)
GROUP_NAME: str = "fastapi-workers" # FastAPI Consumer group name
CONSUMER_NAME: str = "consumer-1"


Expand Down
3 changes: 0 additions & 3 deletions app/core/lifespan.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ async def lifespan(app: FastAPI):
worker = JobWorker(redis_client)
worker_task = asyncio.create_task(worker.run())

app.state.redis_client = redis_client
app.state.worker_task = worker_task

try:
yield
finally:
Expand Down
6 changes: 3 additions & 3 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from app.api.endpoints import predictions

app = FastAPI(
title="DearBelly AI-Powered Pill Identification Service",
description="An AI service to identify pills from images, using a job queue for async processing.",
version="2.0.0",
title="DearBelly CV API",
description="DearBelly CV를 위한 Swagger 입니다.",
version="1.0.0",
lifespan=lifespan
)

Expand Down
14 changes: 7 additions & 7 deletions app/schemas/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class JobResult(BaseModel):
finished_at: str

class ImageJob(BaseModel):
correlationId: str
presignedUrl: str
replyQueue: str
callbackUrl: str | None = None
contentType: str
createdAt: str
ttlSec: int
correlation_id: str = Field(alias="correlationId")
presigned_url: str = Field(alias="presignedUrl")
reply_queue: str = Field(alias="replyQueue")
callback_url: str | None = Field(alias="callbackUrl")
content_type: str = Field(alias="contentType")
created_at: str = Field(alias="createdAt")
ttl_sec: int = Field(alias="ttlSec")
1 change: 0 additions & 1 deletion app/services/s3_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def __init__(self):
self.client = boto3.client(
"s3",
region_name=settings.S3_REGION,
endpoint_url=settings.S3_ENDPOINT_URL,
config=BotoConfig(
retries={"max_attempts": 5, "mode": "standard"},
read_timeout=30,
Expand Down
10 changes: 1 addition & 9 deletions app/worker/redis_client.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import redis
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field
from typing import Any, Dict
from app.core.config import settings

load_dotenv()

redis_host = os.environ.get("REDIS_SERVER_HOST")

redis_client = redis.Redis(
host=redis_host, port=6379, encoding="UTF-8", decode_responses=True
)
redis_client = redis.asyncio.from_url(settings.REDIS_URL, decode_responses=True)

class PublishRequest(BaseModel):
stream: str = Field(default=settings.JOB_STREAM, description="Redis Stream Job name")
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ boto3
requests
torch==2.8.0
torchvision==0.23.0
Pillow==11.3.0
Pillow==11.3.0
dotenv