LocalStackは、AWSのAPIリクエストを手元のDockerコンテナで受け取り、S3やDynamoDBといったサービスの応答を返すエミュレータです。AWS CLIやSDKの接続先を切り替えるだけで使えるため、クラウドへ課金せずに実装とテストを回せます。ただし2026年3月23日にCommunityエディションが終了し、認証トークンの登録が前提になりました。この記事ではdocker composeでの起動からS3操作、Terraformとcdklocalの向け先変更、GitHub Actionsへの組み込みまでを公式ドキュメントで追い、変わった料金体系と採用可否の判断基準まで整理しました。
まとめ:有料化後のLocalStackを続ける条件と外す判断の分かれ目
手元でAWSを再現する価値が費用を上回るのは、開発者が数人規模で、S3・DynamoDB・SQS・Lambdaといった定番サービスを毎日何十回も叩き直すチームです。1回のデプロイ検証に数分待たされる状況が消え、課金を気にせず作り直せます。公式の料金ページによると商用利用の入口はBaseで、1ライセンスあたり月39ドル(年払い時)、月払いなら月45ドルです。5人のチームを年払いで揃えると年額およそ2,340ドルで、AWS上に検証アカウントを維持する費用と比べて特別に高くはありません。
一方で外す判断になるのは、AWS側の権限設計やサービス固有の挙動が案件の中心にある場合です。IAMポリシーの実行はBase以上でしか有効にならず、無償のHobbyでは権限エラーを再現できません。ここを検証したい案件でHobbyのまま進めると、ローカルで全て通ったコードが本番で権限不足に落ちます。
もう一つの分かれ目が商用かどうかです。Hobbyは非商用利用に限定され、受託開発の案件では使えません。無償のまま続けたいならApache-2.0で配布されているmotoへ寄せる方が筋が通ります。
LocalStackがAWS APIをDockerコンテナで受ける仕組みと対応サービス
LocalStackは、AWSのエンドポイントを模したHTTPサーバーをコンテナ内に立てる仕組みです。AWSの実体を持ってくるのではなく、APIの応答を再現します。
4566番ポートで全サービスのAPIを受ける単一エンドポイントの構造
公式のInstallationページに載っているdocker runの例では、127.0.0.1:4566:4566 と 127.0.0.1:4510-4559 をホストへ公開しています。4566番が全サービス共通のエッジポートで、S3もDynamoDBもSQSも同じポートへサービス名込みのリクエストを送ります。ポートをサービスごとに覚える必要はありません。
同じ例では /var/run/docker.sock もコンテナへマウントします。LambdaやECSのように実行環境を別コンテナとして起動するサービスがあり、ホスト側のDockerを呼び出せないと一部の機能が動きません。この設計はコンテナとは?仮想マシンとの違いからDocker・企業の導入判断まで解説で整理した仮想化の考え方をそのまま踏襲しています。
Hobby・Base・Ultimateで変わる対応サービス数と機能の線引き
どのAWSサービスを再現できるかはプランで決まります。公式の料金ページでは、Hobbyが30以上、Baseが55以上、Ultimateが110以上のサービスをエミュレートすると表記されています。EnterpriseはLocalStack for AWSの全サービスと全機能が対象です。
機能面の線引きはさらに明確です。同ページの比較表を2026年9月時点の表記で並べると次のようになります。
| 項目 | Hobby | Base | Ultimate | Enterprise |
|---|---|---|---|---|
| 月額(年払い時・1ライセンス) | 無料 | 39ドル | 89ドル | カスタム |
| 月額(月払い・1ライセンス) | 無料 | 45ドル | 提供なし | カスタム |
| 対応サービス数 | 30以上 | 55以上 | 110以上 | 全サービス |
| 商用利用 | 不可 | 可 | 可 | 可 |
| IAMポリシー実行 | なし | あり | あり | あり |
| Cloud Pods容量 | なし | 300MB | 3GB | 5GB |
| AWS Replicator | なし | なし | あり | あり |
検証したいサービスがどの帯にあるかは、契約前にLocalStack Plansのページで確認してください。AthenaやEMR、Glueといった分析系はUltimate以上の扱いです。CI/CDでの実行自体は全プランで可能と明記されており、プラン選びを分けるのはサービスの顔ぶれと機能の2点になります。
docker composeでLocalStackを起動しS3バケットを作る手順
公式ドキュメントはlstkという新しいCLIを推奨していますが、チームで環境を揃えるならリポジトリに置けるdocker composeが扱いやすいでしょう。
compose.ymlに書く最小構成とLOCALSTACK_AUTH_TOKENの渡し方
最小構成は、イメージにlocalstack/localstackを指定し、4566番ポートを公開し、認証トークンを環境変数で渡すだけです。Auth Tokenのドキュメントには、Docker Composeでの渡し方として LOCALSTACK_AUTH_TOKEN を environment に書く方法が示されています。
services:
localstack:
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566"
- "127.0.0.1:4510-4559:4510-4559"
environment:
- LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN}
- DEBUG=0
volumes:
- "./volume:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
タグを省くと最新版が降ってきます。公式ドキュメントはバージョン固定時に localstack/localstack:<version> の形を案内しており、チーム全員の環境を揃えるならタグを明示する方が事故が減るでしょう。起動後は http://localhost:4566/_localstack/info を叩き、トークンが通っているかを確認します。
awslocalコマンドでS3バケットを作成し一覧を確認する流れ
接続先の切り替えは、AWS CLIに --endpoint-url を付けるだけで済みます。ただし全コマンドに付けて回るのは現実的ではないため、エンドポイントを固定したラッパーのawslocalを入れるのが定番です。
# AWS CLI をそのまま使う場合
aws --endpoint-url=http://localhost:4566 s3 mb s3://demo-bucket
aws --endpoint-url=http://localhost:4566 s3 ls
# awslocal を入れた場合(--endpoint-url は不要)
pip install awscli-local
awslocal s3 mb s3://demo-bucket
awslocal s3 cp ./report.csv s3://demo-bucket/
awslocal s3 ls s3://demo-bucket/
認証情報は実在しない値で構いません。署名の中身を厳密に見ないため、AWS_ACCESS_KEY_ID=test のようなダミーで通ります。ここが実AWSとの大きな違いです。鍵の取り違えによる事故が起きない代わりに、権限を絞った状態の検証もできません。実AWS上でのS3やDynamoDBの組み立て方はAWS サーバーレス ハンズオン|Lambda・DynamoDB・API GatewayでREST APIを作る手順【2026年版】で扱っています。
TerraformとAWS CDKのエンドポイントをLocalStackへ向ける設定
実務ではIaCのコードごと検証したい場面がほとんどです。プロバイダ側の向け先を差し替えます。
Terraformのprovider awsにendpointsを書いて向け先を変える
Terraformでは、awsプロバイダのブロックにendpointsを並べてサービスごとのURLを指定します。あわせて認証情報のダミー化と、アカウントIDやリージョンの検証をスキップする設定を入れます。
provider "aws" {
region = "ap-northeast-1"
access_key = "test"
secret_key = "test"
skip_credentials_validation = true
skip_requesting_account_id = true
s3_use_path_style = true
endpoints {
s3 = "http://localhost:4566"
dynamodb = "http://localhost:4566"
sqs = "http://localhost:4566"
lambda = "http://localhost:4566"
}
}
s3_use_path_style を有効にする理由は、仮想ホスト形式のURLだとバケット名がサブドメインへ入り、localhost宛てでは名前解決に失敗するためです。ここを落とすとS3だけ動きません。本番用の定義と切り替える方法はTerraformでAWSを構築する手順|aws 6系の認証とS3バックエンド設計を併せて見てください。
cdklocalとtflocalが肩代わりする書き換えの範囲
endpointsを毎回書くのが煩雑なら、ラッパーを使う手があります。tflocalはTerraform用、cdklocalはAWS CDK用で、いずれも実行時にエンドポイントとダミー認証情報を注入し、素の terraform や cdk と同じ感覚で動かせます。
pip install terraform-local aws-cdk-local
tflocal init
tflocal apply -auto-approve
cdklocal bootstrap
cdklocal deploy
ラッパーが肩代わりするのは接続先の差し替えだけです。どのリソースタイプが再現されるかはプランの対応サービスに依存するため、CDKで書いたスタックがそのまま通るとは限りません。AWS CDK(cdk)とは?仕組み・使い方とCloudFormation・Terraformとの違いのとおりCDKはCloudFormationテンプレートへ変換されるので、未対応リソースが1つ混ざればデプロイ全体が止まります。
GitHub ActionsのジョブでLocalStackを起動し統合テストを回す構成
プルリクエストごとにAWS相当の統合テストを流せるようになると、実アカウントを共有して順番待ちする状況がなくなります。
servicesでコンテナを立てヘルスチェックを待ってからテストする書き方
GitHub Actionsのservicesにlocalstackを置き、起動完了を待ってからテストを実行します。待たずに走らせると、最初の数テストだけ接続拒否で落ちる不安定なジョブになります。
jobs:
integration:
runs-on: ubuntu-latest
services:
localstack:
image: localstack/localstack
ports:
- 4566:4566
env:
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: wait for localstack
run: |
for i in $(seq 1 30); do
curl -sf http://localhost:4566/_localstack/health && exit 0
sleep 2
done
exit 1
- name: run integration tests
env:
AWS_ENDPOINT_URL: http://localhost:4566
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
run: pytest tests/integration
ワークフローの基本的な組み立て方はGitHub Actionsでビルド・自動テストを設定する方法|CI/CDワークフローの作り方で解説しているので、ジョブ分割やキャッシュの設計はそちらに委ねます。
CIトークンをSecretsに置きフォークPRで落ちる問題を避ける設定
認証トークンのドキュメントでは、CI環境ではCIプロバイダのシークレットマネージャーへ保存するよう案内されています。GitHub Actionsであればリポジトリシークレットです。ただし外部フォークからのプルリクエストにはシークレットが渡らない仕様があり、OSSとして公開しているリポジトリではこのジョブだけ必ず失敗します。
回避策は、フォーク由来のイベントではジョブをスキップする条件を付けるか、メンテナの手動承認を挟む運用にするかの二択です。なお料金改定を告知した公式ブログでは、CIクレジットの上限が撤廃され、フェアユースの範囲で全プランが無制限に実行できると説明されています。実行回数を気にしてジョブを間引く設計はもう要りません。パイプライン全体の考え方はCI/CDとは:仕組み・パイプライン構成・GitHub Actionsの設定例と導入判断の基準を解説に整理しています。
2026年3月23日のCommunity終了と商用利用で必要になるプランの実額
ここが、2025年以前に書かれた解説記事と現状が食い違う部分です。「無料で使えるAWSエミュレータ」という説明は、2026年3月23日を境に成り立たなくなりました。
Hobbyが非商用限定になったことで受託開発が使えなくなった範囲
公式ブログの告知によれば、2026年3月23日をもってLocalStack for AWSのCommunityエディションのサポートが終了しました。同時に、配布はDocker Hub経由の単一イメージへ集約され、利用にはユーザーアカウントと認証トークンが必要になっています。トークン無しで docker run するだけ、という以前の導線は残っていません。
後継の無償枠がHobbyですが、ライセンスページの記載では対象が非商用利用に限られます。受託開発で顧客のシステムを作る作業は商用利用にあたり、この枠には入りません。個人の学習や趣味のプロジェクトはHobby、業務で1行でも書くならBase以上、という線引きです。学生にはGitHub Education認証を条件としたStudent枠、コミュニティのOSSプロジェクトには審査を経たスポンサーシップ枠が別にあります。
Base 39ドルとUltimate 89ドルの差と人数で増えるライセンス費用
ライセンスは個々のユーザーへ割り当てる方式です。つまり人数分だけ買う必要があります。Baseは1ライセンスあたり月39ドル(年払い時)で、月払いを選ぶと月45ドル。Ultimateは月89ドルで、月払いの提供はありません。
見積もりに落とすと、バックエンド3人とインフラ1人の4人チームでBaseを年払いした場合は年額およそ1,872ドルです。Ultimateが必要な担当が1人混ざれば、その1人分が月89ドルへ上がります。有料プランの新規利用者には30日間のトライアルがあるので、対象サービスがBaseの範囲に収まるかは契約前に実コードで確かめてください。プランを1段上げるより検証対象のサービスを絞る方が安く済む場面は珍しくありません。
Cloud Podsの300MB・3GB・5GBという保存容量で決まる使い方
Cloud Podsは、LocalStackの状態を丸ごと保存して他の開発者やCIと共有する機能です。容量はBaseが300MB、Ultimateが3GB、Enterpriseが5GBで、Hobbyには付きません。
300MBは、テスト用マスタデータとDynamoDBのテーブル定義を詰める程度なら十分ですが、S3へ数百MBのファイルを置いた状態の保存には足りません。CIの前処理でシードデータを流し込む設計にすれば、Podに載せるのは構成定義だけで済み、Baseの容量でも回せます。容量を理由にプランを上げる前に、状態をコードから再生成できる形にする方が費用面で有利でしょう。
IAM強制とサービス差でLocalStackの検証結果が本番とずれる場面
エミュレータである以上、本番と完全には一致しません。どこがずれるかを把握しないまま進めると、ローカルで全て緑なのに本番で落ちます。
IAMポリシー実行がBase以上でHobbyでは権限エラーを再現できない点
料金ページの機能比較では、IAMポリシー実行がBase以上の機能として明記されています。裏を返せばHobbyでは全てのAPIコールが権限チェックを通過します。バケットポリシーの記述を間違えていても、ロールに必要なアクションを付け忘れていても、ローカルでは通ってしまうということです。
本番デプロイ後にAccessDeniedで初めて気づく事故はここから生まれます。権限設計そのものが案件の論点になるなら、Hobbyは選択肢から外してください。IAMを含めて検証したいのにライセンス費用は抑えたい、という条件は両立しません。
エミュレーション差で通ってしまうテストと本番で初めて出る失敗
権限以外にも、実サービス側の制約が再現されない領域があります。整合性モデル、スロットリングやレート制限、サービスクォータ、リージョン間のレイテンシ、料金の発生条件などです。ローカルでは一瞬で返るDynamoDBの書き込みが、本番ではキャパシティを超えてスロットリングされる、といった差が典型です。
LocalStackで確認できるのは、APIの呼び出し方とアプリケーションのロジックが正しいかまでです。性能特性と上限値の検証は実AWS上の環境でしか意味を持ちません。どこまで代替物に置き換えるかという問題は、モックとは?スタブとの違い・テストダブル5分類と単体テストでの使い分けを実装者向けに解説で整理したテストダブルの使い分けと同じ構図になります。高機能なフェイクであって、本番の代わりではありません。
motoとAWS実アカウントを含めた3案の比較とLocalStackを見送る条件
選択肢はLocalStackだけではありません。無償で続ける道と実AWSを使う道が残ります。
motoをpipで入れてmoto_serverを5000番で動かす軽量な選択肢
motoはApache-2.0ライセンスで配布されているAWSモックライブラリです。本来はPythonのテスト内でデコレータとして使いますが、Server Modeのドキュメントによれば、moto_server コマンドで単独のHTTPサーバーとしても起動できます。既定ポートは5000で、Python以外のSDKからも利用できます。
pip install 'moto[ec2,s3,all]'
moto_server -p3000
moto_server -H 0.0.0.0
接続側はboto3で endpoint_url='http://localhost:5000' を指定するか、新しめのSDKなら AWS_ENDPOINT_URL 環境変数で一括指定できます。Dockerを立てる必要がなくCIでの起動も速い代わりに、対応サービスの粒度とCloud Podsのような共有機能ではLocalStackに届きません。単体テストの延長でS3やSQSを偽装したいだけなら、motoで足ります。
LocalStackの採用を見送ってよい3つの条件と代わりに置く手段
次の3条件のいずれかに当てはまるなら、LocalStackを入れない判断で構いません。
- 検証したいAWSサービスがS3・SQS・DynamoDBなど数個に収まり、テストがPython中心である。motoで代替でき、ライセンス費用が要りません。
- 案件の論点がIAM権限設計・クォータ・性能特性にある。エミュレータでは判断材料が得られず、実AWSの検証アカウントを用意する方が確実です。
- 開発者が10人を超え、全員が毎日AWSを叩くわけではない。人数分のライセンスが要るため、共有の検証アカウントを1つ持つ方が安くなる場合があります。
逆に、開発者が数人でサービスの顔ぶれがBaseに収まり、CIで毎コミット統合テストを回したいなら費用対効果は高いままです。マネージドサービスを多数つなぐ構成の向き不向きはサーバーレスとは?仕組み・メリットとコンテナとの使い分けを解説で整理しました。検証環境の設計とクラウド基盤の構築をまとめて任せたい場合は、AWS・Google Cloud・Azureのインフラ構築でご相談いただけます。
よくある質問
導入検討でよく挙がる論点を、2026年9月時点の公式ドキュメントに沿って整理しました。
LocalStackは今でも無料で使えますか?
非商用利用に限れば無料のHobbyプランが使えます。ただし2026年3月23日にCommunityエディションのサポートが終了し、利用にはユーザーアカウントと認証トークンの登録が必要になりました。トークン無しでコンテナを起動するだけ、という以前の使い方は残っていません。受託開発や社内システムの開発といった商用利用は、Hobbyの対象外です。この場合は1ライセンスあたり月39ドル(年払い時)のBase以上を契約する必要があります。
LocalStackとmotoはどちらを選ぶべきですか?
対象サービスが数個でテストがPython中心ならmotoで足ります。Apache-2.0ライセンスで費用がかからず、moto_server を5000番で立てれば他言語のSDKからも叩けるためです。一方、Lambdaの実行やCloudFormation経由のデプロイまで通しで確認したい場合や、状態をCloud Podsでチームに配りたい場合はLocalStackが有利です。判断の軸は無料かどうかではなく、再現したい範囲がAPIの応答までか、実行環境まで含むかにあります。
LocalStackのエンドポイントはサービスごとに違いますか?
いいえ、4566番が全サービス共通のエッジポートです。S3でもDynamoDBでもSQSでも、同じ http://localhost:4566 に対してリクエストを送れば、LocalStack側でサービスを振り分けます。公式のdocker run例では4510から4559番も公開していますが、これは一部の機能が個別ポートを使うためのもので、通常のAPI操作で意識する必要はありません。AWS CLIなら --endpoint-url か、awslocalコマンドを使います。
CIでLocalStackを回すと追加費用はかかりますか?
2026年3月23日の改定で、CIクレジットの上限は撤廃されました。公式ブログの告知では、フェアユースポリシーの範囲内で全プランがCI実行を無制限に使えると説明されています。プランごとの実行回数を気にしてジョブを間引く設計は不要です。ただしCIで使う場合も認証トークンは必要で、GitHub Actionsならリポジトリシークレットへ保存します。外部フォークからのプルリクエストにはシークレットが渡らないため、その経路ではジョブが失敗します。
LocalStackで通ったテストは本番でも同じ結果になりますか?
なりません。IAMポリシーの実行はBase以上の機能で、Hobbyでは権限チェックが働かないため、ポリシーの不備があっても通過します。加えてスロットリング、サービスクォータ、結果整合性のタイミング、リージョン間のレイテンシは再現されません。LocalStackで検証できるのはAPIの呼び出し方とアプリケーション側のロジックまでで、性能特性と上限値は実AWS上の検証環境で確かめる必要があります。
関連記事
- AWS サーバーレス ハンズオン|Lambda・DynamoDB・API GatewayでREST APIを作る手順【2026年版】:LocalStackで再現する構成を実AWS上で組む手順です
- TerraformでAWSを構築する手順|aws 6系の認証とS3バックエンド設計:向け先を切り替える前提となるプロバイダ設定を扱っています
- AWS CDK(cdk)とは?仕組み・使い方とCloudFormation・Terraformとの違い:cdklocalが肩代わりする本体側の仕組みです
- GitHub Actionsでビルド・自動テストを設定する方法|CI/CDワークフローの作り方:統合テストを載せるワークフローの組み立て方です
- モックとは?スタブとの違い・テストダブル5分類と単体テストでの使い分けを実装者向けに解説:エミュレータをどこまで代替物として使うかの整理です