고용노동 정책 어시스턴트 배포 및 완료
고용노동 정책 어시스턴트 배포 후기: FastAPI + MySQL(Railway) + React(Vercel) 조합 완전체 구축기
오늘은 React 프론트엔드와 FastAPI 백엔드로 구성된 ‘고용노동 정책 어시스턴트’ 애플리케이션을 배포하는 과정에서 마주친 여러 문제와 이를 해결한 방법에 대해 자세히 공유하려고 합니다. 특히 Vercel과 Render라는 두 다른 플랫폼에 배포하면서 발생한 데이터베이스 연결, CORS, 라이브러리 의존성 등의 이슈를 어떻게 해결했는지 정리했습니다.
##
1. 배포 환경 구성
프로젝트는 다음과 같이 구성되어 있습니다:
- 프론트엔드: React (Vercel에 배포)
- 백엔드: FastAPI (Render에 배포)
- 데이터베이스: MySQL (Railway에 호스팅)
처음에는 로컬에서 모든 것이 잘 작동했지만, 실제 배포 환경에서는 여러 문제가 발생했습니다.
🛠 배포 과정
1. Railway로 MySQL 무료 DB 생성
MySQL을 로컬에서 뭘로 바꿀지 고민했다. 처음엔 맨날 쓰던 aws RDS DB를 쓸까 하다가 굳이 aws로 배포 안 할건데 하다가 찾다가 발견했다. 꽤나 괜찮은 것 같다. 관련 정보가 좀 부족하긴한데 앞으로도 유용하게 쓸듯?
DATABASE_URL=mysql:*********************net:42077/railway
MYSQL_HOST=****
MYSQL_PORT=42077
MYSQL_USER=root
MYSQL_PASSWORD=****
MYSQL_DB=railway
문제 1: 데이터베이스 연결 오류
오류 현상
백엔드를 Render에 배포한 후 첫 번째로 마주친 문제는 다음과 같은 데이터베이스 연결 오류였습니다:
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'mysql.railway.internal' ([Errno -2] Name or service not known)")
오류 원인
로그를 분석한 결과, FastAPI 애플리케이션이 mysql.railway.internal
이라는 내부 호스트명으로 MySQL 데이터베이스에 연결을 시도하고 있었습니다. 이 호스트명은 Railway 플랫폼 내부에서만 접근 가능한 주소로, Render에서 호스팅되는 애플리케이션에서는 접근할 수 없었습니다.
해결 방법
Render 대시보드에서 환경 변수를 확인한 결과, MYSQL_HOST
가 mysql.railway.internal
로 설정되어 있었습니다. 이를 Railway 데이터베이스의 외부 접속 URL인 centerbeam.proxy.rlwy.net
으로 변경하고, 포트도 3306
에서 42077
로 수정했습니다.
# 변경 전
MYSQL_HOST=mysql.railway.internal
MYSQL_PORT=3306
# 변경 후
MYSQL_HOST=centerbeam.proxy.rlwy.net
MYSQL_PORT=42077
그리고 DATABASE_URL
도 외부 접속 URL을 사용하도록 설정했습니다:
DATABASE_URL=mysql://root:sc****************xy.rlwy.net:42077/railway
##
2. Render로 FastAPI 배포
Render에 백엔드 프로젝트를 연결하고, 위에서 설정한 MySQL 변수들을 .env
파일 또는 Render 환경변수에 등록했다.
👉 주의할 점
.env
파일이 backend 폴더 내부가 아니라 루트(root) 에 있다면 Settings(BaseSettings)
에서 env_file = ".env"
로는 못 불러온다. backend/.env
로 위치를 맞춰줘야 정상 동작!
처음에 .env가 frontend에 한개, root에 한개 있어서 좀 이 에러가 오래 걸렸다. 다음부터는 .env파일 처음부터 디렉토리 잘 해놔야겠다. 로컬에서는 문제가 없어서 넘겼더니 이런 문제가 생겼다.
###
3. Pinecone 관련 에러
Exception: The official Pinecone python package has been renamed from `pinecone-client` to `pinecone`.
✅ 해결 방법
requirements.txt
에서 pinecone-client
를 제거하고 pinecone
최신 패키지를 설치한 후 다시 배포했다.
최신버전의 pinecone 에서는 pinecone-client가 아니라 pinecone을 사용한다. langchain도 그렇고 이런 건 공식문서에서 계속 바뀌어서 좀 귀찮다. 걍 둘 다 되게 나두면 안되나.
###
4. CORS 정책 문제
가장 시간을 오래 잡아먹었던 이슈 😵💫
증상
- 프론트엔드에서 회원가입 버튼 클릭 시 다음 오류 발생:
XMLHttpRequest cannot load https://labor-policy-assistant.onrender.com/api/v1/auth/register due to access control checks.
Preflight response is not successful. Status code: 400
원인
.env
파일에 정의한 CORS_ORIGINS
이 ["http://localhost:3000"]
만 있어서, 실제 배포된 프론트엔드 URL이 허용되지 않음.
✅ 해결 방법
.env
에 다음처럼 배포 URL 추가:
CORS_ORIGINS=["http://localhost:3000", "https://labor-policy-assistant.vercel.app"]
그리고 config.py
에서 이를 settings.CORS_ORIGINS
로 불러오게 되어 있으므로, FastAPI에 CORS 미들웨어는 정상적으로 적용됨 ✅
5. React에서 API URL 하드코딩 문제
처음엔 http://localhost:8000
으로 하드코딩된 상태였음
→ 실제 배포된 백엔드 API는 Render에서 호스팅된 도메인이므로, 하드코딩하면 당연히 CORS 오류.
✅ 해결 방법
.env
파일에 다음처럼 작성:
REACT_APP_API_URL=https://labor-policy-assistant.onrender.com
- 코드에서 하드코딩된 부분을 다음처럼 수정:
const API_URL = process.env.REACT_APP_API_URL;
✅ 최종 확인
- 회원가입/로그인 정상 작동
- 정책 목록 및 추천 정상 호출
- AI 요약 및 챗봇 기능 정상 작동
- 프론트와 백엔드 완벽 연동
🔚 마무리
이번 배포는 단순히 서버 올리는 수준이 아니라,
- 환경변수 관리
- CORS 처리
- API 연결
- 패키지 버전 이슈
- 데이터베이스 연결
까지 모두 포함되어서 좀 오래걸렸던 것 같다. 그래도 하루만에 끝나서 다행이다. 이제 다음 프로젝트 바로 들어가자.