반응형

이미지 압축 및 s3 업로드는

정말 많이 쓰이지만 의외로 포스팅이 없어

간단히 정리해본다.

 

 

처리절차

1. 클라이언트 요청 (생략)

2. multer-s3로 aws 업로드

3. key로 s3 object를 불러와 압축 후 재 업로드

4. 기존 파일 key로 제거

 

 

1. 클라이언트 요청 (생략)

요청은 포스트맨(Postman)으로 요청,

테스트하면 됨으로 생략 (form-data 방식 활용)

 

 

2. multer-s3로 aws 업로드

express router에서 미들웨어 처리를 해줄것이다.

그전에 multer-s3 미들웨어를 만들어주자.

// aws.ts
const AWS = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');

const aws_config = {
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_KEY,
    region: 'ap-northeast-2',
    signatureVersion: 'v4',
};

export const s3 = new AWS.S3();

export const uploadImage = multer({
  storage: multerS3({
    s3,
    bucket: 'test.bucket',
    metadata: (req, file, cb) => {
      cb(null, { fieldName: file.fieldname });
    },
    key: (req, file, cb) => {
      const ext = path.extname(file.originalname);
      const timestamp = new Date().getTime().valueOf();
      const filename = 'test' + timestamp + ext;
      cb(null, filename);
    },
  }),
});

이제 사용자 요청을 받는 router부분에서

uploadImage를 미들웨어로 넣어주면 된다.

// image.router.ts
router.post('/image/upload', uploadImage.single('photo'), (req, res) => {
  ...
})

 

 

3. key로 s3 object를 불러와 압축 후 재 업로드 & 기존 파일 key로 제거

uploadImage 처리 후 req.file에서

업로드된 이미지 객체의 key를 확인할 수 있다.

 

이 key를 활용해 객체를 불러와

압축하여 재업로드 및 삭제를 진행할것이다.

 

// aws.ts
export const compressImageUploadByKey = async (key: string, width?: number) => {
  try {
    const compressedKey = `compressed_${key}`;
    const config = {
      Bucket: 'test.bucket',
      Key: key
    }
        
    let resizedConfig: any = {
      Bucket: 'test.bucket',
      Key: compressedKey
    }

    // fetch
    const imageData: any = await s3.getObject(config).promise();

    // resizing
    const imageBuffer = await sharp(imageData.Body).resize({ width: width || 640 }).toBuffer();
    resizedConfig.Body = imageBuffer;
    
    // upload
    await s3.putObject(resizedConfig).promise();

    // origin image delete
    await s3.deleteObject(config).promise();

    return compressedKey;
  } catch(error) {
    console.log('Get image by key from aws: ', error);
  }
}

불러오고, 압축하고, 업로드하고, 지우고

4가지 작업이 진행되었다.

 

 

새로 업로드된 이미지의 Key를

DB에 저장하거나 하는 작업을 

각 작업 환경에 맞게 진행하면 끝

반응형
반응형

클라이언트 코드를

EC2에서 관리 및 배포하곤 했었는데

사실 용량도 많이 차지하고 좋은 방법은 아니라고 생각했다.

 

더 빠른 전달속도와 더 쉬운 프로젝트 관리를 위한 방법을 찾던중

CloudFront + Route53+ S3 + ACM(for SSL)
조합을 발견했다.

 

처음해보는 사람이라도 쉽게 할수있고,

효과는 눈이 번쩍일정도로 뛰어난것같다.

 

이에 대해 고민하던 나와 다른 분들을위해

위 조합을 이용하는 방법을 상세하게 공유하고자 한다.

 

1. S3

1-1) 먼저, 시작은 S3에서부터다

1-2) React 프로젝트가 있다면 빌드후 생성된 파일들을 S3에 올릴것이다.

1-3) S3 -> 버킷 만들기

1-4) 주의사항은 모든 퍼블릭 액세스 차단을 해제시킬것 (사이트는 누구나 접근가능해야하니까요)
1-4-1) 버킷 만들기
1-5) 버킷을 만들고나면 객체 탭에다가 빌드후 생성된 파일들을 드래그다운하여 업로드한다.
1-6) 다음, 권한 탭에서 버킷 정책을 생성해준다
1-6-1) 편집 -> 정책 생성기 
1-6-2) Select Type of Policy: S3
1-6-3) Effect: Allow

1-6-4) Principal: *

1-6-5) Aws Service: S3

1-6-6) Actions: GetObject
1-6-7) ARN: 정책 편집 페이지에 있는 버킷ARN을 복사해 붙여넣는다. 그리고 뒤에 /*을 덧붙인다
1-6-8) ARN 예시: arn:aws:s3:::coke.cola/*
1-7) 속성탭으로 이동한다.
1-7-1) 맨 하단에 정적 웹 사이트 호스팅을 편집
1-7-2) 정적 웹사이트 호스팅 -> 활성화, 유형 -> 정적 웹사이트 호스팅, 인덱스 문서 -> index.html
1-7-3) 변경 사항 저장

여기까지 했으면 S3설정은 끝났다.

심심하다면 index.html의 객체 URL로 접근해보면 접속됨을 확인할 수 있다.

 

이제 누구나 쉽게 접속할수있게 도메인을 설정해주는 것과 좀더 빠른 페이지를 위한 CloundFront 적용이 남았다.

아, 안전한 서비스 제공을 위한 SSL도 필수니까 당연히 진행하는거로


이전 포스팅에서 했던것처럼 ACM(Certificate Manager)을 통해 SSL 인증서를 생성해보자

 

2.  SSL 인증

2-1) ACM (Certificate Manager)에 접속
2-2) 인증서 요청 -> 공인 인증서 요청
2-3) 도메인 이름 사용하고자 하는거로 입력  (S3에 저장한 사이트를 운영하고자하는 사이트 도메인), (구매해둔 도메인은 있다는 가정)

2-4) DNS 검증 -> 태그 설정 (내가 식별을 위한거니까 영문으로 알아볼수 있게 쓰면됨)

2-5) 검토를 하고나서 생성된 정보를 기반으로 Route 53에 해당 CNAME을 등록해주면 됩니다.

 

 

SSL은 간단히 이정도만 해주면 끝입니다.

그러면 잠시 뒤 발급완료 처리가 됩니다.

 

다음 순서는 CloudFront입니다.

S3에서 파일을 제공하는것보다 빠를 뿐아니라, SSL을 연결해주는것도 쉽게 가능합니다.

 

3. CloudFront 설정하기 - 조금 번거로움

3-1) CloudFront 접속 

3-2) Create distribution

3-2-1) Origin Domain 검색 (로딩이 좀 걸립니다) ->  S3 버킷이 나타나면 클릭

3-2-2) Viewer protocol policy: Redirect HTTP to HTTPS

3-2-3) Custom SSL certificate - optional: 이전에 생성해둔거로 지정

3-2-4) Default root object: index.html

3-2-5) Create distribution
3-3) 생성됐다면, 도메인을 설정해줄건데요. 다시 Roue53에 해당 호스팅 영역으로 갑니다.

3-3-1) 레코드 생성 - "A 유형"

3-3-2) 도메인 이름 설정 (2-3과 일치하게)

3-3-3) 트래픽 라우트 대상 -> 별칭 active -> Cloud Front 배포에 대한 별칭 선택 -> 검색란에 CloudFront의 Distribution domain name 이름 검색 및 선택

3-3-4) 3-3-1 ~ 3-3-3의 작업을 한번 더 반복하여 "AAA 유형"도 생성

3-4) 거의 끝났습니다. 다시 Clound Front로 돌아갑니다.

3-4-1) 해당 객체를 Edit

3-4-2) Alternative domain name에 "Add Item" 하여 2-3에서 만든 도메인과 동일하게 입력해줍니다.
3-4-3) 그리고 저장하면 끝

 

자 이제 두근두근 하면서

해당 도메인에 https://로 접속해 봅니다.

 

잘되나요? 잘됐길바라며 여기서 마치겠습니다.

반응형
반응형

S3에 업로드된 파일의 이름변경, 언제 필요할까요?

특정한 이름 구조나 패턴을 갖춘 파일들이 필요할 때가 분명히 있습니다.

제가 이번에 해당 경험을 하게되어 간단히 정보를 공유해보고자 합니다.

 

 

 

S3에서 제공하는 API를 활용하면 제법 다양한 일들을 할 수 있습니다.

그중에서 이번엔 버킷에서 항목들의 목록을 가져오고, 항목들의 이름을 변경하는 방법에 대해서 알아보고자 합니다.

먼저, S3 API 중에 항목의 이름을 변경하는 API는 존재하지 않습니다.

따라서, 항목을 카피하는 copyObject를 이용해  변경된 이름의 Object를 생성하고 원본을 지우는 방식을 채택해야합니다.

 

항목들을 가져올때는 listObjectsV2를 사용하는데요 간단한 예시를 들어보겠습니다.

const config = {
  accessKeyId: process.env.AWS_KEY,
  secretAccessKey: process.env.AWS_SECRET_KEY,
  region: 'ap-northeast-2',
  signatureVersion: 'v4',
};

AWS.config.update(config);
const s3 = new AWS.S3();

s3.listObjectsV2({ Bucket: `pdf.pitchit`, MaxKeys: 1000 }, async (err, data) => {
  const { Contents } = data;
  const keys = Contents.map(info => info.Key);
  
  // 키를 활용해 다양한 액션을 취할 수 있습니다.
  // 그중에서 객체 복사는 다음과 같이 간단히 할 수 있습니다.
  
  const info = {
    Bucket: 'origin_bucket',
    CopySource: `/target_bucket/${key}`,
    Key: new_name, // 변경할 이름입니다.
  };
  
  s3.copyObject(info, async (err, data) => {
    ...
  });
});

 

 

 

반응형
반응형

nodejs에서 s3에 이미지를 업로드하는 방법은 두가지가 있습니다.

 

1.  multer-s3사용하기

2. s3, api사용하기

 

nodejs를 통해 개발을 해오신분이라면 multer에 익숙하리라 생각합니다.

multer-s3는 이미 업로드의 위치를 s3의 버킷으로 합니다. 

간단히 살펴볼까요?

 

* multer, multerS3 사용

const multer = require('multer');
const multerS3 = require('multer-s3');
const aws = require('aws-sdk');

aws.config.update({
    accessKeyId: myAccessKey,
    secretAccessKey: mySecretKey,
    signatureVersion: 'v4',
    region: myRegion,
});

const s3 = new aws.S3();

const imageUpload = multer({
    storage: multerS3({
        s3: s3,
        bucket: 'myS3Bucket',
        metadata: (req, file, cb) => {
            cb(null, { fieldName: file.fieldname });
        },
        key: (req, file, cb) => {
            cb(null, Date.now().toString());
        },
    }),
});

이와같이 어렵지 않게 업로드 할 수 있습니다.

 

* 이번에는 AWS에서 document의 putObject를 살펴보겠습니다.

var params = {
	Body: <Binary String>, 
	Bucket: "examplebucket", 
	Key: "HappyFace.jpg", 
	Tagging: "key1=value1&key2=value2"
};

 s3.putObject(params, function(err, data) {
	if (err) console.log(err, err.stack); // an error occurred
	else     console.log(data);           // successful response
	/*
	data = {
		ETag: "\"6805f2cfc46c0f04559748bb039d69ae\"", 
		VersionId: "psM2sYY4.o1501dSx8wMvnkOzSBB.V4a"
 	}
 	*/
 });

 

두 방법 모두 간편하여, 원하는 방법으로 사용하시면 될것같습니다.

현재, 저는 multer를 쓰고있지만, 이왕이면 aws에서 가이드해주는 방식을 따르는것이

좋다고 생각합니다.

 

반응형