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

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

関連記事