본문 바로가기

카테고리 없음

Node.js multer로 AWS S3에 이미지 업로드하기 + heroku

쇼핑몰을 만들며 생긴 일… 이미지가 올라가지 않았다.

 

heroku에선 30분에 한 번씩 sleep 모드로 들어가서 이미지를 지워버린다는 얘기도 있었고, 무엇보다 일단 이미지 업로드 자체가 되질 않았다. 이렇게 된 거 aws 란 넘을 함 이용해보자! 하며 삽질을 시작했다. 결과는 만족한다. 삽질은 괴롭지만 결과는 늘 달다!

 

이 글은 AWS의 IAM, S3등등 AWS의 사이트에서 할 수 있는 세팅을 전부 한 상태라는 전제 하에 진행합니다.

 

 

 

S3 페이지의 버킷에 들어와서 업로드를 눌러 이미지를 업로드 했을 시,

객체 URI를 클릭하면 정상적으로 이미지가 뜨는가? 를 먼저 확인하고 진행하도록 한다.

 


할 일

  1. 프론트에서 Axios를 이용하여 유저가 직접 업로드한 이미지를 넘겨주면
  2. 서버에서는 건네받은 이미지를 s3저장소에 저장한다

1. 모듈을 설치 (multer-s3, aws-sdk)

먼저 아마존 sdk 모듈을 설치한다.

npm install --save aws-sdk

그다음 multer-s3 모듈을 설치한다. (기존 코드는 오리지널 multer 모듈을 사용했지만, s3에 업로드하기 위해서는 전용 모듈인 multer-s3 모듈을 설치할 필요가 있다.)

npm install --save multer-s3

2. 모듈 불러오고 AWS config설정하기

서버측 FileUpload.js 파일에서 두 모듈을 불러온다.

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

상단에 AWS config작성

AWS.config.update({
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
  region: "ap-northeast-2",
});

확인해본다… console.log로… accessKeyId든 secretAccessKey든 찍어서 확인해보고 만약 undefined로 뜬다면 env 설정이 되어 있지 않다는 뜻이므로 그것부터 한다.

콘솔에 정확히 뜬다면 그냥 3번으로 넘어가면 된다.

2-1. 로컬에서 환경변수 설정

일단 이미지 업로드가 되는지 로컬환경에서 테스트 할 것이시 때문에 로컬 설정부터 해준다.

터미널창에 이렇게 입력

aws configure

나는 지금 이미 입력해둔 상태라 저렇게 뜨지만 원래는 AWS Acess Key ID [None] : 입력칸…

이렇게 뜰 것이다. 여기에 aws 유저 생성시 받았던 값들을 입력한다.

이제 다시 2로 돌아가서 설정한 후 console에 잘 나오는지 확인해본다.

3. 이미지 업로드 로직 수정

건네받은 이미지를 저장하는 로직 multerS3를 이용하는 방식으로 수정한다

const upload = multer({
  storage: multerS3({
    s3: new AWS.S3(), // 접근 권한 설정
    bucket: "corner-dream-atelier",
    key(req, file, cb) {
      const fileName = file.originalname.toLowerCase().split(" ").join("-");
      cb(null, `${Date.now()}_${fileName}`);
    },
  }),
}).single("file");

router.post("/image", (req, res) => {
  // 가져온 이미지를 저장

  upload(req, res, (err) => {
    if (err) {
      return res.json({ success: false, err });
    }

    return res.json({
      success: true,
      filePath: res.req.file.key,
    });
  });
});

이제 프론트에서 이미지를 받아올 때 http://localhost:5000/${imageSrc} 로 받아오는 것이 아니라 본인의 아마존 주소를 이용하면 된다. 모르겠는 경우는

아까 이미지 업로드에서 확인한 객체url을 확인.

배포시 어떻게…?

배포할땐 어떻게해야 환경변수르 사용할 수 있을까 할까. aws config로 설정해둔 env 값들은 로컬에서만 작동한다. 그렇다고 env를 이용하지 않고 하드코딩으로 private한 값들을 집어넣는 것은 너무 위험하다. heroku에서 다행히도 환경변수를 설정할 수 있다. 굿

2-1. heroku 환경변수 설정

일단 헤로쿠 로그인을 한 후 cofig를 설정한다

heroku login

 

heroku config:set AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy

이제 heroku 로 배포한 사이트에서도 이미지가 잘 올라간다.