Tous les articles
Mer. 8 avril 2026 · 4 min de lecture

🪣 LocalStack et Ministack : un AWS complet sur sa machine

LocalStack

📚 Introduction

Travailler avec AWS au quotidien pose deux problèmes récurrents : les coûts qui s’accumulent sur les environnements de dev et de CI, et la dépendance au réseau pour la moindre boucle de test. Tester une intégration S3 ou un consumer SQS depuis sa machine en TER ou en avion devient un calvaire.

LocalStack émule la majorité des services AWS dans un seul conteneur Docker. Depuis la version 2026.03.0, une seule image (localstack/localstack) est publiée, et le démarrage requiert désormais un LOCALSTACK_AUTH_TOKEN pour la plupart des services au-delà du tier gratuit. Ministack, apparu en mars 2026 dans la foulée de ce repositionnement, est une alternative MIT-licensed qui vise les 55+ services AWS, avec la particularité de spawner de vrais conteneurs pour RDS, ElastiCache ou ECS plutôt qu’un mock.

Dans les deux cas, l’idée est identique : pointer le SDK AWS sur un endpoint local (port 4566 par défaut), et continuer à coder comme si l’on parlait au vrai AWS.

🚀 Démarrer un LocalStack en 30 secondes

LocalStack se lance avec un simple docker-compose.yml, calqué sur l’exemple officiel actuel :

services:
  localstack:
    container_name: localstack-main
    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
      - PERSISTENCE=1
    volumes:
      - ./.localstack:/var/lib/localstack
      - /var/run/docker.sock:/var/run/docker.sock

Un docker compose up -d plus tard, on dispose d’une API AWS écoutant sur http://localhost:4566. Toutes les opérations classiques fonctionnent :

aws --endpoint-url=http://localhost:4566 s3 mb s3://invoices
aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name billing
aws --endpoint-url=http://localhost:4566 dynamodb list-tables

🪶 Ministack : la version “tactique”

Ministack vise une niche complémentaire : une image Docker de l’ordre de 150 Mo, un démarrage annoncé autour de 2 secondes, et ~30 Mo de RAM au repos. Côté installation, deux options :

# Via PyPI
pip install ministack && ministack
 
# Via Docker (recommandé pour la CI)
docker run -p 4566:4566 ministackorg/ministack

L’endpoint reste http://localhost:4566, identique à LocalStack, et les SDK AWS ne voient aucune différence. C’est l’option que je sélectionne sur les pipelines GitHub Actions, là où l’image LocalStack alourdit le temps de boot. Pour la persistance entre redémarrages :

docker run -p 4566:4566 \
  -e PERSIST_STATE=1 \
  -v ministack-state:/tmp/ministack-state \
  ministackorg/ministack

🧰 Exemple complet : S3 + SQS depuis Laravel

Voyons un cas pratique : une application Laravel qui dépose un fichier sur S3, puis publie un message SQS pour déclencher un traitement asynchrone. Configuration dans config/filesystems.php :

'disks' => [
	's3' => [
		'driver' => 's3',
		'key' => env('AWS_ACCESS_KEY_ID'),
		'secret' => env('AWS_SECRET_ACCESS_KEY'),
		'region' => env('AWS_DEFAULT_REGION', 'eu-west-3'),
		'bucket' => env('AWS_BUCKET'),
		'endpoint' => env('AWS_ENDPOINT'),
		'use_path_style_endpoint' => true,
	],
],

Côté .env.local, on cible LocalStack :

AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=invoices
AWS_ENDPOINT=http://localhost:4566
SQS_QUEUE=http://localhost:4566/000000000000/billing

Et un job Laravel qui combine les deux :

final class UploadInvoiceAndNotify
{
	public function handle(Invoice $invoice): void
	{
		Storage::disk('s3')->put(
			"invoices/{$invoice->id}.pdf",
			$invoice->renderPdf()
		);
 
		BillingQueue::push(new InvoiceUploaded($invoice->id));
	}
}

Tout ce qui passait avant par les serveurs AWS passe maintenant par votre Docker local. Aucune ligne de code applicatif à toucher entre dev et production : seules les variables d’environnement changent.

🧪 Intégration dans la CI

Sur GitHub Actions, Ministack se prête particulièrement bien au pattern services: :

services:
  ministack:
    image: ministackorg/ministack
    ports:
      - 4566:4566
    env:
      PERSIST_STATE: 0

Les tests d’intégration s’exécutent contre une vraie API AWS (locale), pas contre un mock partiel. Le delta de fiabilité est significatif : on attrape des erreurs de signature, de permissions IAM ou de format de message qu’un mock laisserait passer.

⚠️ Limites à connaître

  • LocalStack n’est plus “gratuit par défaut” depuis la version 2026.03.0 : un LOCALSTACK_AUTH_TOKEN est requis pour la majorité des services au-delà du tier de base. Sur les projets perso ou les pipelines CI exigeants, c’est souvent le déclencheur pour basculer sur Ministack.
  • Le comportement d’IAM est partiel par défaut. Pour tester les permissions à fond, activer ENFORCE_IAM=1 sur LocalStack.
  • Ministack émule différemment : certains services (RDS, ElastiCache, ECS) lancent de vrais conteneurs Docker, donc nécessitent que le socket Docker soit monté (/var/run/docker.sock) et consomment plus de ressources que les mocks purs.
  • Les latences réseau de production ne se reproduisent pas en local : restez prudents sur les hypothèses de performance.

🎉 Conclusion

LocalStack reste l’option historique quand on veut couvrir le périmètre AWS le plus large, services payants inclus. Ministack se distingue sur les CI et les setups où l’on veut un démarrage rapide, une licence MIT et un comportement plus fidèle pour RDS ou ElastiCache (vrais conteneurs au lieu de mocks).

Dans les deux cas, la règle d’or est la même : faites en sorte que votre code n’ait jamais à savoir s’il parle à LocalStack, à Ministack ou au vrai AWS. Une simple variable d’environnement doit suffire à basculer. Et pour orchestrer tout ça depuis une CI, la pipeline GitHub Actions que je décris ici s’intègre parfaitement avec un service Ministack monté en parallèle.

🔗 Liens utiles

/faq

Questions fréquentes

Quelle différence entre LocalStack et Ministack ?

+

LocalStack émule la majorité des services AWS dans un conteneur Docker mais requiert un LOCALSTACK_AUTH_TOKEN depuis la version 2026.03.0. Ministack, apparu en mars 2026, est une alternative MIT-licensed visant 55+ services, qui spawne de vrais conteneurs pour RDS, ElastiCache ou ECS plutôt qu'un mock.

Sur quel port l'API AWS locale est-elle exposée ?

+

Dans les deux cas, l'endpoint est http://localhost:4566 par défaut. Il suffit de pointer le SDK AWS sur cet endpoint local et de continuer à coder comme si l'on parlait au vrai AWS.

LocalStack est-il toujours gratuit ?

+

Non : depuis la version 2026.03.0, LocalStack n'est plus « gratuit par défaut » et un LOCALSTACK_AUTH_TOKEN est requis pour la majorité des services au-delà du tier de base, ce qui pousse souvent à basculer sur Ministack pour les projets perso ou les CI.