배경
이미지나 비디오 같은 정적 파일 로딩 레이턴시를 줄이기 위해 Cloud CDN 서비스를 사용해야 했고, GCP에서 백엔드로 운영 중인 NestJS에서 이미지를 저장할 때 이를 적용해야 해서 나중에 참고할 수 있도록 글로 정리하게 되었습니다.
버킷 생성
GCS에 업로드 하기 전에 먼저 저장소를 생성해야 합니다.
GCP 메뉴 중 Cloud Storage로 이동해서 버킷을 생성해 줍니다.

다음으로 백엔드가 GCS에 접근할 수 있도록 키를 발급해야 합니다.
'IAM > 서비스 계정'으로 이동해서 저장소 관리자 권한을 부여한 서비스 계정을 만들고 키를 생성해 줍니다.



생성한 서비스 계정으로 이동해서 json 키를 생성합니다.

다운받은 키 내용 모두를 환경설정 파일로 만들어서 프로젝트 내에 저장합니다.
깃에 푸시할 때는 키 파일을 ignore로 설정하고 리포지토리 환경변수로 생성해서 사용하는 것이 권장됩니다.
gcs-service-key.json
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "...",
"client_id": "...",
"auth_uri": "...",
"token_uri": "...",
"auth_provider_x509_cert_url": "...",
"client_x509_cert_url": "..."
}
다음으로 package.json script에 아래와 같이 GCP 인증을 추가합니다.
package.json
{
...
"scripts": {
...
"start:dev": "GOOGLE_APPLICATION_CREDENTIALS='gcs-service-key.json' nest start --watch",
...
},
...
}
다음으로 multer 옵션을 작성해서 파일 저장 프로세스를 정의합니다.
multer-options.ts
import { diskStorage } from 'multer';
import * as fs from 'fs';
import * as uuid from 'short-uuid';
export const multerOptions = {
storage: diskStorage({
destination: function (req, file, cb) {
const path = `${process.env.UPLOADS_TEMP_URL}`;
cb(null, path);
// 디렉터리 없으면 디렉터리를 새로 생성
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true });
}
},
filename: function (req, file, cb) {
const rightNow = new Date();
const yymmdd = rightNow.toISOString().slice(0, 10).replace(/-/g, '');
cb(null, `${yymmdd}${uuid.generate()}`);
},
}),
};
다음으로 temp파일에 저장된 이미지 파일을 GCS에 업로드 하면 됩니다.
아래 패키지를 먼저 설치해주세요.
npm i @google-cloud/storage --save
image.controller.ts
import { Storage } from '@google-cloud/storage';
...
@Post()
@UseInterceptors(FileInterceptor('img', multerOptions))
uploadTempFile(@UploadedFile() image: Express.Multer.File) {
const rightNow = new Date();
const year = rightNow.toISOString().slice(0, 4);
const month = rightNow.toISOString().slice(5, 7);
const storage = new Storage({ projectId: process.env.GCP_PROJECT_ID });
return storage
.bucket(process.env.GCP_BUCKET_NAME)
.upload(`${process.env.UPLOADS_TEMP_URL}/${image.filename}`, {
destination: `${year}/${month}/${image.filename}`,
});
}
위와 같이 upload()를 하면 이미지 파일이 GCS에 업로드 되며, 폴더가 없으면 자동으로 생성해줍니다.
'JavaScript > NestJS' 카테고리의 다른 글
[NestJS] 채팅 구현하기(with ReactJS) (1) | 2023.05.22 |
---|---|
[NestJS] 스케줄러로 반복 작업 설정하기 (0) | 2023.05.18 |