【DynamoDB】【Docker】docker-composeでDynamoDBとDjangoの開発環境を構築する


docker-composeでDynamoDBとDjangoの開発環境を構築する

はじめに

DynamoDBって安くて早くていいですよね。そんなDynamoDBをローカルで開発するためのDockerImageがあるってご存知ですか?そんなDockerImageを利用した開発環境構築の一例を照会します。

環境

プロダクション環境に即して利用するイメージのバージョンは以下です。
DynamoDBのGUI操作用にdynamodb-adminを利用します。Nodeはその環境を一緒に構築する際に利用します。

環境 バージョン
Python 3.7.4
MySQL 5.7
Node 10.16.3-alpine

環境構築

DjangoとMySQL

完全にゼロから構築するのでまずはDjangoプロジェクトを開始します。
公式のDjangoイメージはバージョンが古いので自分で作ります。

$ django-admin startproject dynamodb_example
$ cd dynamodb_example/
$ touch docker-compose.yml
$ touch Dockerfile
FROM python:3.7.4

RUN apt-get update
RUN apt-get install -y --no-install-recommends apt-utils gettext
RUN mkdir /app; mkdir /app/dynamodb_example

WORKDIR /app
COPY dynamodb_example /app/dynamodb_example
COPY requirements.txt /app/
COPY manage.py /app/

RUN pip install -r requirements.txt

EXPOSE 8080
CMD ["python", "manage.py", "runserver", "0.0.0.0:8080"]
docker-compose.yml
version: "3"
services:
  mysql:
    container_name: example-mysql
    ports:
      - 53306:3306
    image: mysql:5.7
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./persist/mysql:/var/lib/mysql
    restart: always
    environment:
      MYSQL_USER: example
      MYSQL_PASSWORD: example
      MYSQL_DATABASE: example
      MYSQL_ROOT_PASSWORD: example

  django:
    container_name: example-django
    build: .
    volumes:
      - .:/app
    working_dir: /app
    command: sh -c "./wait-for-it.sh db:3306; python3 manage.py runserver 0.0.0.0:8000"
    env_file: .env
    ports:
      - 58080:8000
    depends_on:
      - mysql

ポートが50000台なのは絶対被りたくないからです。とくに意味はありません。
DynamoDBと接続するためのライブラリはboto3とそれをWrapしているpynamodbを入れておきます。

requirements.txt
boto3
pynamodb
Django==2.2.4
djangorestframework==3.10.3
django-filter
mysqlclient==1.3.13

環境変数の意味をあまりなしていないですが一応…

DB_ENGINE=django.db.backends.mysql
DB_HOST=mysql
DB_DATABASE=example
DB_USERNAME=root
DB_PASSWORD=example
DB_PORT=3306

とりあえずDjangoとMySQLの疎通を確認したいのでDjangoのDATABASESを書き換えます。

setting.py
DATABASES = {
    'default': {
        'ENGINE': os.getenv('DB_ENGINE'),
        'NAME': os.getenv('DB_DATABASE'),
        'USER': os.getenv('DB_USERNAME'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'OPTIONS': {
            'init_command': 'SET foreign_key_checks = 0;',
            'charset': 'utf8mb4',
        },
    }
}

ここまで来たらとりあえず起動するか確認します。

$ docker-compose up -d
$ docker-compose exec django bash
$ python manage.py migrate

問題なければ、次にDynamoDB Localdynamodb-adminを入れてきます。

DynamoDB Local

docker-compose.ymlにdynamodbを記載します。
永続化ようにコマンドの最後にdbPathを指定します。

docker-compose.yml
  dynamodb:
    container_name: example-dynamodb
    image: amazon/dynamodb-local
    command: -jar DynamoDBLocal.jar -dbPath /home/dynamodblocal/data
    volumes:
      - ./persist/dynamodb:/home/dynamodblocal/data
    ports:
      - 50706:8000

dynamodb-admin

公式イメージがあったのですが、作ってしまったのでそちらを利用します。

$ mkdir dynamodb-admin
$ touch dynamodb-admin/Dockerfile
$ touch dynamodb-admin/.env
FROM node:10.16.3-alpine

RUN ["apk", "update"]
RUN ["npm", "install", "dynamodb-admin", "-g"]

EXPOSE 50727
CMD ["dynamodb-admin", "-p", "50727"]

環境変数のDYNAMO_ENDPOINTにはdynamodbのコンテナーサービス名とコンテナ側のポートを指定します。

DYNAMO_ENDPOINT=http://dynamodb:8000
AWS_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=ACCESS_ID
AWS_SECRET_ACCESS_KEY=ACCESS_KEY

このdyanamodb-adminを加えた最終的なdocker-compose.ymlファイルは以下のようになります。

docker-compose.yml
version: "3"
services:
  dynamodb:
    container_name: example-dynamodb
    image: amazon/dynamodb-local
    command: -jar DynamoDBLocal.jar -dbPath /home/dynamodblocal/data
    volumes:
      - ./persist/dynamodb:/home/dynamodblocal/data
    ports:
      - 50706:8000
  dynamodb-admin:
    container_name: example-dynamodb-admin
    build: dynamodb-admin/
    command: dynamodb-admin -p 8000
    env_file: dynamodb-admin/.env
    ports:
      - 50727:8000
    depends_on:
      - dynamodb
  mysql:
    container_name: example-mysql
    ports:
      - 53306:3306
    image: mysql:5.7
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./persist/mysql:/var/lib/mysql
    restart: always
    environment:
      MYSQL_USER: example
      MYSQL_PASSWORD: example
      MYSQL_DATABASE: example
      MYSQL_ROOT_PASSWORD: example
  django:
    container_name: example-django
    build: .
    volumes:
      - .:/app
    working_dir: /app
    command: sh -c "./wait-for-it.sh db:3306; python3 manage.py runserver 0.0.0.0:8000"
    env_file: .env
    ports:
      - 58080:8000
    depends_on:
      - mysql
      - dynamodb

http://localhost:50727をブラウザで表示して以下のように表示されていれば成功です。

Create Table等したい放題です。

永続化の確認

適当にテーブルを作ってみます。

作成されました。

コンテナーを削除して再起動します。

$ docker-compose down
$ docker-compose up -d

http://localhost:50727を開いて先程のテーブルが残っていれば永続化もうまく行っています。

最後に

このリポジトリーは以下で公開します。今後更新するかもしれないのでtagは1.0.0です。
https://github.com/Cohey0727/example_dynamodb
もしよければ利用してください。