f78949c21a
Build & Deploy / build-and-deploy (push) Failing after 9s
Backend (server/): - Fastify + Prisma + PostgreSQL 16 - JWT 인증 (bcrypt) + 카카오 OAuth (/auth/kakao — kapi.kakao.com 호출) - REST API: auth, users, family, policies, claims, score, notifications, diagnosis, consults - 실제 보험점수 알고리즘 (카테고리별 가중치·최소보장 기반) - Multipart 업로드 (영수증/진단서 → 디스크 persistence) - Swagger UI /docs Client: - api/client.ts + api/endpoints.ts (fetch 래퍼 + AsyncStorage 토큰) - 인증 스토어 (hydrate/login/register/kakao/logout) - 로그인/회원가입 화면 + 카카오 버튼 - 홈/내보험/가족/점수/청구 API 연동 (pull-to-refresh) - 보험 추가 모달 + 가족 구성원 추가 모달 - 로그인 전/후 스택 분기 (RootNavigator) Infra: - docker-compose.yml (로컬 Postgres+API) - server/Dockerfile (Prisma migrate deploy + node) - deploy/k8s/postgres.yaml (StatefulSet + 10Gi PVC) - deploy/k8s/api.yaml (Deployment + Ingress api.insurance.junggomoa.com) - CI workflow 확장 (web + api 동시 빌드·배포) - POSTGRES_PASSWORD / JWT_SECRET Gitea Secrets 추가 필요 - 반응형 웹 레이아웃 (max-width 480px 폰 프레임) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
140 lines
4.6 KiB
Markdown
140 lines
4.6 KiB
Markdown
# 🚀 배포 가이드 (Full Stack)
|
|
|
|
```
|
|
git push → Gitea Actions
|
|
├─ Web Docker build → insurance.junggomoa.com (nginx)
|
|
├─ API Docker build → api.insurance.junggomoa.com (Fastify)
|
|
└─ Postgres StatefulSet (10Gi PVC)
|
|
```
|
|
|
|
## ☑ 한 번만 설정 (Gitea Repo Secrets)
|
|
|
|
[https://git.junggomoa.com/chpark/insurance/settings/actions/secrets](https://git.junggomoa.com/chpark/insurance/settings/actions/secrets)
|
|
|
|
| Secret | 값 | 비고 |
|
|
|---|---|---|
|
|
| `REGISTRY_USER` | `chpark` | Gitea 사용자명 |
|
|
| `REGISTRY_TOKEN` | (Gitea → Settings → Applications → Generate Token, `write:package` 체크) | |
|
|
| `KUBE_CONFIG` | 서버에서 생성한 base64 kubeconfig | 아래 스크립트 참고 |
|
|
| `POSTGRES_PASSWORD` | 임의의 강한 비밀번호 (예: `openssl rand -hex 24`) | DB 비번 |
|
|
| `JWT_SECRET` | 임의의 32자 이상 랜덤 문자열 (`openssl rand -hex 32`) | JWT 서명키 |
|
|
| `INGRESS_MODE` | `ingress` 또는 `ingressroute` | Traefik 버전 |
|
|
|
|
## 🔑 kubeconfig 생성 (서버에서 한 번만)
|
|
|
|
```bash
|
|
ssh chpark@183.99.177.40
|
|
kubectl create namespace insurance 2>/dev/null || true
|
|
kubectl -n insurance create serviceaccount gitea-deployer
|
|
kubectl create clusterrolebinding gitea-deployer \
|
|
--clusterrole=cluster-admin \
|
|
--serviceaccount=insurance:gitea-deployer
|
|
|
|
TOKEN=$(kubectl -n insurance create token gitea-deployer --duration=8760h)
|
|
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
|
|
CA=$(kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
|
|
|
|
cat > /tmp/gitea-kubeconfig <<EOF
|
|
apiVersion: v1
|
|
kind: Config
|
|
clusters:
|
|
- cluster:
|
|
server: ${SERVER}
|
|
certificate-authority-data: ${CA}
|
|
name: cluster
|
|
contexts:
|
|
- context:
|
|
cluster: cluster
|
|
user: gitea-deployer
|
|
namespace: insurance
|
|
name: default
|
|
current-context: default
|
|
users:
|
|
- name: gitea-deployer
|
|
user:
|
|
token: ${TOKEN}
|
|
EOF
|
|
|
|
base64 -w0 /tmp/gitea-kubeconfig
|
|
```
|
|
|
|
출력된 긴 문자열 → `KUBE_CONFIG` 시크릿에 붙여넣기.
|
|
|
|
## 🌐 DNS
|
|
|
|
A 레코드 2개 필요:
|
|
- `insurance.junggomoa.com` → Traefik LoadBalancer IP
|
|
- `api.insurance.junggomoa.com` → Traefik LoadBalancer IP
|
|
|
|
## 💻 로컬 개발 (docker-compose)
|
|
|
|
```bash
|
|
# 1. 서버 의존성 + DB 기동
|
|
cd server
|
|
npm install
|
|
cd ..
|
|
docker compose up -d postgres
|
|
|
|
# 2. Prisma 마이그레이션
|
|
cd server
|
|
cp .env.example .env
|
|
npx prisma migrate dev --name init
|
|
npm run dev # → http://localhost:4000 (Swagger: /docs)
|
|
|
|
# 3. 다른 터미널에서 모바일/웹 클라이언트
|
|
cd ..
|
|
npm run web # → http://localhost:8081
|
|
# 브라우저에서 API 가 localhost:4000 에 붙도록 자동 기본값 동작
|
|
```
|
|
|
|
## 🧪 API 스모크 테스트
|
|
|
|
```bash
|
|
# 회원가입
|
|
curl -X POST http://localhost:4000/auth/register \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"test@test.com","password":"password123","name":"박철현","age":34,"gender":"MALE","job":"사무직"}'
|
|
|
|
# 로그인
|
|
curl -X POST http://localhost:4000/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"test@test.com","password":"password123"}'
|
|
|
|
# 카카오 로그인 (카카오 SDK에서 받은 access_token 필요)
|
|
curl -X POST http://localhost:4000/auth/kakao \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"accessToken":"YOUR_KAKAO_ACCESS_TOKEN"}'
|
|
```
|
|
|
|
## 📦 카카오 로그인 연동
|
|
|
|
### 백엔드
|
|
- `POST /auth/kakao` 엔드포인트가 `access_token`을 받아 `https://kapi.kakao.com/v2/user/me` 호출 → 프로필 매핑 → JWT 발급
|
|
|
|
### 클라이언트
|
|
현재 웹에서는 개발용 `window.prompt`로 토큰 붙여넣기 지원. 실제 운영에서는:
|
|
- **Web**: Kakao JS SDK 로 `Kakao.Auth.login()` 호출 → `access_token` 획득 → `/auth/kakao`
|
|
- **Native (iOS/Android)**: `@react-native-seoul/kakao-login` — `bare workflow`로 prebuild 후 연동
|
|
|
|
### 필요한 Kakao Developer 설정
|
|
1. https://developers.kakao.com/ 앱 생성
|
|
2. 플랫폼: Web (도메인 등록: `https://insurance.junggomoa.com`), Android/iOS 별도
|
|
3. 카카오 로그인 → Redirect URI: `https://insurance.junggomoa.com/auth/kakao/callback`
|
|
4. 동의항목: 닉네임(필수), 프로필 이미지(선택), 이메일(선택)
|
|
|
|
## 🛠 트러블슈팅
|
|
|
|
```bash
|
|
# Pod 로그
|
|
kubectl -n insurance logs -l app.kubernetes.io/name=insurance-api --tail=100
|
|
|
|
# DB 접속
|
|
kubectl -n insurance exec -it postgres-0 -- psql -U insurance
|
|
|
|
# 마이그레이션 수동 실행
|
|
kubectl -n insurance exec -it deploy/insurance-api -- npx prisma migrate deploy
|
|
|
|
# 이미지 재배포
|
|
kubectl -n insurance rollout restart deployment/insurance-api deployment/insurance-web
|
|
```
|