오늘 Meat-A-Eye 서비스의 백엔드와 프론트엔드를 AWS EC2 환경에서 Docker로 배포했습니다.트러블슈팅 과정과 최종 성공 명령어를 한 페이지로 정리합니다.
개요
- 환경: AWS EC2 (Ubuntu 24.04 LTS)
- 백엔드: FastAPI (Python 3.11) + RDS (MySQL)
- 프론트엔드: Next.js 16 + Tailwind CSS
- 핵심 도구: Docker (Containerization)
명령 프롬프트 실행(cmd) -> cd 본인 .pem으로 서버 접속
ls -a # 현재 상태 확인용
1단계: 프로젝트 루트 설정 및 환경 변수(.env) 통합
배포의 핵심은 보안과 설정의 분리입니다. 모든 중요한 키(API Key, DB 정보)를 루트 폴더(Meat-A-Eye-Service)의 .env 파일 하나로 관리합니다.
1. .env 파일 생성 및 작성
cd ~/Meat-A-Eye-Service
nano .env
내용 작성 (중요: 변수명은 백엔드 코드의 Settings 클래스와 일치해야 함)
# [DB 정보]
MYSQL_HOST=your-rds-endpoint.amazonaws.com
MYSQL_PORT=3306
MYSQL_USER=admin
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=meat_eye
# [API 키 5종 세트 및 기타]
KAMIS_API_KEY=your_key
SAFE_FOOD_API_KEY=your_key
TRACEABILITY_API_KEY=your_key
IMPORT_MEAT_API_KEY=your_key
GEMINI_API_KEY=your_key
# [프론트엔드 통신용]
NEXT_PUBLIC_API_URL=http://your-ec2-public-ip:8000
Ctrl + O -> Enter (저장), Ctrl + X (종료)
2단계: 백엔드(FastAPI) 도커 배포
1. Dockerfile 작성 (최적화 버전)
이 Dockerfile은 libgl1 라이브러리 문제를 해결하고, uvicorn이 meat_backend.main 모듈 안에 있는 app을 직접 실행하도록 설계되었습니다.
cat > Dockerfile <<EOF
FROM python:3.11-slim
# 시스템 라이브러리 설치 (OpenCV 등 이미지 처리에 필수)
RUN apt-get update && apt-get install -y \\
libgl1 \\
libglib2.0-0 \\
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 의존성 설치 (PyTorch CPU 버전으로 용량 최적화)
COPY Meat_A_Eye-backend/requirements.txt .
RUN pip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cpu
RUN pip install --no-cache-dir -r requirements.txt
# 소스 복사 및 경로 설정
COPY Meat_A_Eye-backend/ ./Meat_A_Eye-backend/
COPY Meat_A_Eye-aimodels/ ./Meat_A_Eye-aimodels/
# PYTHONPATH를 설정해야 내부 패키지 임포트가 깨지지 않음
ENV PYTHONPATH=/app/Meat_A_Eye-backend:/app/Meat_A_Eye-aimodels
WORKDIR /app/Meat_A_Eye-backend
EXPOSE 8000
# [핵심] uvicorn 실행 시 main.py 내의 app 객체를 정확히 타겟팅
CMD ["uvicorn", "meat_backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
EOF
2. 빌드 및 실행
# 이미지 빌드
docker build -t meat-a-eye-api .
# 컨테이너 실행 (8000번 포트 연결 및 .env 주입)
docker run -d --name meat-api-container -p 8000:8000 --env-file .env meat-a-eye-api
3단계: 프론트엔드(Next.js) 도커 배포
프론트엔드는 빌드 시 발생하는 타입 에러와 정적 파일 생성(out 폴더) 문제를 해결하는 것이 핵심입니다.
1. Tailwind & Next.js 설정 자동 수정
sed 명령어를 사용하여 tailwind.config.ts의 문법 오류를 수정하고, next.config.mjs에 배포 옵션을 추가합니다.
cd ~/Meat-A-Eye-Service/Meat_A_Eye-frontend
# Tailwind darkMode 타입 에러 수정 (["class"] -> "class")
sed -i 's/darkMode: \["class"\]/darkMode: "class"/g' tailwind.config.ts
# Next.js 정적 내보내기(Export) 및 빌드 에러 무시 설정
cat > next.config.mjs <<EOF
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: { unoptimized: true },
typescript: { ignoreBuildErrors: true }, // 빌드 중단 방지
eslint: { ignoreDuringBuilds: true },
};
export default nextConfig;
EOF
2. 프론트엔드 Dockerfile 작성 (Multi-stage)
용량을 줄이기 위해 빌드는 Node.js에서, 실행은 Nginx에서 수행합니다.
cat > Dockerfile <<EOF
# 1단계: 빌드 스테이지
FROM node:20-slim AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 2단계: Nginx 스테이지 (가벼운 웹 서버)
FROM nginx:stable-alpine
# 빌드된 out 폴더를 Nginx 경로로 복사
COPY --from=build-stage /app/out /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
EOF
3. 빌드 및 실행
# 이미지 빌드
docker build -t meat-a-eye-frontend .
# 컨테이너 실행 (80번 기본 포트 사용)
docker run -d --name meat-frontend-container -p 80:80 meat-a-eye-frontend
4. 실제 명령 프롬프트(CMD)창
# 1. 기존 컨테이너 중지 및 삭제
$ docker rm -f meat-api-container
meat-api-container
# 2. Dockerfile 작성 (백엔드 경로 최적화)
$ cat > Dockerfile <<EOF
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
libgl1 \
libglib2.0-0 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Meat_A_Eye-backend/requirements.txt .
RUN pip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cpu
RUN pip install --no-cache-dir -r requirements.txt
COPY Meat_A_Eye-backend/ ./Meat_A_Eye-backend/
COPY Meat_A_Eye-aimodels/ ./Meat_A_Eye-aimodels/
ENV PYTHONPATH=/app/Meat_A_Eye-backend:/app/Meat_A_Eye-aimodels
WORKDIR /app/Meat_A_Eye-backend
EXPOSE 8000
CMD ["uvicorn", "meat_backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
EOF
# 3. 도커 이미지 빌드
$ docker build -t meat-a-eye-api .
Successfully built 62b215f13e23
Successfully tagged meat-a-eye-api:latest
# 4. 컨테이너 실행 및 .env 환경 변수 주입
$ docker run -d --name meat-api-container -p 8000:8000 --env-file .env meat-a-eye-api
652159ff820676aa3030540004af720ea1d9b50c00e13a87d68eeffd3d6b2eea
# 5. 실행 상태 확인
$ docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
652159ff8206 meat-a-eye-api "uvicorn meat_backen…" Up 4 seconds 0.0.0.0:8000->8000/tcp meat-api-container
결과 확인
배포가 완료되면 아래의 주소로 접속하여 상태를 확인합니다.
| 서비스 | 접속 주소 | 확인 사항 |
| Frontend | http://[EC2-IP] | 메인 대시보드 화면 출력 여부 |
| Backend API | http://[EC2-IP]:8000/docs | Swagger UI 및 DB 데이터 통신 여부 |
