Débutant6 min de lecture

Exécuter DynamoDB Local avec Docker : le guide complet

DynamoDB Local est l'émulation téléchargeable de DynamoDB par AWS, dans un seul processus — même API, pas de compte AWS, pas de réseau, pas de facture par requête. Utilise-le pour le développement local et les tests d'intégration, puis pointe le même code vers le cloud en production. Il ignore le débit provisionné et ne ralentit jamais, il ne peut donc pas remplacer un test de charge ou de limites.

Comment exécuter DynamoDB Local avec Docker ?

Exécute docker run -p 8000:8000 amazon/dynamodb-local pour démarrer l'image officielle, qui expose le moteur DynamoDB sur http://localhost:8000. Pointe ton SDK AWS ou ta CLI vers cet endpoint avec n'importe quelles fausses informations d'identification, puis crée des tables et exécute des requêtes exactement comme tu le ferais avec le cloud. Ajoute -sharedDb et un volume -dbPath monté pour conserver les données entre les redémarrages.

Démarrer le conteneur

docker run -p 8000:8000 amazon/dynamodb-local

Cela expose le moteur sur http://localhost:8000.

docker-compose

La plupart des projets l'épinglent dans docker-compose.yml pour que toute l'équipe obtienne le même endpoint :

services:
  dynamodb:
    image: amazon/dynamodb-local
    user: root
    command: '-jar DynamoDBLocal.jar -sharedDb -dbPath /data'
    ports:
      - '8000:8000'
    volumes:
      - dynamodb-data:/data
volumes:
  dynamodb-data:

L'image s'exécute sous l'utilisateur non-root dynamodblocal, qui ne peut pas ouvrir un fichier de base de données à l'intérieur du volume nommé appartenant à root — sans user: root, tu tombes sur SQLiteException [14] unable to open database file et chaque appel se bloque.

Persistance

Par défaut, DynamoDB Local est en mémoire — chaque table disparaît à l'arrêt du conteneur. Deux options la rendent durable :

  • -sharedDb maintient tous les clients sur un seul fichier de base de données partagé (sans elle, chaque jeu d'informations d'identification/région obtient sa propre base isolée — une surprise fréquente du type « où est passée ma table ? »).
  • -dbPath /data + un volume monté écrit ce fichier sur le disque, pour que les données survivent à docker compose down.

Pointer le SDK vers lui

Seul l'endpoint change — les informations d'identification peuvent être n'importe quelles fausses valeurs :

import {DynamoDBClient} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({
  endpoint: 'http://localhost:8000',
  region: 'local',
  credentials: {accessKeyId: 'x', secretAccessKey: 'x'}
});

Créer une table

aws dynamodb create-table \
  --endpoint-url http://localhost:8000 \
  --table-name AppData \
  --attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S \
  --key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST

Un schéma PK/SK single-table comme celui-ci est une bonne valeur par défaut. Quand tu charges des fixtures, convertis du JSON brut au format wire avec le convertisseur DynamoDB-JSON.

Vérifie que le conteneur est en marche et que la table a bien été créée :

aws dynamodb list-tables --endpoint-url http://localhost:8000

Parcourir avec une interface graphique

Les appels CLI deviennent vite fastidieux. Les options habituelles sont l'interface web open source dynamodb-admin ou un client de bureau. DynoTable se connecte directement à localhost:8000 (ou à n'importe quel endpoint LocalStack — voir se connecter à DynamoDB Local et LocalStack) et te permet de parcourir, d'interroger avec le et d'éditer des tables locales avec la même interface que celle que tu utilises pour les tables cloud — sans allers-retours avec la CLI aws.

Ce que Local n'émule pas

Traite Local comme une couche de compatibilité API, pas un simulateur de capacité. Il ignore le débit provisionné, ne renvoie jamais ProvisionedThroughputExceededException, et ne modélise pas le comportement de burst on-demand. Un test de charge contre Local ne te dit rien sur les limites de partition ou la capacité adaptative dans AWS.

D'autres écarts apparaissent dans les tests d'intégration si tu ne les anticipes pas :

ComportementDynamoDB LocalAWS DynamoDB
Facturation / RCU / WCUAucuneMesurée par requête
ThrottlingJamaisOui, aux limites table/index
Timing de suppression TTLBest-effort, pas lié à un SLABalayages d'arrière-plan selon le planning AWS
Livraison DynamoDB StreamsSimplifiéeSémantique stream complète + câblage Lambda
Transactions cross-tablesSupportées dans les builds récentsACID complet avec limites documentées
Global Tables / PITRNon disponiblesFonctionnalités de production

Si ton test affirme du throttling, l'expiration TTL en quelques secondes, ou le fan-out de streams, lance au moins une suite contre une table cloud jetable ou LocalStack avec les fonctionnalités dont tu as besoin activées.

Un workflow local pratique

La plupart des équipes câblent Local en trois couches :

  1. Tests unitaires — lance le conteneur en CI, crée les tables dans beforeAll, démonte dans afterAll. Garde les fixtures petites ; marshalle le JSON ordinaire via le convertisseur DynamoDB JSON quand les tests collent des maps d'attributs à la main.
  2. Tests d'intégration — exerce la même factory de client SDK que ton app utilise, en ne swapant que endpoint et credentials. Affirme sur la forme d'item et les écritures conditionnelles, pas sur la capacité consommée (Local ne renvoie pas de ConsumedCapacity significatif pour budgéter).
  3. Exploration manuelle — connecte DynoTable avec un profil Local, prépare des éditions, et lance des requêtes PartiQL ou à condition de clé avant de déployer des changements de schéma.

Quand tu dépasses un seul processus — plusieurs services, triggers S3, ou routage façon IAM — passe à LocalStack ou un compte de dev. Local reste la boucle la plus rapide pour « mon mode d'accès compile-t-il ? ».

Seeder des données sans marshalling à la main

Charger dix items de fixture depuis un fichier JSON est plus rapide quand tu ne tags pas chaque valeur toi-même. Colle le tableau dans le convertisseur DynamoDB JSON, copie la sortie marshallée, et batch-write avec BatchWriteItem contre --endpoint-url http://localhost:8000. Pour des fixtures riches en updates, assemble l'UpdateExpression dans le DynamoDB expression builder et colle les maps d'attributs générées dans ton harness de test.

L'éditeur d'item de DynoTable fait le même marshalling au commit — utile quand un échec de test te laisse regarder des blobs bruts {"S":...} dans la CLI.

Quand quitter Local

Passe à une vraie table quand tu as besoin de l'un des éléments suivants mesuré sur AWS lui-même :

  • Planification de capacité — un item de 1 Ko interrogé 1 000 fois par seconde consomme environ 250 RCU/s à cohérence à terme en facturation on-demand ; Local rapporte zéro. Modélise ça avec le calculateur de tarifs en utilisant les tailles du calculateur de taille d'item.
  • Lag de propagation d'index — les lectures GSI sont à cohérence à terme en production ; Local renvoie les lignes d'index assez vite pour que les bugs de lecture périmée se cachent jusqu'au déploiement.
  • IAM cross-compte — les rôles scopés aux ressources et les clés de condition n'existent que dans le cloud.

Garde Local pour le feedback rapide sur le schéma et la syntaxe d'expression ; valide les hypothèses de coût et de cohérence contre une table de staging avant le trafic de production.

Pièges à scripter autour

  • -sharedDb oublié — chaque paire de credentials unique obtient une base isolée ; la CI et ton laptop ont l'air d'univers différents.
  • Volume appartenant à root sans user: root — le backend SQLite échoue en silence jusqu'à ce que tu ajoutes l'override compose de la section ci-dessus.
  • Supposer la parité Streams — les Lambdas activées sur stream ont besoin d'une cible cloud ou LocalStack ; Local seul n'exercera pas le fan-out.
  • Clés en chaîne vide — autorisées sur les attributs non-clés depuis 2020, toujours rejetées sur les clés ; valide les fixtures comme tu le ferais dans AWS.

Télécharge DynoTable, ajoute un profil pointé sur http://localhost:8000, et parcours les tables que tu viens de créer — la même grille, le même constructeur de filtres et le SQL Workbench que tu utilises en production, avec zéro dépense AWS sur la boucle.

Mis à jour