每天进步一点:配置localstack本地测试AWS功能

in #cn11 months ago (edited)

今天开始试用localstack,感觉非常好用。用localstack开发AWS应用非常方便,下面把整个过程记录一下。整个过程是基于这个英文教程的,但下面只是我自己的理解和笔记,并不是对英文教程的翻译。

localstack

LocalStack是什么?

Localstack允许你在本地尝试一系列的AWS服务,而无需担心费用问题。

  • 支持离线方式
  • 你无需和他人共享AWS资源,这样想怎么搞就怎么搞,不用担心影响到别人
  • 轻松管理本地资源
  • 完全免费
  • 尝试AWS服务而不需要AWS账号

设置

首先确保安装了Docker, AWS CLI, 然后确保运行了aws configure来生成并保存相关密码。

接下来创建一个项目,比如“test1", 并在该项目中创建一些文件:

mkdir test1
cd test1
touch index.js docker-compose.yml .env
mkdir .localstack

复制一个图片,比如:test.jpg 到项目目录下。

进行npm配置和安装配套AWS 包:

npm init 
npm install aws-sdk dotenv

编辑 docker-compose.yml 并添加如下内容:

version: '3.2'
services:
  localstack:
    image: localstack/localstack:latest
    container_name: localstack_demo
    ports:
      - '4563-4599:4563-4599'
      - '8055:8080'
    environment:
      - SERVICES=s3
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
    volumes:
      - './.localstack:/tmp/localstack'
      - '/var/run/docker.sock:/var/run/docker.sock'

启动docker容器:

docker-compose up 

等个2分钟左右你就可以在浏览器中访问 localstack 界面了: http://localhost:8055/

对于本地的AWS S3,可以通过如下端口访问: http://localhost:4572/

现在你就可以在本地测试AWS的服务了!

通过localstack来测试AWS S3服务

通过localstack来创建一个S3 bucket:

aws --endpoint-url=http://localhost:4572 s3 mb s3://demo-bucket

注意:这里的 --endpoint-url 参数指定了 localstack 中对应的 s3 访问路径。

在 localstack 的日志中,你会看到如下信息:

localstack_demo | 2019-12-06 15:10:14,909:API: 127.0.0.1 - - [06/Dec/2019 15:10:14] "PUT /demo-bucket HTTP/1.1" 200 

在 localstack S3 的Web界面中,你可以看到:

<Buckets>
<Bucket>
<Name>demo-bucket</Name>
<CreationDate>2006-02-03T16:45:09.000Z</CreationDate>
</Bucket>
</Buckets>

为S3 bucket添加访问控制列表ACL:

aws --endpoint-url=http://localhost:4572 s3api put-bucket-acl --bucket demo-bucket --acl public-read

现在,你的S3 bucket就对外公开了。

现在你可以检查一下这个文件: .localstack/data/s3_api_calls.json

{"a": "s3", "m": "PUT", "p": "/demo-bucket", "d": "XXXXXXXX", "h": {"host": "localhost", "Accept-Encoding": "identity", "User-Agent": "aws-cli/1.16.183 Python/3.6.9 Linux/4.15.
0-72-generic botocore/1.12.253", "X-Amz-Date": "20191206T151014Z", "X-Amz-Content-SHA256": "xxxx", "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXX, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=xxxx", "Content-Length": "153", "X-Forwarded-For": "172.30.0.1, 0.0.0.0:4572", "content-type": "binary/octet-str
eam"}}
{"a": "s3", "m": "PUT", "p": "/demo-bucket?acl", "d": "", "h": {"host": "localhost", "Accept-Encoding": "identity", "x-amz-a
cl": "public-read", "User-Agent": "aws-cli/1.16.183 Python/3.6.9 Linux/4.15.0-72-generic botocore/1.12.253", "X-Amz-Date": "
20191206T151327Z", "X-Amz-Content-SHA256": "xxxx", "Authorizatio
n": "AWS4-HMAC-SHA256 Credential=xxxx", "Content-Length": "
0", "X-Forwarded-For": "172.30.0.1, 0.0.0.0:4572", "content-type": "binary/octet-stream"}}

可以看到,你的所有操作都被记录了下来。

编辑 .env 文件,并添加如下内容:

AWS_ACCESS_KEY_ID='123'
AWS_SECRET_KEY='xyz'
AWS_BUCKET_NAME='demo-bucket'

其实这里 AWS key & secret 填什么都可以,只要不是空字符串就行。localstack 并不进行身份验证.

创建文件: aws.js

const AWS = require('aws-sdk')
require('dotenv').config()

const credentials = {
   accessKeyId: process.env.AWS_ACCESS_KEY_ID,
   secretAccessKey: process.env.AWS_SECRET_KEY,
}

const useLocal = process.env.NODE_ENV !== 'production'

const bucketName = process.env.AWS_BUCKET_NAME

const s3client = new AWS.S3({
   credentials,

   endpoint: useLocal ? 'http://localhost:4572' : undefined,
   s3ForcePathStyle: true,
})

const uploadFile = async (data, fileName) =>
   new Promise((resolve) => {
      s3client.upload(
         {
            Bucket: bucketName,
            Key: fileName,
            Body: data,
         },
         (err, response) => {
            if (err) throw err
            resolve(response)
         },
      )
   })

module.exports = uploadFile

创建文件 test-upload.js:

const fs = require('fs')
const path = require('path')
const uploadFile = require('./aws')

const testUpload = () => {
    const filePath = path.resolve(__dirname, 'test.jpg')
    const fileStream = fs.createReadStream(filePath)
    const now = new Date()
    const fileName = `test-image-${now.toISOString()}.jpg`
    uploadFile(fileStream, fileName).then((response) => {
        console.log(":)")
        console.log(response)
    }).catch((err) => {
        console.log(":|")
        console.log(err)
    })
}

testUpload()

运行如下命令进行测试:

node test-upload.js

从docker日志中你可以看到对应的图片路径,例如:

http://localhost:4572/demo-bucket/test-image-2019-12-06T15%3A28%3A57.037Z.jpg

如果再次检查文件: .localstack/data/s3_api_calls.json, 你会看到图片被转换为二进制数据并被存储。

Sort:  

Hi, @aafeng!

You just got a 0.96% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.