728x90
반응형

자동화를 위한 CI/CD 워크플로우

1. GitHub Actions에서 ECR 리포지토리 자동 생성

GitHub Actions에서 AWS CLI 명령을 실행하여 ECR 리포지토리가 없는 경우 자동으로 생성하도록 설정합니다.

2. Docker 이미지 빌드, 태그, 푸시 자동화

GitHub Actions가 코드를 푸시할 때 Docker 이미지를 빌드하고 태그를 자동으로 생성한 뒤, AWS ECR에 푸시하도록 구성합니다.

3. ECS 배포 자동화

AWS CLI 명령어를 통해 ECS에 Task Definition을 자동으로 등록하고, 서비스 업데이트까지 진행되도록 설정합니다.

 


자동화된 GitHub Actions 워크플로우

 

프로젝트 디렉토리 경로
.github/workflows/deploy.yml

name: CI/CD Pipeline

# 1. 워크플로우 트리거 설정
# main 브랜치에 코드가 푸시될 때만 이 워크플로우가 실행됩니다.
on:
  push:
    branches:
      - main  # main 브랜치에 푸시될 때 실행

jobs:
  deploy:
    runs-on: ubuntu-latest  # 이 작업은 Ubuntu 최신 버전에서 실행됩니다.

    steps:
    # 2. GitHub 리포지토리에서 코드 체크아웃
    # 깃허브 리포지토리의 코드를 가져옵니다.
    - name: Checkout code
      uses: actions/checkout@v3

    # 3. AWS CLI 구성
    # AWS 리소스와 상호작용하기 위해 AWS CLI를 설정합니다.
    - name: Configure AWS CLI
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}  # 깃허브 액션의 Secrets에 AWS Access Key를 저장해야 함.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}  # 깃허브 액션의 Secrets에 AWS Secret Key를 저장해야 함.
        aws-region: ap-northeast-2  # 사용할 AWS 리전 (예: 서울 리전)

    # 4. ECR 리포지토리 확인 및 생성
    # Docker 이미지를 저장할 ECR 리포지토리가 존재하지 않을 경우 생성합니다.
    - name: Create ECR repository if not exists
      run: |
        REPO_NAME=my-app  # 사용할 ECR 리포지토리 이름을 정의합니다.
        # 리포지토리가 있는지 확인하고, 없으면 생성
        aws ecr describe-repositories --repository-names $REPO_NAME || \
        aws ecr create-repository --repository-name $REPO_NAME

    # 5. Amazon ECR 로그인
    # AWS ECR에 Docker CLI를 통해 로그인합니다.
    - name: Log in to Amazon ECR
      run: |
        aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.ap-northeast-2.amazonaws.com
        # `<account-id>` 부분에 AWS 계정 ID를 작성해야 합니다.

    # 6. Docker 이미지 빌드 및 ECR 푸시
    # 로컬에서 Docker 이미지를 빌드하고 ECR에 푸시합니다.
    - name: Build and push Docker image
      run: |
        IMAGE_URI=<account-id>.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest  # 푸시할 이미지의 URI
        docker build -t my-app .  # Docker 이미지 빌드
        docker tag my-app:latest $IMAGE_URI  # Docker 이미지에 태그 추가
        docker push $IMAGE_URI  # ECR에 Docker 이미지 푸시
        # `<account-id>` 부분에 AWS 계정 ID를 작성해야 합니다.

    # 7. ECS 배포
    # 새로운 Task Definition을 등록하고 ECS 서비스를 업데이트합니다.
    - name: Deploy to ECS
      run: |
        CLUSTER_NAME=my-app-cluster  # ECS 클러스터 이름
        SERVICE_NAME=my-app-service  # ECS 서비스 이름
        TASK_FAMILY=my-app-task  # ECS Task Definition 패밀리 이름

        # 기존 Task Definition 가져오기
        TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition $TASK_FAMILY)

        # Task Definition에 새로운 Docker 이미지 URI 반영
        NEW_TASK_DEFINITION=$(echo $TASK_DEFINITION | jq --arg IMAGE_URI $IMAGE_URI \
          '.taskDefinition | .containerDefinitions[0].image = $IMAGE_URI | del(.status,.taskDefinitionArn,.revision,.requiresAttributes,.compatibilities)')

        # 새로운 Task Definition JSON 파일로 저장
        echo $NEW_TASK_DEFINITION > new-task-definition.json

        # 새 Task Definition 등록 및 ARN 저장
        TASK_ARN=$(aws ecs register-task-definition --cli-input-json file://new-task-definition.json --query 'taskDefinition.taskDefinitionArn' --output text)

        # ECS 서비스 업데이트
        aws ecs update-service --cluster $CLUSTER_NAME --service $SERVICE_NAME --task-definition $TASK_ARN
        # Task Definition의 ARN이 서비스에 반영되며 새로운 컨테이너를 실행합니다.

Secrets 설정

  1. AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY를 GitHub Secrets에 추가:
    • GitHub 리포지토리 > Settings > Secrets and variables > Actions로 이동.
    • New repository secret 클릭 후 아래 키-값 쌍 추가:
      • AWS_ACCESS_KEY_ID: AWS Access Key
      • AWS_SECRET_ACCESS_KEY: AWS Secret Key

ECR 설정

  • <account-id>: AWS 계정 ID를 ECR URI에 반영해야 합니다. 예를 들어:
123456789012.dkr.ecr.ap-northeast-2.amazonaws.com
  • REPO_NAME: ECR 리포지토리 이름입니다. 위 예제에서는 my-app으로 지정.

ECS 설정

  • CLUSTER_NAME: ECS 클러스터 이름입니다. (예: my-app-cluster)
  • SERVICE_NAME: ECS 서비스 이름입니다. (예: my-app-service)
  • TASK_FAMILY: ECS Task Definition 이름입니다. (예: my-app-task)

Docker 이미지 태그

  • IMAGE_URI: AWS ECR에 푸시할 이미지의 URI입니다.
    • 형식: <account-id>.dkr.ecr.<region>.amazonaws.com/<repository-name>:<tag>
    • 예: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest
728x90
반응형
728x90
반응형

Multer는 Node.js를 위한 미들웨어로, 다중 파트(Multipart) 데이터를 처리하는 데 사용됩니다. 특히 파일 업로드와 관련해 매우 유용하며, Nest.js에서도 쉽게 통합할 수 있습니다. 아래는 Multer에 대한 개념 정리와 Nest.js 프로젝트에 적용하는 방법에 대한 예시입니다.


Multer의 개념

Multer란?

  • Multipart/form-data: HTML form 태그로 전송되는 파일 데이터를 처리하기 위한 포맷입니다. 일반적으로 파일 업로드에 사용됩니다.
  • Multer: Express.js 기반의 미들웨어로, HTTP 요청에서 multipart/form-data 데이터를 처리하는 데 특화되어 있습니다.

Multer의 주요 기능

  1. 파일 저장 위치:
    • 메모리(memoryStorage): 파일이 버퍼에 저장됩니다.
    • 디스크(diskStorage): 서버의 디스크에 파일이 저장됩니다.
  2. 파일 필터링:
    • 업로드할 파일의 유형(예: 이미지, 텍스트 파일 등)을 제한할 수 있습니다.
  3. 이름 지정:
    • 업로드된 파일의 이름을 제어할 수 있습니다.
  4. 제한 설정:
    • 업로드 파일 크기, 개수 등을 제한할 수 있습니다.
    •  

Multer를 Nest.js 프로젝트에 적용하기

1. Multer 설치

Nest.js에서 Multer를 사용하려면 관련 패키지를 설치해야 합니다:

npm install --save @nestjs/platform-express multer

2. Controller 구현

Multer를 사용하여 파일 업로드를 처리하는 컨트롤러를 작성합니다.

import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';

@Controller('upload')
export class UploadController {
  @Post()
  @UseInterceptors(
    FileInterceptor('file', {
      storage: diskStorage({
        destination: './uploads', // 파일 저장 경로
        filename: (req, file, callback) => {
          // 파일 이름 설정: 현재 시간 + 확장자
          const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
          const ext = extname(file.originalname);
          callback(null, `${uniqueSuffix}${ext}`);
        },
      }),
      limits: {
        fileSize: 5 * 1024 * 1024, // 최대 파일 크기: 5MB
      },
      fileFilter: (req, file, callback) => {
        if (!file.mimetype.match(/\/(jpg|jpeg|png|gif)$/)) {
          return callback(new Error('Only image files are allowed!'), false);
        }
        callback(null, true);
      },
    }),
  )
  uploadFile(@UploadedFile() file: Express.Multer.File) {
    console.log('Uploaded file:', file);
    return {
      message: 'File uploaded successfully!',
      file: file,
    };
  }
}

3. Module 설정

컨트롤러를 모듈에 등록합니다.
upload.module.ts

import { Module } from '@nestjs/common';
import { UploadController } from './upload.controller';

@Module({
  controllers: [UploadController],
})
export class UploadModule {}

 

app.module.ts

UploadModule을 메인 모듈에 포함시킵니다.

import { Module } from '@nestjs/common';
import { UploadModule } from './upload/upload.module';

@Module({
  imports: [UploadModule],
})
export class AppModule {}

4. 폴더 생성

업로드된 파일을 저장할 디렉토리를 생성합니다. 프로젝트 루트에 uploads 폴더를 만들어야 합니다:

/final-Project
  ├── src
  │     ├── app.module.ts
  │     ├── upload
  │           ├── upload.controller.ts
  │           ├── upload.module.ts
  ├── uploads    <-- 업로드된 파일 저장 디렉토리

 

728x90
반응형
728x90
반응형

주요 라이브러리:

  • libavcodec: 비디오 및 오디오 코덱에 대한 인코딩 및 디코딩 기능 제공
  • libavformat: 미디어 파일 형식을 다루는 기능 제공
  • libswscale: 이미지 및 비디오의 크기 조절과 색 공간 변환 기능 제공
  • libswresample: 오디오 리샘플링 및 포맷 변환 기능 제공
  • libavfilter: 비디오와 오디오 필터링 기능 제공

다양한 포맷간의 변환, 인코딩, 디코딩, 필터링, 스트리밍 등 여러 작업을 지원

 

공식 문서에서 다양한 설명 제공

import { Injectable } from '@nestjs/common';
import { exec } from 'child_process';  // 'child_process' 모듈을 사용하여 FFmpeg 명령어를 실행
import { promisify } from 'util';  // exec을 Promise 기반으로 사용하기 위해 promisify 사용

const execPromise = promisify(exec);  // exec을 Promise 방식으로 변환

@Injectable()
export class VideoService {
  // 영상 자르기 함수
  async cutVideo(inputPath: string, startTime: string, endTime: string, outputPath: string): Promise<string> {
    try {
    
    
    
      // FFmpeg 명령어 생성
      // -i: 입력 파일 경로
      // -ss: 시작 시간
      // -to: 종료 시간
      // -c copy: 비디오와 오디오 스트림을 복사하여 빠르게 처리
      // outputPath: 자른 후 저장할 파일 경로
      const command = `ffmpeg -i ${원본영상경로로} -ss ${시작 시간} -to ${종료 시간} -c copy ${저장할 경로}`;
      
      
      
      // 명령어 실행
      const { stdout, stderr } = await execPromise(command);
      //execPromise(command)는 Node.js의 child_process.exec을 Promise 기반으로 감싼 버전입니다.
	  //command는 실행할 FFmpeg 명령어로, 이 명령어는 영상 자르기 작업을 수행하게 됩니다.
      
      
      
      
      console.log('FFmpeg Output:', stdout);  // FFmpeg 실행 결과 출력
      if (stderr) {
        console.error('FFmpeg Error:', stderr);  // FFmpeg 에러 메시지 출력
      }



      // 작업 성공 시 반환 메시지
      return `Video cut successfully from ${startTime} to ${endTime}. Output: ${outputPath}`;
    } catch (error) {
      console.error('Error cutting video:', error);  // 에러 발생 시 로그 출력
      throw new Error('Failed to cut video');  // 에러 발생 시 예외 처리
    }
  }
}
728x90
반응형
728x90
반응형
 
1일차: 프로젝트 주제 선정

오늘은 팀원들과 함께 프로젝트 주제를 정하는 시간을 가졌습니다. 여러 아이디어가 나왔지만, 결국 모두가 흥미를 느끼고 참여할 수 있는 주제로 합의했어요. 주제에 맞춰 요즘 많은 회사들이 사용하는 최신 기술 스택들을 조사하고, 이번 프로젝트에 적절히 녹여낼 계획입니다. 이를 통해 우리 프로젝트가 실무적인 트렌드도 반영할 수 있도록 하려고 해요.
1일차) 협업툴**노션**을 활용해서 프로젝트 계획하기


2일차: 필요한 기능 정의와 기술 스택 정리

**노션**페이지에 필요한 기능들 정리

오늘은 우리가 정한 주제에 맞춰서 필요한 기능들을 정의하고, 각 기능을 구현하기 위해 어떤 기술이 필요한지 분석해봤어요. 이 과정에서 각 기능마다 필요한 라이브러리나 프레임워크도 함께 정리했는데, 무작정 사용하기보다는 그 필요성을 꼼꼼히 따져보려고 해요.

 

왜 따져봐야 할까요.

 

라이브러리나 프레임워크는 프로젝트의 속도를 올릴 수 있지만, 너무 많이 쓰면 오히려 코드가 복잡해지고 관리도 어려워져요. 그래서 꼭 필요한 경우에만 사용하기로 했습니다. 필요한 경우에는 이걸 왜 쓰는지, 장점은 무엇인지, 사용하지 않으면 어떤 점이 불편해질지까지 생각해보면, 시간이나 비용 면에서도 더 나은 선택을 할 수 있을 것 같거든요.

노션에 이 모든 내용들을 정리해서 앞으로도 참고하려고 해요.


 

영상 편집 에디터 페이지 구현 고려

이번 프로젝트에서 영상을 주제로 다루다 보니, 사용자 경험을 높이기 위해 영상 편집 에디터 페이지를 구현할 수 있을지 고민하게 되었어요. 그 과정에서 가장 필요한 프레임워크로 FFmpeg가 있다는걸 발견했습니다.

 

FFmpeg는 다양한 라이브러리를 제공하여 영상 편집 기능을 구현하는 데 큰 도움을 줄 수 있습니다. 주요 라이브러리로는 다음이 있어요:

  • libavcodec: 비디오와 오디오 코덱의 인코딩 및 디코딩 기능을 제공
  • libavformat: 다양한 미디어 파일 형식을 다루는 기능 제공
  • libswscale: 이미지와 비디오의 크기 조절 및 색 공간 변환 기능 제공
  • libswresample: 오디오 리샘플링 및 포맷 변환 기능 제공
  • libavfilter: 비디오와 오디오 필터링을 위한 기능 제공

이 라이브러리들을 잘 활용하면 영상 편집 에디터 페이지도 충분히 구현할 수 있을 것 같아요. 다음 게시글에서는 FFmpeg의 자세한 기능과 사용법에 대해 다루면서, 어떻게 프로젝트에 적용할 수 있을지 구체적으로 살펴보겠습니다!

728x90
반응형
728x90
반응형

이번 프로젝트에서는 다양한 협업툴을 사용하여 효율적으로 작업을 진행할 예정입니다. 주요 협업툴로는 깃허브, 라이브쉐어, , 노션 등이 있습니다. 그 중 오늘은 **노션(Notion)** 을 어떤식으로 사용해서 프로젝트를 진행할 것인지에 대해
이야기 해보려합니다.

우선 노션 홈페이지에서 체인트 투게더라는 팀명으로 페이지를 만들었습니다.


1. 노션을 통한 협업 계획 

**노션(Notion)**을 활용해서 팀 내 기획, 회의록, 와이어프레임, API 명세서, ERD 작성 등 다양한 문서 작업을 체계적으로 관리할 예정입니다. 이를 활용하여 프로젝트 전반의 흐름을 관리하고, 각 구성원들이 실시간으로 업데이트와 수정 사항을 공유할 수 있습니다.


2. 노션 활용 분야

  • 기획: 10초 길이의 짧은 영상을 올리고 볼수있는 틱톡?같은 웹페이지를 만들기로 했습니다

  • 회의록 작성: 매일 회의를 시작할 시간을 정하고, 노션에 회의록을 남겨 모든 팀원들이 언제든지 회의 내용을 쉽게 확인할 수 있도록 했습니다.

  • 와이어프레임: 저희는 피그마를 사용해서 초기 UI/UX 디자인을 도식화하여 프로젝트의 방향성을 잡았습니다.

  • 기술 스택 및 기능 정리: 개발에 필요한 기술 스택과 주요 기능들을 정리하여 팀원들이 어떤 기술을 사용하고 어떤 기능을 개발해야 하는지 명확히 정리할 예정입니다

이 외에도

  • API 명세서: 프로젝트에 필요한 API의 설계와 규격을 명확히 정리할수 있습니다.
  • ERD: 데이터베이스 설계를 시각적으로 정리하여 데이터 구조를 명확히 합니다.
  • 개발 목표 캘린더: 프로젝트의 일정을 관리하고, 각 목표를 달성할 수 있는 계획을 수립합니다.

이러한 모든 내용들은 노션에 정리하고, 이를 바탕으로 본격적인 개발을 시작할 예정입니다.

노션을 사용하면 프로젝트의 전반적인 내용을 한 곳에 모을 수 있어, 개발을 진행하면서 언제든지 필요한 정보를 쉽게 확인할 수 있는 유용한 문서가 될 것입니다.


 

728x90
반응형

+ Recent posts