Skip to content

Repository files navigation

final_main

🛫 기존에 경험하지 못한, 새로운 여행 플래너 !
고민만 하던 여행 계획을 WANT 와 함께 한 번에 스케줄링 해보세요 !



🚣🏻‍♀️ 팀원 소개


팀장 : 전상민


팀원 : 김지은


팀원 : 최아영


팀원 : 표웅기




🛫 WANT 프로젝트 소개

 
코로나19 이후, 여행의 패턴과 요구가 크게 변화했습니다.
사람들은 안전하고 개인화(맞춤화)된 여행을 원하며, 이에 따라 여행 계획을 세우는 데 있어 보다 세심한 접근을 요구하고 있습니다.
이러한 변화에 맞춰 개인화된 여행 플래너 WANT 는 여행자들이 더 나은 경험을 할 수 있도록 도와줍니다.



📚 기술 스택

DB

Backend

Frontend

Devops




⚙️ WBS

WANT_WBS

📋 WANT WBS 확인하기


⚙️ 요구사항 명세서

WANT_WBS

📋 WANT 요구사항 명세서 확인하기


⚙️ ERD CLOUD

스크린샷 2024-08-21 오전 9 15 22


📡 배포 Architecture

🗞️ CI / CD 설계도

image

📋 K8S BACKEND SCRIPT

hpa.yml
# 메트릭 서버 설치 (파드의 자원상황 모니터링 툴)
# kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Horizontal pod autoscaler (수평확장)
# 컨테이너 자동 확장
#  10분이 지나고 나서 부하가 없을시에 자동으로 기본 POD 대수로 돌아옴
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
# 어떤 상황에 어떤것을 늘릴지 정해야함
metadata:
  name: want-hpa

spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: want-deployment
  minReplicas: 2
  maxReplicas: 4
  # CPU 사용률이 50% 넘어가면 실행
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
          
# 부하 테스트 쉘스크립트
# kubctl exec -it 파드명 /bin/bash -n sm
# while true; do curl http://ordersystem-service/product/list; sleep 1; done

# 부하 모니터링
# -w : whatch 옵션을 의미
# kubectl get hpa ordersystem-hpa -n sm -w 
want_depl.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: want-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: want
  template:
    metadata:
      labels:
        app: want
    spec:
      containers:
        - name: want
          # AWS의 ECR를 사용 
          image: 346903264902.dkr.ecr.ap-northeast-2.amazonaws.com/want:latest
          ports: 
            - containerPort: 8088
          resources:
            limits: # 최대 할당량
              cpu: "0.75"
              memory: "600Mi"
            requests: # 최소 할당량
              cpu: "0.25"
              memory: "250Mi"
          env:
            - name: local.redis.host
              valueFrom:
                secretKeyRef:
                  key: local.redis.host
                  name: want-secrets
            - name: cloud.aws.s3.bucket
              valueFrom:
                secretKeyRef:
                  key: cloud.aws.s3.bucket
                  name: want-secrets
            - name: google.client-id
              valueFrom:
                secretKeyRef:
                  key: google.client-id

          # 무중단 배포를 위한 컨테이너 health check
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8088
          # 컨테이너 시작후 지연시간 설정
            initialDelaySeconds: 10
          # 확인 반복 주기
            periodSeconds: 10
          # 요청 timeout 설정
            timeoutSeconds: 1
          # 성공 인식 횟수 설정
            successThreshold: 1
          # 연속 실패 횟수 설정 : 연속적으로 3번을 실패하면 건강하지 않은 상태로 판단하여 기존 서버 종료시키지 않음
            failureThreshold: 3
certificate.yml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
   # 인증서 서버 주소. 해당 서버의 리소스를 통해 인증서 발행
    server: https://acme-v02.api.letsencrypt.org/directory
    #인증서의 사용자
    email: jsangmin99@gmail.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx

# 3. Certificate 생성
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: -
spec:
  secretName: -
  duration: 2160h  # 90일동안 유효함
  renewBefore: 360h # 15일 전에 갱신된다.
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: -
  dnsNames:
  - s-
want_ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: want-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - server.abs.co.kr
    secretName: abc-tls
  rules:
    - host: server.avs.co.kr
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: want-service
                port:
                  number: 80
want_service.yml
apiVersion: v1
kind: Service
metadata:
  name: want-service
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 80 # service Port를 의미,
      targetPort: 8088 #service가 라우팅해줄 대상의 port
  selector:
    app: want
deploy_want_k8s.yml
name: deploy_want_k8s
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '11'

      - name: Cache Gradle Wrapper and JIB Cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper

      - name: install kubctl
        uses: azure/setup-kubectl@v3
        with:
          version: 'v1.26.0'
        id: install

      - name: Configure AWS credentials
        uses: confis-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: update cluster information
        run: aws eks update-kubeconfig --name 5-team-cluster --region ap-northeast-2

      - name: login to ECR
        id: login-ecr
        uses: aab@v1

      - name: Build, tag, and push image to Amazon ECR with Jib
        run: |
          ./gradlew :abc.ecr.ap-northeast-2.amazonaws.com/want:latest

      - name: kubectl apply
        run: |
          kubectl apply -f ./k8s/want_depl.yml
          kubectl rollout restart deployment want-deployment

📋 S3 FRONTEND SCRIPT

deploy_s3.yml
name: deploy to aws s3
# 1. 트리거 생성(main브랜치에 push 될때 현재 스크립트 실행 트리거 발동)
on:
  push:
    branches:
      - main
# 워크플로우는 하나 이상의 작업(job)으로 구성, 여기서는 하나의 작업만을 정의 (job의 이름 은 사용자 맘대로)
jobs:
  build-and-deploy:
    runs-on : ubuntu-latest
    # 각 작업은  여러 step(단계)로 구성
    steps:
    # actions 는 github에서 제공되는 공식 워크플로우
    # chekout은 현재 repo의 main브랜치 소스코드를 카피
      - name: source code checkout
        uses: actions/checkout@v2
# 2.  노드 설치
      - name: setup node jobs
        uses: actions/setup-node@v2
        with: 
          node-version: '20'

      - name: Create .env file
        run: |
          echo "VUE_APP_API_BASE_URL=${{ secrets.VUE_APP_API }}" >> .env
          echo "VUE_APP_GOOGLE_CLIENT_ID=${{ secrets.VUE_APP_GOOGLE }}" >> .env
          echo "VUE_APP_GOOGLE_REDIRECT_URI=${{ secrets.VUE_APP_REDIRECT_URI }}" >> .env
          echo "VUE_APP_GOOGLE_MAPS_API_KEY=${{ secrets.VUE_APP_API_KEY }}" >> .env
  
# 3. npm install
      - name: npm install
        working-directory: .
        run: npm install
# 4. npm build
      - name: npm buildwer
        working-directory: .
        run: npm run build
      
      - name: setup aws cli
        uses: aavs-aws-credentials@v2
        with:
          aws-access-key-id: ${{secrets.AWS_ACESS_KEY}}
          aws-secret-access-key: ${{secrets.AWS_SECRET}}
          aws-region: ap-northeast-2

      - name: clear s3 bucket
        run: aws s3 rm s3://want.devhot.kr/ --recursive

      - name: upload file in s3 bucket
        run: aws s3 cp ./dist s3://want.devhot.kr/ --recursive
      

      - name: invalidate cloudfront cache
        run: aws cloudfront create-invalidation --distribution-id ${{secrets.DISTRIBUTION_ID}} --paths "/*"

🐳 docker-compose

docker-copmose.yml
name: CI/CD Pipeline  
  
on:  
  push:  
    branches:  
      - dev  
  
jobs:  
  build:  
    runs-on: ubuntu-latest  
  
    steps:  
  
      - name: Checkout code  
        uses: actions/checkout@v2  
  
      - name: Set up JDK 11  
        uses: actions/setup-java@v2  
        with:  
          java-version: '11'  
          distribution: 'temurin'  
  
  
      - name: Cache Gradle packages  
        uses: actions/cache@v3  
        with:  
          path: ~/.gradle/caches  
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}  
          restore-keys: |  
            ${{ runner.os }}-gradle-  
      - name: Cache Docker layers  
        uses: actions/cache@v3  
        with:  
          path: /home/runner/.cache/docker  
          key: ${{ runner.os }}-docker-${{ github.sha }}  
          restore-keys: |  
            ${{ runner.os }}-docker-  
      - name: Docker Hub login  
        uses: docker/login-action@v2  
        with:  
          username: ${{ secrets.DOCKER_USERNAME }}  
          password: ${{ secrets.DOCKER_PASSWORD }}  
  
      - name: Build with Jib  
        run: ./gradlew jib --image=j00/want_project:latest  
  
  
  
  deploy:  
    runs-on: ubuntu-latest  
    needs: build  
  
    steps:  
      - name: SSH to EC2  
        uses: appleboy/ssh-action@v0.1.10  
        with:  
          host: ${{ secrets.EC2_HOST }}  
          username: ubuntu  
          key: ${{ secrets.EC2_SSH_KEY }}  
          port: 22  
          script: |  
            cd ~/want            if ! type docker > /dev/null; then              sudo snap install docker || echo "docker install failed"            else              echo "docker is already installed"            fi            sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}            chmod +x deploy.sh            ./deploy.sh %% jsn00/want_project:latest %%


📑 테스트 결과

🧪 배포 환경 서비스 확인

want.devhot.kr 주소창 확인 ✅

전체 서비스 둘러보기 블럭 가져가기

🧪 메인 페이지 관련 기능 테스트

소셜 로그인 / 로그아웃
  • 구글 API 를 이용한 로그인 서비스
  • 여행지, 날짜, 제목 작성 후 일정 생성

🧪 마이 페이지 관련 기능 테스트

일정 조회 / 일정 탈퇴
  • 목록에서 일정 조회 / 조회된 일정 탈퇴

🧪 추천 페이지 관련 기능 테스트

인기 여행지 조회 및 명소 스크랩
  • 사용자들이 많이 등록한 도시별로 조회
  • 내 일정으로 추천 명소 스크랩

🧪 일정 페이지 관련 기능 테스트

일정 초대 및 일정 탈퇴 / 일정 경로 조회
  • 일정에 없는 회원 이메일로 멤버 초대
  • 소속된 일정에서 탈퇴하기
일정 경로 조회
  • 상단 지도 아이콘 클릭 시 해당 일정의 경로 표시
스케줄러 Drag & Drop
  • 스케줄러에서 리스트로 블럭 이동 (일정 해제)
  • 리스트에서 스케줄러로 블럭 이동 (일정 등록)

🧪 블럭 관련 기능 테스트

블럭 상세페이지 연결
  • 스케줄러에 등록된 블럭 클릭 시 상세 페이지로 이동
  • 리스트에서 등록된 블럭 클릭 시 상세 페이지로 이동
블럭에 사진 등록
  • 블럭에 사진 등록 / 여러장 등록 시 슬라이더 처리
GoogleMap 연동
  • GoogleMap 을 통해 장소 지정 및 확인
댓글 달기, 좋아요 달기
  • 같은 프로젝트 팀원과 댓글, 좋아요 기능 연동
블럭 상세 정보 수정 및 블럭 삭제 가능
  • 블럭 상세 페이지에서 편집
  • 블럭 상세 페이지에서 삭제

About

[WANT] What a Nice Trip 여행 일정 서비스

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages