Project/개인 Project

[Project] ChatGPT + 개인 DB 기반 운동기록 API 서버 구축기

강_토발즈 2025. 7. 14. 20:16

 

 



 

ChatGPT 를 유료로 사용한지 2달 정도 되었다. 무료로 사용할 땐, 하루 사용량 제한 같은게 있었기 때문에 궁금한게 있어도 다 물어보지 못하고 끊기는 것을 경험했다. 유료로 사용하니 제한 없이 물어보고, 공부하는데 사용하였다. 근데 한가지 더 욕심이 나는 것은, 나만의 데이터를 가지고 대답을 해주는 기능이였다. 이미 구현할 수 있는 것 이였지만, 구축하는 법을 모르고 있었다.

 

좀 더 자세히 얘기하자면, 나는 유산소 운동이나 근력운동을 할 때 지난번 운동 데이터 (운동 기록 앱의 사진) 을 ChatGPT 에게 넘겨주고, 점진적 과부화, 체지방 감소, 골격근 증가 와 같은 목표를 설정해주고 이에 맞는 가장 과학적인 근거를 이용해서, 무게와 횟수를 짜달라고 한다.

 

하지만 어느정도 운동 데이터가 쌓이니, 메모리가 가득 찼다고 정리하라고 나오기도 하고(소중한 데이터를 지우라고 한다), 어느날은 바로 직전의 데이터를 무시하고 이상한 볼륨과 횟수를 추천해주는 경우가 생겼다. 이에 내 운동정보를 나만의 DB에 저장해놓고, 필요할때 ChatGPT 가 이 DB 를 보고 운동 볼륨과 횟수를 추천해주면 좋겠다 라고 생각하고 바로 실행에 옮겼다

 

 

 1. 설계 단계

 Raspberry Pi 와 Synology NAS 그리고 ChatGPT 의 GPT 만들기 기능을 이용해서 외부에서도 접근 가능한 운동 기록 API 서버를 구축한다. 이 서버는 추후 ChatGPT나 다른 AI에게 내 운동 데이터를 기반으로 루틴을 추천받는 데 활용되는 것이다.  FastAPI + MariaDB + DDNS 포트포워딩으로 ChatGPT 가 내 개인 NAS 의 DB 에 접근하는 식으로 설계하였다.

 

2. 시스템 아키텍처

[외부 요청 (GPT, 브라우저 등)]
↓ 
*******.iptime.org:5055 (DDNS) 
[공유기 포트포워딩: 5055 → 192.168.0.54:5000]
↓
[Raspberry Pi (FastAPI API 서버 실행)]
↓ 
[NAS (192.168.0.20의 MariaDB에 저장된 운동기록에 접근)]
  • Raspberry Pi에 FastAPI 서버 실행해 놓는다.
  • NAS의 MariaDB에서 운동기록 테이블을 조회 할 수 있다. 
  • 외부에서 직접 API 호출 가능하게 한다. (포트포워딩 설정 완료)

즉, chatGPT 가 특정 API 를 호출하면 RaspberryPI 에서 실행 중인 서버가 응답해서 NAS 의 DB를 조회하여 운동기록을 반환하게 한다. chatGTP는 이를 활용하여 오늘 요구한 운동 볼륨과 횟수를 추천해주고 운동을 완료하면 다른 API 를 이용햐여 DB 에 업데이트 하도록 한다.

 

 

3. MariaDB 준비

CREATE DATABASE workout_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE workout_db; CREATE TABLE workout_records ( id INT AUTO_INCREMENT PRIMARY KEY, date DATE NOT NULL, muscle_group VARCHAR(20), exercise VARCHAR(50), weight FLOAT, reps INT, sets INT, difficulty INT, memo VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

 

테스트 데이터를 삽입한다.

INSERT INTO workout_records (date, muscle_group, exercise, weight, reps, sets, difficulty, memo) VALUES ('2025-07-13', '하체', '스쿼트', 70.0, 8, 3, 7, '무릎 괜찮음');

테이블과 테스트 데이터가 잘 삽입되었다.

 

 

 4. FastAPI 코드 구조

workout_api/ 
├── main.py ← API 서버 
├── db.py ← DB 연결 
├── crud.py ← 쿼리 함수 
├── models.py ← 테이블 모델 
├── requirements.txt

 

* 스크립트 파일은 root 암호가 노출, 중요 로직이 노출되어 첨부하지 않았음

 

-서버 실행 하기

uvicorn main:app --host 0.0.0.0 --port 5000

 5. 공유기 포트포워딩 하기

 
항목
외부 포트 5055
내부 IP 192.168.0.54 (Raspberry Pi)
내부 포트 5000
프로토콜 TCP
 
외부(ChatGPT) 에서 우리집으로 접속하고, 특정 프로그램으로 연결되게 하려면 포트포워딩을 해줘야 한다.또한 Synology NAS의 DSM 기본 포트(5000)와 겹치지 않도록 외부 포트를 다르게 설정해 주었다.

 

 

 6. 트러블슈팅: DB 접속 안 됨

서버를 띄운 상태에서 다른 터미널로 접속하여 crul 로 API 명령을 실행했는데 아래와 같은 에러 메시지가 반환되었다.

 

에러 메시지:

Can't connect to MySQL server on '@ang@192.168.0.20'

 

원인:

비밀번호에 @ 기호가 들어가 있었고, 이는 DB 접속용 DATABASE_URL 문자열의 URL 형식을 깨버리는 것 이였다.

 

해결법:

 

@ → %40 로 URL 인코딩을 해 주었다. DB 접속 비밀번호가 1234@ 라면 1234%40 으로 입력 하면 되는 것 이였다.

@ 말고도 다른 특수문자의 경우 인코딩 할 필요가 있으니 아래 인코딩 표를 참고.

 

특수문자 인코딩
@ %40
: %3A
/ %2F
# %23
! %21

 

7. 테스트 결과

- 외부에서 요청에 대한 응답 확인하기

curl http://**********.iptime.org:5055/workout/latest

# 개인 DNS 라 **** 처리
 
- 응답 결과 (외부 측)
 
 
-응답 결과 (서버 측)
 

 

외부에서 API 를 통해 DB 데이터에 대한 요청을 하였고 이에 하나의 세션이 생성되어 연결되었다. 그 이후 데이터를 json 타입으로 반환하여 전달하는 것을 확인할 수 있었다.

 

8. 오늘까지의 작업 마무리

오늘 작업을 통해:

  • 외부에서 접근 가능한 API 서버를 구축했고,
  • 실제 운동 기록을 JSON으로 반환 가능하게 했으며,
  • 비밀번호 인코딩이라는 중요한 트러블슈팅도 경험했다.

현재까지 구현한 전체 구조는 아래와 같다

 외부 요청 (같은 기기에서 테스트)
   ↓  (http://******.iptime.org:5055)
 공유기 포트포워딩 (5055 → 192.168.0.54:5000)
   ↓
 Raspberry Pi (FastAPI 실행 중)
   ↓
 NAS (MariaDB → workout_records 조회)
   ↓
 응답: JSON 운동기록

 

다음 번에는 ChatGPT와 직접 대화를 연결할 수 있는 개인 운동 AI 비서를 완성해보자. 이를 위해서 ChatGPT 와의 연결의 위해 필요한 HTTPS 인증서 적용과 리버스 프록시 설정을 해서, 웹에서 ChatGPT 에게 대화를 하면 내 DB 에서 정보를 가져오도록 하자!