Upload File Node.js Multer S3: Detailed Instructions From A-Z

Upload File Node.js Multer S3: Hướng Dẫn Chi Tiết Từ A-Z

Developers are no strangers to struggling with managing uploaded files, especially when it comes to cloud platforms like Amazon Simple Storage Service (AWS S3). Confusing from configuring IAM permissions, handling large file sizes, to securing credentials so that they are not revealed. This article summarizes real-life experience from Pham Hai, providing a complete guide from A-Z for you to successfully set up the Node.js Multer S3 file upload feature. I will go straight to the point with practical code, helping even beginners to apply it immediately to the project, without going around theory.

Prepare the "airport" for your files: Configure AWS S3 and Node.js

To start uploading files to AWS S3 Node.js, you need to create a solid cloud storage infrastructure including Buckets and grant access through IAM users.

Before diving into coding, we must prepare the correct infrastructure. Setting up correctly from the beginning helps you avoid 90% of "Access Denied" headaches later on. If you're completely new to the cloud ecosystem, checking out the AWS free tier beginner documentation is a great stepping stone to grasp the basics.

Below is a quick comparison table of why at Pham Hai, we always prioritize using S3 instead of saving files directly on the server:

Criteria Save on Server (Disk Storage) Save on AWS S3 (Cloud Storage)
Khả năng mở rộng Limited by hard drive capacity Almost limitless, automatic scaling
Bảo mật & Backup Manual configuration, easy to lose data Built-in IAM, data durability 99.999999999%
Băng thông Consumes bandwidth of the API server itself Completely separate, CloudFront can be combined

Step 1: Create a "home" on S3 - Instructions for creating a Bucket

Bucket S3 acts as a giant root directory in the cloud, serving as a container for all files uploaded from your Node.js server.

Hãy đăng nhập vào tài khoản AWS của bạn và tìm đến dịch vụ S3. Bấm vào nút "Create bucket". Bạn cần chọn một tên bucket duy nhất trên toàn cầu (ví dụ: phamhai-upload-storage-2026) và chọn Region gần với tệp khách hàng của bạn nhất (như ap-southeast-1 - Singapore) để tối ưu tốc độ.

An extremely important note according to the latest update from AWS: The "Object Ownership" feature now disables ACLs (Access Control Lists) by default. If you want users to be able to view public files (like when uploading images to S3 Node.js Multer as avatars), carefully configure Bucket Policy. It is best to turn off "Block all public access" if the nature of the project requires the file to be public.

Step 2: Apply for "passport" - Create an IAM user with S3 access

User IAM provides a set of authentication information including access key and secret key, helping your Node.js application connect and interact with AWS S3 in the most secure way.

Đừng bao giờ dùng root account để tích hợp API! Đây là lỗi bảo mật sơ đẳng. Hãy truy cập vào dịch vụ IAM, tạo một user mới (ví dụ: s3-upload-api-user). Thay vì cấp quyền rộng, hãy áp dụng nguyên tắc đặc quyền tối thiểu (Least Privilege).

Bạn nên tạo một custom policy chỉ cho phép hành động s3:PutObjects3:GetObject vào đúng tên bucket của bạn. Sau khi tạo xong, AWS sẽ hiển thị Access Key ID và Secret Access Key. Hãy copy và cất giữ chúng ngay lập tức, vì Secret Key sẽ không hiển thị lại lần thứ hai.

Step 3: Initialize Node.js project and install "helpers"

Use the npm package management tool to install core libraries including express, multer, multer-s3 and @aws-sdk/client-s3 to get ready to write code.

Mở terminal lên và khởi tạo một project mới với npm init -y. Đối với những bạn đang trong quá trình Học Node.js từ đầu cho backend developer, việc làm quen với NPM và package.json là kỹ năng bắt buộc.

Tiếp theo, hãy chạy lệnh sau để cài đặt các dependency: npm install express multer multer-s3 @aws-sdk/client-s3 dotenv uuid

Ở hướng dẫn cài đặt Multer S3 Node.js này, chúng ta sử dụng @aws-sdk/client-s3 (AWS SDK v3) thay vì bản v2 cũ kỹ. SDK v3 là tiêu chuẩn hiện tại, có dung lượng nhẹ hơn nhờ cơ chế import theo module. Thư viện multer-s3 sẽ đóng vai trò middleware hoàn hảo, kết nối giữa Multer và hệ thống S3.

"Taking off" the first file: Detailed code for uploading a single file to S3

Write code to configure the multer-s3 library in combination with AWS SDK v3 to handle streaming files directly from the client to S3 through an Express API.

Now it's time to roll up your sleeves and get into the actual coding. The goal here is to build a processing flow that receives files from users and pushes them straight to the cloud without needing to temporarily store them on the server hard drive. This technique saves significant I/O resources. If you don't have an API framework available, the article on how to use Express.js to create a complete REST API will provide a solid foundation for you to pair the code below.

Cấu hình Multer với multer-s3 để "bắn" thẳng file lên S3

Initialize S3Client from AWS SDK v3 and pass it to the multer-s3 configuration, also defining the bucket name, ContentType and file naming algorithm (Key).

Đầu tiên, bạn tạo một file tên là s3.config.js. File này sẽ chịu trách nhiệm toàn bộ về cấu hình Multer S3 Node.js.

const { S3Client } = require('@aws-sdk/client-s3');
const multer = require('multer');
const multerS3 = require('multer-s3');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
require('dotenv').config();

// Khởi tạo SDK v3 S3Client
const s3Config = new S3Client({
    region: process.env.AWS_REGION,
    credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    }
});

// Cấu hình Multer
const upload = multer({
    storage: multerS3({
        s3: s3Config,
        bucket: process.env.AWS_BUCKET_NAME,
        contentType: multerS3.AUTO_CONTENT_TYPE,
        metadata: function (req, file, cb) {
            cb(null, { fieldName: file.fieldname });
        },
        key: function (req, file, cb) {
            const uniqueSuffix = uuidv4() + path.extname(file.originalname);
            cb(null, 'uploads/' + uniqueSuffix); // Lưu vào folder uploads/ trên S3
        }
    })
});

module.exports = upload;

Trong đoạn code cách upload file lên S3 bằng Node.js trên, mình dùng uuid để tạo tên file ngẫu nhiên, tránh tình trạng file tải lên sau ghi đè file trước. Thuộc tính contentType: multerS3.AUTO_CONTENT_TYPE cực kỳ đáng giá. Nó tự động nhận diện Metadata của file (hình ảnh, video, PDF) để S3 trả về đúng Content-Type khi có request đọc file.

Write a complete API endpoint with Express.js

Create a POST route in Express, use middleware upload.single() to capture file data and return the public path (Location) of the file on S3.

Tiếp theo, tạo file app.js để thiết lập server Express API. Chúng ta sẽ import cấu hình upload vừa tạo vào đây.

const express = require('express');
const upload = require('./s3.config');
const app = express();

app.post('/api/upload', upload.single('document'), (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ error: 'Không tìm thấy file tải lên' });
        }

        // req.file chứa thông tin trả về từ S3
        res.status(200).json({
            message: 'Upload file Node.js Multer S3 thành công!',
            fileUrl: req.file.location,
            fileKey: req.file.key
        });
    } catch (error) {
        res.status(500).json({ error: 'Lỗi server khi upload file' });
    }
});

app.listen(3000, () => console.log('Server API đang chạy tại port 3000'));

Đoạn code Server-side upload này rất gọn gàng. Thuộc tính req.file.location chính là đường dẫn public URL để bạn lưu vào database. Trong thực tế, bạn không nên mở API này cho tất cả mọi người. Việc tích hợp JWT authentication Node.js bảo mật API là bắt buộc để xác minh danh tính người dùng trước khi cho phép họ tải file lên hệ thống.

Using Postman to test results: A visual example

Set up a POST request on the Postman tool with a form-data body to send the actual file to the newly created API endpoint.

Để chạy thử ví dụ upload file Node.js Multer S3, bạn mở Postman lên. Chọn method POST và nhập URL http://localhost:3000/api/upload.

Chuyển sang tab Body, chọn form-data. Ở cột Key, bạn nhập chữ document (phải khớp exatcly với tên field trong hàm upload.single('document')). Nhớ đổi kiểu dữ liệu của Key từ Text sang File. Ở cột Value, hãy chọn một tấm hình bất kỳ từ máy tính của bạn và nhấn Send. Nếu nhận được response HTTP 200 kèm theo fileUrl, bạn đã thành công!

Expanding routes: Advanced upload techniques and best practices

Optimize the file download system by applying the technique of uploading multiple files at the same time, handling large files with multipart and strictly securing configuration.

As your web application grows, the basic upload method will no longer be sufficient. At this time, you need to equip additional file uploads to AWS S3 Node.js best practices so that the system operates smoothly, withstands high loads and is absolutely safe from security risks.

Upload nhiều file cùng lúc: Xử lý gọn gàng với array() hoặc fields()

Replace the upload.single() method with upload.array() or upload.fields() to allow the client to upload multiple files simultaneously in a single request.

Nếu tính năng của bạn yêu cầu người dùng chọn nhiều ảnh cùng lúc (ví dụ: đăng album ảnh), hãy dùng upload.array('documents', 5) trong route Express. Số 5 ở đây là giới hạn tối đa số lượng file. Lúc này, bạn sẽ nhận dữ liệu qua mảng req.files thay vì req.file.

Trường hợp phức tạp hơn, form có nhiều field riêng biệt (VD: một chỗ cho avatar, một chỗ cho ảnh CCCD), bạn hãy dùng: upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'idCard', maxCount: 2 }]). Đây là cách upload nhiều file lên S3 Node.js linh hoạt và phổ biến nhất trong các dự án thực tế.

Dealing with "huge" files: Why is Multipart Upload a savior?

Use multipart upload technique via @aws-sdk/lib-storage library to split large files, increase transmission speed and avoid timeout errors.

When you need to upload large files to S3 Node.js (for example, a 2GB video), sending a large block of data via regular stream is very risky. The network just needs to flash and the process will fail and you will have to start over.

Đó là lúc Multipart upload tỏa sáng. Thay vì dùng multer-s3, với các file siêu lớn, chúng tôi khuyên bạn nên dùng class Upload từ package @aws-sdk/lib-storage. Kỹ thuật này chia file thành các phần nhỏ (chunk) tầm 5MB và upload song song. Nếu có một chunk bị lỗi mạng, S3 chỉ retry đúng chunk đó. Nó tối ưu băng thông và giảm thiểu rủi ro đứt gãy kết nối cực kỳ hiệu quả.

Don't be "indiscreet": Secure credentials with environment variables (.env)

Store sensitive information such as access keys and secret keys in a separate .env file and include this file in .gitignore to avoid source code leaks.

Bảo mật khi upload file lên S3 Node.js là vấn đề không bao giờ được xem nhẹ. Đã có rất nhiều trường hợp dev vô tình hardcode Secret Key thẳng vào file s3.config.js rồi push lên Github. Hậu quả là bị bot quét được và mất hàng ngàn đô la tiền cloud chỉ sau vài giờ.

Luôn luôn sử dụng biến môi trường. File .env của bạn nên trông như thế này:

AWS_REGION=ap-southeast-1
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_BUCKET_NAME=phamhai-upload-storage-2026

After the file is successfully uploaded and the URL is returned, you need to store this path. For secure and modern database interaction, Prisma ORM Node.js database connection is an excellent tool that helps you store file information in a structured way.

Upload directly from client with Pre-signed URL: Reduce load on server

Create a signed URL from the Node.js backend to authorize the client (like React/Vue) to upload files straight to S3, bypassing the intermediary server.

This is an advanced Client-side upload technique that large systems often use. If a user uploads a 500MB video through your Node.js server and then the server pushes it to S3, you are wasting twice the bandwidth and RAM resources.

Thay vào đó, Node.js sử dụng @aws-sdk/s3-request-presigner để tạo ra một Pre-signed URL có thời hạn (VD: 15 phút). Trình duyệt của người dùng sẽ sử dụng URL này để thực hiện request PUT đẩy file trực tiếp lên S3. Việc upload file bằng pre-signed URL S3 Node.js giải phóng hoàn toàn gánh nặng cho server Express, đặc biệt có lợi khi kết hợp với Transfer Acceleration.

"Half-laughing" situations and how to handle common errors

Cause analysis and troubleshooting instructions for common errors such as access denied, capacity limit exceeded, and network exception handling in Node.js.

During the development process, encountering errors is inevitable. Handling Node.js S3 file upload errors (error handling) well will make your application more professional. Below are classic "diseases" and the ways Pham Hai often uses them to "treat".

"Access Denied" error: Check Bucket policy and IAM permissions

The 403 Access Denied error appears mainly due to misconfigured credentials, missing s3:PutObject permissions in IAM, or the Bucket public access blocking feature being enabled.

Nếu API trả về mã lỗi 403 Access Denied, 99% nguyên nhân nằm ở vấn đề phân quyền. Hãy bình tĩnh kiểm tra lại 3 yếu tố sau: Thứ nhất, Access Key và Secret Key trong file .env đã copy chính xác chưa? Thứ hai, IAM user có được gắn policy cho phép ghi (PutObject) vào đúng tên bucket đó không? Thứ ba, nếu bạn đang cố set ACL public cho file, hãy chắc chắn rằng tab Permissions của Bucket đã tắt tùy chọn "Block all public access".

File size error: Customize limit in Multer

Set the limits property in Multer's configuration to proactively block files that exceed the allowed capacity, protecting the server from memory exhaustion.

To prevent users from intentionally uploading huge junk files that crash the system (especially when using Multer memory storage S3 Node.js), you must limit the file size.

const upload = multer({
    storage: multerS3({...}),
    limits: { fileSize: 1024 * 1024 * 5 } // Giới hạn tối đa 5MB
});

When the file exceeds 5MB, Multer will throw an error. You need to catch this error at the Express.js middleware level and return an error code 413 (Payload Too Large) with a friendly message for the UI to display to the user.

Handle network errors and connection issues to AWS

Use try-catch blocks in combination with automatic retry mechanisms to handle network drops or timeouts when communicating with the Amazon S3 API.

Đôi khi, đường truyền mạng quốc tế chập chờn khiến kết nối từ server Node.js đến AWS bị gián đoạn. Đừng để ứng dụng của bạn bị crash (sập) chỉ vì một lỗi mạng. Hãy luôn bọc logic upload trong khối try...catch. Đối với các hệ thống quan trọng, chúng tôi khuyến khích bạn implement thêm cơ chế tự động retry. Nếu AWS trả về các mã lỗi 5xx (lỗi từ phía server AWS), hệ thống sẽ tự động thử upload lại sau vài giây, giúp trải nghiệm người dùng luôn liền mạch.

With the above knowledge, uploading files to S3 with Node.js and Multer is actually not scary. By flexibly combining these tools, you build a powerful, secure, and easily scalable cloud storage solution. Mastering the file processing flow, configuring credentials security and preparing good error handling scenarios will be the key to your success. Hopefully the real-life experiences from Pham Hai in this article will help you confidently deploy the file upload feature for all projects.

If you have any questions about configuration, or want to share more tips on optimizing your own code, don't hesitate to leave a comment below. I'm always ready to discuss and support!

Lưu ý: Thông tin trong bài viết này chỉ mang tính chất tham khảo. Để có lời khuyên tốt nhất, vui lòng liên hệ trực tiếp với chúng tôi để được tư vấn cụ thể dựa trên nhu cầu thực tế của bạn.

Categories: Lập Trình Web Node.js

mrhai

Để lại bình luận