使用 LocalStack 在本地模擬 AWS 服務,加速開發測試流程,減少雲端開支
專案簡介
LocalStack 是一個完整的 AWS 雲端模擬器,可在本地執行。支援 S3、Lambda、DynamoDB、SQS 等數十種 AWS 服務,讓開發者能在不連接真實 AWS 的情況下開發和測試。
GitHub Stars: 64K+
主要功能
- 本地 AWS - 模擬 80+ AWS 服務
- 快速迭代 - 無需等待雲端部署
- 節省成本 - 減少開發環境費用
- 離線開發 - 不需網路連線
- CI/CD 整合 - 自動化測試
快速開始
Docker Compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| version: '3.8'
services:
localstack:
image: localstack/localstack
ports:
- "4566:4566"
- "4510-4559:4510-4559"
environment:
- SERVICES=s3,lambda,dynamodb,sqs,sns
- DEBUG=1
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "./localstack:/var/lib/localstack"
|
Docker Run
1
2
3
4
| docker run --rm -it \
-p 4566:4566 \
-p 4510-4559:4510-4559 \
localstack/localstack
|
AWS CLI 設定
設定 Profile
1
2
3
4
5
| aws configure --profile localstack
# AWS Access Key ID: test
# AWS Secret Access Key: test
# Default region name: us-east-1
# Default output format: json
|
使用 Endpoint
1
| aws --endpoint-url=http://localhost:4566 s3 ls
|
別名設定
1
2
| # ~/.bashrc 或 ~/.zshrc
alias awslocal='aws --endpoint-url=http://localhost:4566'
|
常用服務
S3
1
2
3
4
5
6
7
8
| # 建立 Bucket
awslocal s3 mb s3://my-bucket
# 上傳檔案
awslocal s3 cp file.txt s3://my-bucket/
# 列出檔案
awslocal s3 ls s3://my-bucket/
|
Lambda
1
2
3
4
5
6
| # lambda_function.py
def handler(event, context):
return {
'statusCode': 200,
'body': 'Hello from LocalStack!'
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 打包
zip function.zip lambda_function.py
# 建立函數
awslocal lambda create-function \
--function-name my-function \
--runtime python3.9 \
--handler lambda_function.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::000000000000:role/lambda-role
# 呼叫
awslocal lambda invoke \
--function-name my-function \
response.json
|
DynamoDB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 建立表格
awslocal dynamodb create-table \
--table-name Users \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
# 新增項目
awslocal dynamodb put-item \
--table-name Users \
--item '{"id": {"S": "1"}, "name": {"S": "John"}}'
# 查詢
awslocal dynamodb scan --table-name Users
|
SQS
1
2
3
4
5
6
7
8
9
10
11
| # 建立佇列
awslocal sqs create-queue --queue-name my-queue
# 發送訊息
awslocal sqs send-message \
--queue-url http://localhost:4566/000000000000/my-queue \
--message-body "Hello SQS"
# 接收訊息
awslocal sqs receive-message \
--queue-url http://localhost:4566/000000000000/my-queue
|
SNS
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 建立主題
awslocal sns create-topic --name my-topic
# 訂閱
awslocal sns subscribe \
--topic-arn arn:aws:sns:us-east-1:000000000000:my-topic \
--protocol sqs \
--notification-endpoint arn:aws:sqs:us-east-1:000000000000:my-queue
# 發布訊息
awslocal sns publish \
--topic-arn arn:aws:sns:us-east-1:000000000000:my-topic \
--message "Hello SNS"
|
Provider 設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| provider "aws" {
access_key = "test"
secret_key = "test"
region = "us-east-1"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
s3 = "http://localhost:4566"
lambda = "http://localhost:4566"
dynamodb = "http://localhost:4566"
sqs = "http://localhost:4566"
sns = "http://localhost:4566"
iam = "http://localhost:4566"
}
}
|
部署資源
1
2
| terraform init
terraform apply
|
Python 整合(Boto3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import boto3
# 建立 LocalStack 客戶端
s3 = boto3.client(
's3',
endpoint_url='http://localhost:4566',
aws_access_key_id='test',
aws_secret_access_key='test',
region_name='us-east-1'
)
# 使用 S3
s3.create_bucket(Bucket='my-bucket')
s3.put_object(Bucket='my-bucket', Key='test.txt', Body='Hello')
|
環境變數方式
1
2
3
4
5
6
7
| import os
os.environ['AWS_ENDPOINT_URL'] = 'http://localhost:4566'
os.environ['AWS_ACCESS_KEY_ID'] = 'test'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'test'
import boto3
s3 = boto3.client('s3') # 自動使用環境變數
|
CI/CD 整合
GitHub Actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| name: Test with LocalStack
on: [push]
jobs:
test:
runs-on: ubuntu-latest
services:
localstack:
image: localstack/localstack
ports:
- 4566:4566
env:
SERVICES: s3,lambda,dynamodb
steps:
- uses: actions/checkout@v4
- name: Run tests
env:
AWS_ENDPOINT_URL: http://localhost:4566
run: |
pip install boto3 pytest
pytest tests/
|
pytest-localstack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # conftest.py
import pytest
import boto3
@pytest.fixture
def s3_client():
return boto3.client(
's3',
endpoint_url='http://localhost:4566',
aws_access_key_id='test',
aws_secret_access_key='test'
)
# test_s3.py
def test_create_bucket(s3_client):
s3_client.create_bucket(Bucket='test-bucket')
buckets = s3_client.list_buckets()
assert 'test-bucket' in [b['Name'] for b in buckets['Buckets']]
|
進階設定
持久化資料
1
2
3
4
5
6
| services:
localstack:
environment:
- PERSISTENCE=1
volumes:
- "./localstack-data:/var/lib/localstack"
|
啟用特定服務
1
2
| environment:
- SERVICES=s3,lambda,dynamodb,sqs
|
Pro 功能
LocalStack Pro 提供更多服務:
- ECS、EKS
- RDS、ElastiCache
- API Gateway v2
- Cognito
相關連結
延伸閱讀