2025. 11. 20. 15:58ㆍWeb
Node.js로 AWS S3에 이미지 업로드하는 실전 가이드

multer + multer-s3 활용, 파일 크기 제한/확장자 검사까지
웹 서비스에서 이미지 업로드 기능은 이제 선택이 아니라 기본 기능에 가깝습니다.
이 글에서는 Node.js 환경에서 AWS S3(Simple Storage Service)를 이용해 이미지 업로드를 구현하는 방법을 단계별로 정리해 보겠습니다.
단순히 올리는 것에서 끝나는 것이 아니라, multer-s3를 활용해 파일 크기 제한, 확장자 검사까지 함께 처리하는 팁도 담았습니다.
AWS S3(Simple Storage Service)란?
AWS S3는 아마존에서 제공하는 객체 저장소 서비스입니다. 이미지, 동영상, 문서 파일 등 다양한 데이터를 안전하게 저장할 수 있고,
전 세계적으로 가장 많이 사용되는 클라우드 스토리지 중 하나입니다.
왜 S3를 사용할까요?
- 비용이 비교적 저렴하고 사용량에 따라 과금되는 구조
- 용량 제한 없이 확장 가능한 구조
- CloudFront 같은 CDN과 연동이 쉬움
- 버전관리, 암호화, 권한 제어 등 보안 기능 제공
정리하자면, 웹에서 이미지 파일을 안정적으로 다루고 싶다면 가장 먼저 고려해볼 만한 저장소라고 보시면 됩니다.
이미지 업로드 전에 준비해야 할 3가지
| 필수 준비 | 설명 |
|---|---|
| S3 버킷 생성 | 이미지 파일을 저장할 공간을 AWS 콘솔에서 생성합니다. |
| IAM 권한 설정 | Node.js 서버가 S3에 접근할 수 있도록 권한이 부여된 IAM 사용자를 만듭니다. |
| Access Key / Secret Key | AWS SDK에서 사용할 수 있도록 액세스 키와 시크릿 키를 발급받습니다. |
주의할 점은 버킷 권한을 퍼블릭으로 너무 넓게 열지 않는 것입니다.
정적 파일을 외부에서 접근할 수 있게 허용하더라도, 정말 필요한 최소 범위만 공개하는 방향으로 설정해 주세요.
Node.js에서 S3 이미지 업로드 구현하기
1. 필요한 패키지 설치
npm install multer multer-s3 aws-sdk
2. AWS SDK 및 S3 설정
.env 파일 등에 키 정보를 넣어두고, 코드에서는 환경 변수를 불러오는 방식을 추천합니다.
const AWS = require("aws-sdk");
AWS.config.update({
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_KEY,
region: "ap-northeast-2", // 한국(서울) 리전
});
const s3 = new AWS.S3();
3. multer-s3로 스토리지 엔진 설정
multer와 multer-s3를 이용해 업로드된 파일이 바로 S3 버킷으로 올라가도록 설정합니다.
const multer = require("multer");
const multerS3 = require("multer-s3");
const upload = multer({
storage: multerS3({
s3: s3,
bucket: "YOUR_BUCKET_NAME", // 본인 버킷 이름
acl: "public-read", // 업로드된 파일을 공개 URL로 접근 가능하게
contentType: multerS3.AUTO_CONTENT_TYPE,
key: (req, file, cb) => {
const fileName = `images/${Date.now()}_${file.originalname}`;
cb(null, fileName);
},
}),
});
위 설정까지 하면 기본적인 S3 이미지 업로드는 동작합니다.
하지만 실제 서비스에서는 파일 크기와 확장자 제한이 거의 필수라고 볼 수 있습니다.
실무 팁: 파일 확장자 & 크기 제한하기
이미지 업로드 기능이 있다고 해서 아무 파일이나 다 받아서는 안 됩니다.
악성 스크립트나 서버 저장 공간을 과도하게 사용하게 만드는 파일 업로드를 막기 위해 다음 옵션들을 함께 설정해 주세요.
const upload = multer({
storage: multerS3({
s3: s3,
bucket: "YOUR_BUCKET_NAME",
acl: "public-read",
contentType: multerS3.AUTO_CONTENT_TYPE,
key: (req, file, cb) => {
const fileName = `images/${Date.now()}_${file.originalname}`;
cb(null, fileName);
},
}),
limits: {
fileSize: 5 * 1024 * 1024, // 5MB 제한
},
fileFilter: (req, file, cb) => {
const allowed = ["image/jpeg", "image/png", "image/jpg"];
if (allowed.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error("올바르지 않은 이미지 형식입니다. (jpg, jpeg, png만 허용)"));
}
},
});
- 파일 크기 제한: 예제에서는 5MB로 제한
- 허용 MIME 타입: image/jpeg, image/jpg, image/png
- GIF, EXE, ZIP 파일 등은 보안과 용량 관리를 위해 업로드를 막는 것을 권장
라우터에 업로드 기능 연결하기
Express 기준으로, 단일 파일 업로드를 처리하는 기본 예시는 다음과 같습니다.
const express = require("express");
const router = express.Router();
// "image"는 클라이언트에서 보내는 form-data 필드 이름과 같아야 합니다.
router.post("/upload", upload.single("image"), (req, res) => {
// multer-s3를 통해 업로드가 성공하면 req.file에 정보가 들어옵니다.
res.json({
success: true,
imageUrl: req.file.location, // 업로드된 S3 이미지 URL
});
});
module.exports = router;
프론트엔드에서는 form-data 형식으로 image 필드에 파일을 담아 이 라우터로 전송하면,
S3에 업로드된 후 공개 URL(imageUrl)을 응답으로 받아 사용할 수 있습니다.
정리: 지금 프로젝트에 바로 적용해 보세요
AWS S3를 이용하면 서버 디스크 용량을 크게 신경 쓰지 않고도 안정적인 이미지 업로드 시스템을 구성할 수 있습니다.
이번 글에서는
- AWS S3 버킷과 IAM 계정 준비
- Node.js + AWS SDK 기본 설정
- multer-s3를 활용한 이미지 업로드 구현
- 파일 크기 및 확장자 제한을 통한 기본적인 보안 강화
까지 한 번에 정리해 보았습니다.
이제 사용 중인 프로젝트의 업로드 로직에 한 단계씩 적용해 보세요.
직접 적용해 보면서 오류나 궁금한 점이 생기면, 그 부분을 정리해서 다시 한 번 개선하는 식으로
“내 서비스에 맞는 업로드 구조”를 만들어 가는 것이 중요합니다.
다음에는 CloudFront와 연동해서 이미지 로딩 속도를 최적화하는 방법이나,
폴더 구조 및 권한 전략을 어떻게 가져가면 좋은지에 대해서도 따로 정리해 볼 예정입니다.
궁금한 점이나 같이 다뤄줬으면 하는 내용이 있다면 댓글로 편하게 남겨 주세요 :)
'Web' 카테고리의 다른 글
| GitHub Actions로 프론트엔드 CI 자동화 구축하기 (Setting Up Frontend CI Automation with GitHub Actions) (0) | 2025.11.14 |
|---|---|
| 로또번호 생성기 (Next.js & MySQL) (4) | 2024.12.28 |
| <img> 태그의 alt 속성 왜 넣어야 하나? (0) | 2022.12.01 |
| create-nuxt-app은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는배치 파일이 아닙니다. (1) | 2022.11.09 |