Files
insurance/DEPLOY.md
T
chpark 035eb0259f
Build & Deploy / build-and-deploy (push) Failing after 1m56s
feat: Kubernetes 자동 배포 파이프라인 구축
- Dockerfile: Expo web export → nginx multi-stage 빌드
- nginx.conf: SPA fallback, gzip, health endpoint
- K8s manifests: namespace, deployment (2 replicas), service, ingress
- Traefik IngressRoute (선택적) 포함
- Gitea Actions workflow: push 시 빌드→Gitea Registry push→rollout restart
- DEPLOY.md: 초기 설정 가이드 (kubeconfig, secrets, DNS)

Domain: insurance.junggomoa.com

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:59:51 +09:00

6.1 KiB

🚀 배포 가이드

자동 배포 파이프라인

git push → Gitea Actions → Docker 빌드 → Container Registry → Kubernetes rollout
                                                                   ↓
                                                       insurance.junggomoa.com

📋 한 번만 해야 하는 초기 설정

1단계 — Gitea 측 설정 (웹 UI)

① Gitea Actions Runner 활성화

  1. https://git.junggomoa.com/chpark/insuranceSettings
  2. 좌측 Actions 메뉴 → Enable Actions 체크
  3. 조직/인스턴스 관리자가 Runner를 하나 등록해둬야 합니다
    • Runner 없다면 관리자에게 요청
    • 또는 Kubernetes에 act-runner Helm 차트로 직접 설치 (아래 스크립트 참고)

② Container Registry 접근 토큰 발급

  1. Gitea → 우측 상단 프로필 → SettingsApplications
  2. Generate New Token → 권한 write:package, read:package 체크
  3. 발급된 토큰 복사 (한 번만 보임)

③ Repository Secrets 등록

Repo → SettingsSecrets and VariablesActionsAdd Secret:

Name Value 설명
REGISTRY_USER chpark Gitea 사용자명
REGISTRY_TOKEN (위에서 발급한 토큰) Container Registry 인증
KUBE_CONFIG (아래 2단계에서 생성) base64 인코딩된 kubeconfig
INGRESS_MODE ingress 또는 ingressroute Traefik 설치 방식 (아래 확인)

2단계 — Kubernetes 측 설정 (서버 SSH 1회)

SSH 접속:

ssh chpark@183.99.177.40

① Traefik 설치 방식 확인

kubectl api-resources | grep -i traefik
  • 결과에 ingressroutes.traefik.io 나오면 → INGRESS_MODE=ingressroute
  • 아무것도 안 나오면 → INGRESS_MODE=ingress (표준 Ingress 사용)

② CI용 kubeconfig 생성 (서비스 어카운트 방식, 권장)

# 네임스페이스·서비스어카운트 선생성
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

# 토큰 생성 (24시간 기본, 필요 시 --duration=8760h 로 1년)
TOKEN=$(kubectl -n insurance create token gitea-deployer --duration=8760h)

# 현재 API 서버 주소
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CA=$(kubectl -n insurance get secret \
  $(kubectl -n insurance get sa gitea-deployer -o jsonpath='{.secrets[0].name}' 2>/dev/null || echo "") \
  -o jsonpath='{.data.ca\.crt}' 2>/dev/null || \
  kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')

# kubeconfig 생성
cat <<EOF > /tmp/gitea-kubeconfig
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 인코딩 → Gitea secret에 넣을 값
base64 -w0 /tmp/gitea-kubeconfig

출력된 긴 문자열을 복사해서 Gitea의 KUBE_CONFIG secret에 붙여넣으세요.

③ DNS 확인

insurance.junggomoa.com 이 k8s 클러스터의 Traefik LoadBalancer IP 로 등록돼 있어야 합니다.

dig insurance.junggomoa.com +short

IP가 안 나오거나 잘못됐다면 DNS 관리자에게 추가 요청:

  • insurance.junggomoa.com A <클러스터 LB IP>

이후부터 — 자동 배포

코드 수정 후:

git add .
git commit -m "수정 내용"
git push

Gitea Actions 탭에서 진행 상황 확인:

약 3~5분 후 https://insurance.junggomoa.com 에 새 버전 반영됩니다.


🧪 수동 1회 배포 (CI 세팅 전 테스트용)

SSH 접속 후:

# 코드 받기
git clone https://git.junggomoa.com/chpark/insurance.git
cd insurance

# 도커 이미지 빌드
docker build -t git.junggomoa.com/chpark/insurance:latest .

# 레지스트리 로그인 & push
docker login git.junggomoa.com -u chpark -p <토큰>
docker push git.junggomoa.com/chpark/insurance:latest

# K8s 시크릿 & 매니페스트 적용
kubectl apply -f deploy/k8s/namespace.yaml
kubectl -n insurance create secret docker-registry gitea-registry \
  --docker-server=git.junggomoa.com \
  --docker-username=chpark \
  --docker-password=<토큰>
kubectl apply -f deploy/k8s/deployment.yaml
kubectl apply -f deploy/k8s/service.yaml
kubectl apply -f deploy/k8s/ingress.yaml      # 또는 ingressroute-traefik.yaml

# 상태 확인
kubectl -n insurance get all
kubectl -n insurance get ingress

🔧 트러블슈팅

증상 원인 해결
ImagePullBackOff Registry 인증 실패 gitea-registry secret 재생성
404 page not found (Traefik) Ingress host 불일치 insurance.junggomoa.com 철자 확인
TLS 인증서 없음 cert-manager 미설정 관리자에게 와일드카드 인증서 요청 또는 cert-manager 설치
Actions 실패: no runner Runner 미등록 조직에 act-runner 등록 필요

로그 확인:

kubectl -n insurance logs -l app.kubernetes.io/name=insurance-web --tail=100
kubectl -n insurance describe deployment insurance-web
kubectl -n insurance describe ingress insurance-web

📁 배포 관련 파일

Dockerfile                           # Multi-stage 빌드 (Expo → nginx)
.dockerignore
.gitea/workflows/deploy.yml          # CI/CD 파이프라인
deploy/
  ├── nginx.conf                     # SPA fallback + gzip + health
  └── k8s/
      ├── namespace.yaml
      ├── deployment.yaml            # 2 replicas, rolling update
      ├── service.yaml               # ClusterIP :80
      ├── ingress.yaml               # 표준 Ingress (Traefik ingressClass)
      └── ingressroute-traefik.yaml  # Traefik CRD 버전 (선택)