Floci × Lambda ハンズオン — Function URL・ウォームプール対応のローカル実行【2026年版】

目次
この記事でわかること
- FlociでLambda関数をローカル実行する基本
- Function URL の発行とHTTP呼び出し
- S3 / DynamoDB Streams / SQS トリガーの連携
- ウォームプール・エイリアス・環境変数の扱い
- コールドスタート対策とデバッグTips
FlociはLambdaをDockerコンテナベースで再現します。Function URL・ウォームプール・エイリアスに対応し、S3やDynamoDB Streamsと組み合わせたイベント駆動アーキテクチャのローカル検証に最適です。
Flociの基本は 入門記事 を参照してください。
セットアップ
services:
floci:
image: hectorvent/floci:latest
ports:
- "4566:4566"
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Lambda実行用
- ./floci-data:/app/data
environment:
- FLOCI_STORAGE_MODE=persistent
重要: Lambda関数はFlociがホストのDockerを呼び出して実行するため、/var/run/docker.sock のマウントが必須です。
最小Lambda関数(Python)
handler.py:
def handler(event, context):
return {
"statusCode": 200,
"body": f"Hello {event.get('name', 'world')}!",
}
ZIPにパッケージング:
zip function.zip handler.py
関数作成:
aws lambda create-function \
--function-name hello \
--runtime python3.12 \
--role arn:aws:iam::000000000000:role/lambda-role \
--handler handler.handler \
--zip-file fileb://function.zip \
--endpoint-url http://localhost:4566
呼び出し
aws lambda invoke \
--function-name hello \
--payload '{"name":"Floci"}' \
--cli-binary-format raw-in-base64-out \
response.json \
--endpoint-url http://localhost:4566
cat response.json
# {"statusCode": 200, "body": "Hello Floci!"}
Node.js関数の例
index.mjs:
export const handler = async (event) => ({
statusCode: 200,
body: JSON.stringify({ message: `Hello ${event.name || "world"}` }),
});
zip function.zip index.mjs
aws lambda create-function \
--function-name hello-node \
--runtime nodejs20.x \
--role arn:aws:iam::000000000000:role/lambda-role \
--handler index.handler \
--zip-file fileb://function.zip \
--endpoint-url http://localhost:4566
Function URL
aws lambda create-function-url-config \
--function-name hello \
--auth-type NONE \
--endpoint-url http://localhost:4566
レスポンスの FunctionUrl にcurlで直接アクセスできます:
curl -X POST http://localhost:4566/lambda-url/hello \
-H "Content-Type: application/json" \
-d '{"name":"Floci"}'
環境変数
aws lambda update-function-configuration \
--function-name hello \
--environment Variables="{STAGE=dev,LOG_LEVEL=debug}" \
--endpoint-url http://localhost:4566
エイリアス
バージョン管理と組み合わせてBlue/Greenデプロイの検証:
aws lambda publish-version --function-name hello --endpoint-url http://localhost:4566
aws lambda create-alias --function-name hello --name prod --function-version 1 \
--endpoint-url http://localhost:4566
aws lambda invoke --function-name hello:prod --payload '{}' out.json \
--endpoint-url http://localhost:4566
ウォームプール
コールドスタート削減のためのウォームプール設定:
aws lambda put-provisioned-concurrency-config \
--function-name hello \
--qualifier prod \
--provisioned-concurrent-executions 2 \
--endpoint-url http://localhost:4566
Flociはプロビジョンド同時実行の挙動もローカル検証できます。
S3 → Lambda トリガー
S3へのオブジェクト作成でLambdaを起動:
# バケット作成
aws s3 mb s3://uploads --endpoint-url http://localhost:4566
# Lambda権限付与
aws lambda add-permission \
--function-name hello \
--statement-id s3-invoke \
--action lambda:InvokeFunction \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::uploads \
--endpoint-url http://localhost:4566
# イベント通知
aws s3api put-bucket-notification-configuration \
--bucket uploads \
--notification-configuration '{
"LambdaFunctionConfigurations": [{
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:hello",
"Events": ["s3:ObjectCreated:*"]
}]
}' \
--endpoint-url http://localhost:4566
# オブジェクトアップロードでLambda起動
echo "test" > file.txt
aws s3 cp file.txt s3://uploads/ --endpoint-url http://localhost:4566
DynamoDB Streams → Lambda
aws lambda create-event-source-mapping \
--function-name hello \
--event-source-arn arn:aws:dynamodb:us-east-1:000000000000:table/Users/stream/... \
--starting-position TRIM_HORIZON \
--endpoint-url http://localhost:4566
DynamoDBへのPut/Update/Deleteが自動的にLambdaに配信されます。
SQS → Lambda
aws sqs create-queue --queue-name tasks --endpoint-url http://localhost:4566
aws lambda create-event-source-mapping \
--function-name hello \
--event-source-arn arn:aws:sqs:us-east-1:000000000000:tasks \
--batch-size 10 \
--endpoint-url http://localhost:4566
デバッグTips
ログ確認
aws logs describe-log-streams \
--log-group-name /aws/lambda/hello \
--endpoint-url http://localhost:4566
aws logs get-log-events \
--log-group-name /aws/lambda/hello \
--log-stream-name <stream-name> \
--endpoint-url http://localhost:4566
Lambdaコンテナの直接確認
docker ps | grep floci-lambda
docker logs <container>
Flociが生成したLambda実行コンテナのログを直接参照できます。
よくあるエラー
Docker socket not available
docker-compose.yml に /var/run/docker.sock のマウントが抜けています。必須です。
Runtime.ImportModuleError
ZIP内のディレクトリ構造ミス。handler.py はZIPのルートに置く必要があります。
Function timed out
デフォルト3秒。必要に応じて --timeout 30 を指定して再作成 or update-function-configuration で変更。
コールドスタートが遅い
初回のみDockerイメージpullが発生します。ウォームプール設定で改善可。
FAQ
Q. Lambda Layers は使える?
はい。publish-layer-version で登録し、関数に --layers でアタッチできます。
Q. コンテナイメージLambda(Image runtime)は?
基本的な PackageType=Image に対応しています。ECRの代わりにローカルDockerイメージを指定可能。
Q. VPCやNATの挙動は?
VPC設定は受け付けますが、実ネットワーク分離は行われません。疎通確認のみローカル、挙動確認は実AWSで。
Q. Step Functionsと組み合わせられる?
はい。Flociは Step Functions に対応しており、ステートマシンからLambdaを呼び出せます。
AWS SAM との連携
SAMテンプレートで定義したLambda群をFlociにデプロイする運用例:
template.yaml:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
Hello:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./
Handler: handler.handler
Runtime: python3.12
デプロイは通常のCloudFormation APIを通じて行えるため、aws cloudformation deploy --endpoint-url http://localhost:4566 で適用可能。SAMテンプレートの構文チェックをローカルで完結できます。
Serverless Framework との連携
serverless.yml:
service: my-app
provider:
name: aws
runtime: python3.12
plugins:
- serverless-localstack
custom:
localstack:
stages: [local]
host: http://localhost:4566
serverless-localstack プラグインは Floci でも同じエンドポイント互換で動作します。
コンテナイメージLambda
コンテナベースのLambdaもFlociで検証可能:
FROM public.ecr.aws/lambda/python:3.12
COPY handler.py ${LAMBDA_TASK_ROOT}
CMD ["handler.handler"]
docker build -t my-lambda:latest .
# Floci向けに関数登録(PackageType=Image)
aws lambda create-function \
--function-name image-lambda \
--package-type Image \
--code ImageUri=my-lambda:latest \
--role arn:aws:iam::000000000000:role/lambda-role \
--endpoint-url http://localhost:4566
ECRプッシュ不要でローカルDockerイメージを直接指定できる点がFlociの強みです。
Lambda Layers
共通ライブラリをLayer化して複数関数で共有:
mkdir -p python
pip install requests -t python/
zip -r layer.zip python/
aws lambda publish-layer-version \
--layer-name common-libs \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.12 \
--endpoint-url http://localhost:4566
aws lambda update-function-configuration \
--function-name hello \
--layers arn:aws:lambda:us-east-1:000000000000:layer:common-libs:1 \
--endpoint-url http://localhost:4566
テスト戦略
ユニットテスト(pytest + moto)
Lambdaハンドラー単体の高速テスト:
from moto import mock_aws
from handler import handler
@mock_aws
def test_handler():
res = handler({"name": "test"}, None)
assert res["statusCode"] == 200
統合テスト(Floci)
import json, boto3
def test_lambda_integration():
lam = boto3.client("lambda", endpoint_url="http://localhost:4566",
region_name="us-east-1",
aws_access_key_id="test", aws_secret_access_key="test")
res = lam.invoke(FunctionName="hello",
Payload=json.dumps({"name": "CI"}).encode())
body = json.loads(res["Payload"].read())
assert "Hello CI" in body["body"]
リモートデバッグ(Python)
Flociが起動するコンテナ内のLambdaに debugpy でアタッチ:
# handler.py 冒頭
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client()
def handler(event, context):
...
Lambda関数の --environment にデバッグポートを露出させ、VSCodeから attach 設定でブレークポイントデバッグが可能です。
実運用シナリオ
APIバックエンドのCIテスト
- PR作成 → GitHub Actions で Floci 起動
- SAMで全Lambda関数デプロイ
- PytestでAPI Gateway経由の統合テスト実行
- 終了時にコンテナ破棄
マイグレーション検証
- 本番移行前にFloci上でLambda × DynamoDB × S3 × SNS の完全なE2Eを実行
- データパイプラインのリトライ挙動・DLQ転送を事前検証
本番Lambdaとの差異
- VPC・セキュリティグループの本当の分離は再現されない
- Cold start時間は本番より大幅に短い
- IAM実行ロールの条件評価は簡略化
- Provisioned Concurrency の課金挙動は再現されない
- X-Ray トレースは未対応
まとめ
- FlociはLambdaをDockerベースで再現し、Function URL・エイリアス・ウォームプール対応
- S3 / DynamoDB Streams / SQS トリガー連携でイベント駆動のE2Eテストが可能
/var/run/docker.sockのマウントが必須の初期つまずきポイント- VPC・IAM細部など本番相当検証は実AWSで