로컬에서 AI API 서버를 구축하고 싶은데, 환경 설정에서 매번 막히시나요? 이 튜토리얼은 Docker Compose를 사용하여 안정적인 로컬 AI API 개발 환경을 몇 분 만에 구축하는 방법을 알려드립니다. 특히 ConnectionError, 401 Unauthorized, rate limit 등의 실제 개발 현장에서 자주 마주치는 오류들을 선제적으로 방지하는 설정까지 다룹니다.
왜 Docker Compose인가?
AI API 개발 환경을 로컬에 구축하면 여러 가지 이점이 있습니다:
- 비용 절감: 개발 단계에서 API 호출 비용 최소화
- 오프라인 개발: 네트워크 환경에 의존하지 않는 개발
- 빠른 반복: 로컬에서 즉시 테스트 및 디버깅 가능
- 일관된 환경: 팀원들과 동일한 개발 환경 공유
사전 준비물
- Docker Desktop (버전 20.10 이상)
- Docker Compose (버전 2.0 이상)
- HolySheep AI API 키 (지금 가입하고 무료 크레딧 받기)
프로젝트 구조 생성
먼저 프로젝트 디렉토리를 만들고 필요한 파일들을 설정합니다.
# 프로젝트 디렉토리 생성
mkdir ai-api-local-dev
cd ai-api-local-dev
디렉토리 구조 생성
mkdir -p proxy logs cache
touch .env
docker-compose.yml 작성
AI API 리버스 프록시 서버와 관련 서비스를 설정합니다. Nginx를 활용한 안정적인 프록시 환경 구축이 핵심입니다.
version: '3.8'
services:
# Nginx 리버스 프록시
nginx:
image: nginx:alpine
container_name: ai-api-proxy
ports:
- "8080:80"
- "8443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./logs:/var/log/nginx
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
networks:
- ai-network
restart: unless-stopped
# API 캐시 레이어 (선택사항)
redis:
image: redis:7-alpine
container_name: ai-cache
ports:
- "6379:6379"
volumes:
- ./cache:/data
networks:
- ai-network
restart: unless-stopped
command: redis-server --appendonly yes
# 로컬 개발용 Mock API (개발 전용)
mock-api:
image: mockserver/mockserver:5.15.0
container_name: ai-mock-server
ports:
- "1080:1080"
environment:
- MOCKSERVER_INITIALIZATION_JSON_PATH=/config/mockserver.json
volumes:
- ./mock-config.json:/config/mockserver.json:ro
networks:
- ai-network
profiles:
- development
networks:
ai-network:
driver: bridge
Nginx 설정 파일
AI API 요청을 HolySheep AI로 프록시하면서 로깅과 캐싱을 설정합니다.
events {
worker_connections 1024;
}
http {
# 로깅 포맷 설정
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# 버퍼 설정
client_body_buffer_size 16k;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
# 타임아웃 설정
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 90s;
# Gzip 압축
gzip on;
gzip_types application/json text/plain;
server {
listen 80;
server_name localhost;
# HolySheep AI API 프록시 설정
location /v1/ {
# 실제 환경에서는 HolySheep AI 주소로 변경
proxy_pass https://api.holysheep.ai/v1/;
proxy_http_version 1.1;
proxy_set_header Host api.holysheep.ai;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# HolySheep AI API 키 헤더
proxy_set_header Authorization "Bearer ${HOLYSHEEP_API_KEY}";
# CORS 헤더
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
# Preflight 요청 처리
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
# 헬스체크 엔드포인트
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
Python 클라이언트 설정
이제 HolySheep AI API를 호출하는 Python 클라이언트를 만들어 보겠습니다. 이 설정으로 401 Unauthorized 오류를 방지할 수 있습니다.
# requirements.txt
openai==1.12.0
python-dotenv==1.0.0
httpx==0.26.0
api_client.py
import os
from dotenv import load_dotenv
from openai import OpenAI
.env 파일에서 API 키 로드
load_dotenv()
HolySheep AI 클라이언트 설정
client = OpenAI(
api_key=os.getenv("HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1", # 절대 api.openai.com 사용 금지
timeout=120.0, # 요청 타임아웃 설정
max_retries=3 # 자동 재시도 설정
)
def test_chat_completion():
"""ChatGPT 스타일 API 호출 테스트"""
try:
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": "당신은 도움이 되는 AI 어시스턴트입니다."},
{"role": "user", "content": "안녕하세요! 간단한 자기소개를 해주세요."}
],
temperature=0.7,
max_tokens=500
)
print("✅ API 호출 성공!")
print(f"모델: {response.model}")
print(f"응답: {response.choices[0].message.content}")
print(f"사용량: {response.usage}")
return response
except Exception as e:
print(f"❌ API 호출 실패: {type(e).__name__}")
print(f"오류 메시지: {str(e)}")
raise
if __name__ == "__main__":
test_chat_completion()
.env 파일 설정
# HolySheep AI API 키 (.env 파일)
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
Nginx 설정에서 사용할 변수
NGINX_HOST=localhost
NGINX_PORT=80
Redis 캐시 설정
REDIS_HOST=ai-cache
REDIS_PORT=6379
개발 환경 실행
# Docker Compose로 모든 서비스 시작
docker-compose up -d
서비스 상태 확인
docker-compose ps
로그 확인
docker-compose logs -f nginx
헬스체크
curl http://localhost:8080/health
Mock 서버 설정 (선택)
개발 단계에서 실제 API 호출 없이 테스트하려면 Mock 서버를 사용하세요.
# mock-config.json
{
"httpRequest": {
"method": "POST",
"path": "/v1/chat/completions"
},
"httpResponse": {
"statusCode": 200,
"headers": {
"Content-Type": ["application/json"]
},
"body": {
"id": "chatcmpl-mock-123",
"object": "chat.completion",
"created": 1234567890,
"model": "gpt-4.1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "안녕하세요! Mock 서버에서 응답하고 있습니다. 실제 API 키를 설정하면 HolySheep AI에서 실시간 응답을 받을 수 있습니다."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 50,
"total_tokens": 70
}
},
"delay": {
"timeUnit": "MILLISECONDS",
"value": 100
}
}
}
# Mock 서버 포함하여 실행
docker-compose --profile development up -d mock-api
Mock 서버 로그 확인
docker-compose logs -f mock-api
로컬 vs HolySheep AI 연결 테스트
# test_connection.py
import os
import httpx
from dotenv import load_dotenv
load_dotenv()
def test_local_proxy():
"""로컬 Nginx 프록시 연결 테스트"""
print("=== 로컬 프록시 테스트 ===")
try:
response = httpx.get("http://localhost:8080/health", timeout=10)
print(f"✅ 로컬 프록시 연결 성공: {response.status_code}")
except Exception as e:
print(f"❌ 로컬 프록시 연결 실패: {e}")
def test_direct_holysheep():
"""HolySheep AI 직접 연결 테스트"""
print("\n=== HolySheep AI 직접 연결 테스트 ===")
api_key = os.getenv("HOLYSHEEP_API_KEY")
if not api_key or api_key == "YOUR_HOLYSHEEP_API_KEY":
print("⚠️ HolySheep API 키가 설정되지 않았습니다.")
print(" .env 파일에 API 키를 설정하세요.")
print(" https://holysheep.ai/register 에서 무료 크레딧을 받으세요!")
return
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4.1",
"messages": [
{"role": "user", "content": "테스트 메시지"}
],
"max_tokens": 10
}
try:
with httpx.Client(timeout=30) as client:
response = client.post(
"https://api.holysheep.ai/v1/chat/completions",
headers=headers,
json=payload
)
if response.status_code == 200:
print("✅ HolySheep AI 연결 성공!")
print(f" 응답: {response.json()}")
elif response.status_code == 401:
print("❌ 401 Unauthorized 오류")
print(" API 키를 확인하거나 새로 생성하세요.")
elif response.status_code == 429:
print("⚠️ Rate limit 초과")
print(" 잠시 후 다시 시도하거나 요금제를 확인하세요.")
else:
print(f"❌ 오류 발생: {response.status_code}")
print(f" {response.text}")
except httpx.TimeoutException:
print("❌ ConnectionError: 타임아웃 발생")
print(" 네트워크 연결을 확인하세요.")
except Exception as e:
print(f"❌ 예상치 못한 오류: {e}")
if __name__ == "__main__":
test_local_proxy()
test_direct_holysheep()
자주 발생하는 오류 해결
1. ConnectionError: timeout 오류
원인: 네트워크 연결 문제 또는 API 서버 응답 지연
# 해결 방법 1: 타임아웃 시간 증가
client = OpenAI(
api_key=api_key,
base_url="https://api.holysheep.ai/v1",
timeout=180.0, # 3분으로 증가
max_retries=5 # 재시도 횟수 증가
)
해결 방법 2: httpx 클라이언트로 세밀한 제어
from httpx import Timeout
timeout = Timeout(
connect=30.0,
read=120.0,
write=30.0,
pool=30.0
)
client = OpenAI(api_key=api_key, timeout=timeout)
2. 401 Unauthorized 오류
원인: API 키 누락, 잘못된 키, 만료된 키
# 해결 방법: 키 검증 및 디버깅
import os
def validate_api_key():
api_key = os.getenv("HOLYSHEEP_API_KEY")
# 키 형식 검증
if not api_key:
raise ValueError("HOLYSHEEP_API_KEY 환경 변수가 설정되지 않았습니다.")
if api_key == "YOUR_HOLYSHEEP_API_KEY":
raise ValueError(
"기본값이 그대로 사용되고 있습니다. "
"https://holysheep.ai/register 에서 실제 API 키를 발급받아 "
".env 파일에 설정하세요."
)
# HolySheep AI 키 형식 검증 (sk-hs-로 시작)
if not api_key.startswith("sk-hs-"):
print("⚠️ HolySheep AI 키 형식이 다릅니다.")
print(f" 현재: {api_key[:10]}...")
print(" 올바른 형식: sk-hs-...")
return api_key
사용
api_key = validate_api_key()
print(f"✅ API 키 검증 완료: {api_key[:10]}...")
3. Rate Limit 초과 (429 오류)
원인: 짧은 시간内有太多 요청
# 해결 방법: 요청 간격 조절 및 재시도 로직
import time
import asyncio
from openai import RateLimitError
def request_with_retry(client, payload, max_retries=3):
"""지수 백오프로 재시도하는 요청 함수"""
for attempt in range(max_retries):
try:
response = client.chat.completions.create(**payload)
return response
except RateLimitError as e:
wait_time = 2 ** attempt # 1초, 2초, 4초...
print(f"⚠️ Rate limit 초과. {wait_time}초 후 재시도... ({attempt+1}/{max_retries})")
time.sleep(wait_time)
except Exception as e:
print(f"❌ 오류 발생: {e}")
raise
raise Exception("최대 재시도 횟수 초과")
사용 예시
payload = {
"model": "gpt-4.1",
"messages": [{"role": "user", "content": "안녕하세요"}]
}
response = request_with_retry(client, payload)
4. CORS 에러 (프론트엔드 연동 시)
원인: 브라우저의 크로스 오리진 요청 차단
# 해결: Nginx CORS 설정 확인
nginx.conf의 location 블록에 다음 헤더 추가
location /v1/ {
proxy_pass https://api.holysheep.ai/v1/