React 웹 앱의 AWS에 배포 스크립트를 만든 시행 착오 과정

시스템 구성도





시스템 구성


  • React 소스 코드는 S3 Backet에 업로드
  • Backet은 CloudFront를 통해 게시합니다
  • 스테이징 환경과 프로덕션 환경이 있다


  • 하고 싶은 일



    불행히도 CI는 도입되지 않았으므로 수동으로 배포해야합니다.
    스테이징 환경과 프로덕션 환경에 배포를 가능한 한 단순화하고 싶습니다.

    지금까지 수동으로 한 일


  • API의 방향을 변경하여 npm run build
  • 해당 S3 버킷에 build한 파일을 업로드
  • CloudFront 캐시 비활성화
  • 이것을 production 과 staging 로 실시


  • 하나씩 스크립트화해 간다!



    지금까지 수동으로 한 일


  • API의 방향을 변경하여 npm run build
  • 해당 S3 버킷에 build한 파일을 업로드
  • CloudFront 캐시 비활성화
  • 이것을 production 과 staging 로 실시


  • React 빌드시 .env 파일 간 전환


  • npm-scripts에 prebuild를 정의하고 .env 파일을 바꿉니다.
  • 에서 postbuild로 실행 취소

  • 아무튼 움직였다

    env-cmd



    나중에 공식 문서를 보면 그 자체로 즐거움이 있습니다.

    Deployment · Create React App
    Customizing Environment Variables for Arbitrary Build Environments
    (모든 빌드 환경에 대한 환경 변수 사용자 정의)

    For example, to create a build environment for a staging environment:


    어떻게 사용합니까?



    package.json
    {
      "scripts": {
        "build": "react-scripts build",
        "build:staging": "env-cmd .env.staging npm run build"
      }
    }
    


    지금까지 수동으로 한 일


  • API의 방향을 변경하여 npm run build
  • 해당 S3 버킷에 build한 파일을 업로드
  • CloudFront 캐시 비활성화
  • 이것을 production 과 staging 로 실시


  • Amazon S3에 파일 업로드


  • AWS SDK로 업로드
  • async function putFile(sourceFile) {
      // S3にputするファイル名
      const dir = process.env.DIRECTORY ? `${process.env.DIRECTORY}/` : '';
      const key = sourceFile.replace('build/', dir);
      // ファイルの内容を取得
      const data = await fs.readFile(sourceFile);
    
      const params = {
        Bucket: process.env.BUCKET,
        Key: key,
        Body: data,
        ContentType: mime.lookup(sourceFile),
      };
      await s3.putObject(params).promise();
    
      debug(`putObject: ${key}`);
    }
    

    지금까지 수동으로 한 일


  • API의 방향을 변경하여 npm run build
  • 해당 S3 버킷에 build한 파일을 업로드
  • CloudFront 캐시 비활성화
  • 이것을 production 과 staging 로 실시


  • CloudFront 캐시 무효화



    deploy.js
    const cloudFront = new aws.CloudFront();
    
    await cloudFront.createInvalidation({
      DistributionId: process.env.DistributionId,
      InvalidationBatch: {
        CallerReference: uuid(),
        Paths: {
          Quantity: 1,
          Items: ['/*'],
        }
      }
    }).promise();
    


    지금까지 수동으로 한 일


  • API의 방향을 변경하여 npm run build
  • 해당 S3 버킷에 build한 파일을 업로드
  • CloudFront 캐시 비활성화
  • 이것을 production 과 staging 로 실시


  • 환경 변수를 좋은 느낌으로 전환



    dotenv
    Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
    .env.production.env.staging 를 npm-scripts로 부르기

    어떻게 사용합니까?



    deploy.js
    // 環境変数TARGETを元に読み込むファイルを切り替え
    const target = process.env.TARGET || 'production';
    require('dotenv').config({
      path: `${process.cwd()}/.env.${target}`,
    });
    

    package.json
    {
      "scripts": {
        "deploy": "node scripts/deploy.js",
        "deploy:staging": "TARGET=staging npm run deploy"
      }
    }
    


    요약



    ec2의 WebAPI 업데이트가 수동이므로 npm-scripts에서 업데이트를 킥 할 수 있으면 좋겠습니다.

    좋은 웹페이지 즐겨찾기