Sử dụng localstack để giả lập upload file s3

Hí anh em! Tôi saiury92 đây ! Trong một thập niên qua và cũng có thể một vài thập niên tới AWS vẫn làm bố của các Cloud Service Providers, 10 dự án thì tới 9 dự án cần upload file lên Amazon S3. Trong bài viết hôm nay, tôi sẽ giúp các đồng dâm thực hiện việc giả lập upload file s3 ở local mà không cần AWS account. Let’s go !!!!

LocalStack ?

LocalStack là một nền tảng mã nguồn mở cho phép bạn chạy và giả lập các dịch vụ AWS ở local. LocalStack hỗ trợ nhiều dịch vụ AWS khác nhau : S3, Lambda, SNS, ES, SES, API Gateway, …. Dịch vụ cần quan tâm của chúng ta là S3.

Start LocalStack bằng docker ?

Chúng ta có thể setup LocalStack trực tiếp trên máy thông qua pip:

pip install localstack

Nhưng bây giờ là thời đại của containerization, chúng ta mà không sử dụng docker là bị sếp nói là lạc hậu đấy ! Để chạy localstack với docker compose cho S3, anh em có thể sử dụng docker-compose.yml file dưới đây:

version: '3.9'
services:
  localstack:
    image: localstack/localstack:latest
    container_name: localstack_s3_demo
    environment:
      SERVICES: s3
    ports:
      - '127.0.0.1:4566:4566'

Start LocalStack container để sử dụng nào:

docker-compose up -d

Tạo mới một s3 bucket với tên “bucket-demo“:

docker exec -it localstack_s3_demo awslocal s3 mb s3://bucket-demo

Upload file to S3 ?

Để demo việc upload lên file tới S3 tôi sử dụng package @aws-sdk/client-s3 cho gần gũi với đại chúng anh em coder, anh em có thể tham khảo đoạn code dưới đây:

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import fs from "fs";

const S3_AWS_ACCESS_KEY_ID = "dummy";
const S3_AWS_SECRET_KEY = "dummy";
const S3_AWS_BUCKET_NAME = "bucket-demo";
const useLocal = true; // false if not using LocalStack

const client = new S3Client({
  region: "us-east-1",
  endpoint: useLocal ? "http://127.0.0.1:4566" : undefined,
  credentials: {
    accessKeyId: S3_AWS_ACCESS_KEY_ID,
    secretAccessKey: S3_AWS_SECRET_KEY,
  },
});

const params = {
  Bucket: S3_AWS_BUCKET_NAME,
  Key: "example.jpg",
  ContentType: "image/jpeg",
  Body: fs.readFileSync("./example.jpg"),
  s3ForcePathStyle: true,
};

const command = new PutObjectCommand(params);

try {
  const response = await client.send(command);
  console.log(response);
  console.log("File uploaded successfully!");
} catch (error) {
  console.error(error);
}

Start upload file :

 > node upload.js
 
{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'CE5CQBpI8HEwPsSI4pChERwgSYOvFLIjv5xTPbO9Zg1GLEEp80vN',
    extendedRequestId: 'MzRISOwyjmnupAC6A5B7CD242F7B57/JypPGXLh0OVFGcJaaO3KW/hRAqKOpIEEp',
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  ETag: '"2067c44cf823bd1b9c2cb66ba8f407e2"'
}
File uploaded successfully!
 

Sử dụng package@aws-sdk/s3-request-presignerđể lấy presigned URL:

// getSignedUrl.js

import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const S3_AWS_ACCESS_KEY_ID = "dummy";
const S3_AWS_SECRET_KEY = "dummy";
const S3_AWS_BUCKET_NAME = "bucket-demo";
const useLocal = true;

const client = new S3Client({
  region: "us-east-1",
  endpoint: useLocal ? "http://127.0.0.1:4566" : undefined,
  credentials: {
    accessKeyId: S3_AWS_ACCESS_KEY_ID,
    secretAccessKey: S3_AWS_SECRET_KEY,
  },
});

const params = {
  Bucket: S3_AWS_BUCKET_NAME,
  Key: "example.jpg",
  Expires: 3600, // The URL will expire in 3600 seconds.
};

const command = new GetObjectCommand(params);

try {
  const url = await getSignedUrl(client, command);
  console.log(url);
} catch (error) {
  console.error(error);
}

Get presigned URL:

> node getSignedUrl.js

http://127.0.0.1:4566/bucket-demo/example.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dummy%2F20231008%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20231008T100241Z&X-Amz-Expires=900&X-Amz-Signature=73d10095729f1d47feee9926aa0c0d31d086c979206f93b475265bee2dc4cd4f&X-Amz-SignedHeaders=host&x-id=GetObject

Đơn giản thực sự đúng không anh em ! Nếu các đồng chí có bất kỳ thắc mắc hay chạy các đoạn script trên có bất cứ bug nào hãy comment cho mình được biết nha ! Cảm ơn các đồng dâm ! Thân ái và hẹn gặp lại !

0 Shares:
2 comments
  1. Nếu đặt config docker-compose như trên thì sẽ chỉ cài S3 thôi đúng ko a, mình sẽ chỉ định được service muốn cài

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like