DockerでRails+React+dynamodb-local環境をつくりたい

# はじめに
以前にGo+React+MySQL環境をつくる記事を投稿したのですが、

https://qiita.com/does_not_exist/items/b79b3fd51ea6ef39df23

GoをRailsに、MySQLをdynamodb-localに変更する機会があったので簡単にまとめてみます。
Reactに関しては同じ手順になるので割愛します

# ディレクトリ準備
```
sample-project
┣ docker
┃   ┣ backend
┃   ┃　┗ Dockerfile
┃   ┣ react
┃　　　 ┗ Dockerfile
┣ .env
┣ docker-compose.yml
```   

# ファイル準備

```.docker/react/Dockerfile
FROM node

RUN apt-get update
```

```.docker/backend/Dockerfile
FROM ruby:2.7.5 as base
RUN apt-get update && apt-get install -y build-essential make
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && apt-get install -y nodejs
RUN npm install --global yarn

RUN mkdir /app
WORKDIR /app

COPY ./backend/Gemfile /app/Gemfile
COPY ./backend/Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY ./backend /app

FROM base as dev
```


```docker-compose.yml
services:
  app:
    build: ./docker/react
    container_name: react_qiita
    tty: true
    working_dir: /usr/src/app
    volumes:
      - ./react:/usr/src/app
    command: sh -c "yarn start"
    ports:
      - "3000:3000"

  rails_qiita:
    build:
      context: .
      dockerfile: ./docker/rails/Dockerfile
      target: dev
    command: bash -c "rm -f tmp/pids/server.pid && yarn install && bundle exec rails s -p 8080 -b '0.0.0.0'"
    volumes:
      - ./backend:/app
    container_name: rails_qiita
    tty: true
    ports:
      - "8080:8080"

  dynamodb-qiita-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-qiita-local
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal

  dynamodb-qiita-admin:
    container_name: dynamodb-qiita-admin
    image: aaronshaf/dynamodb-admin:latest
    environment:
      DYNAMO_ENDPOINT: ${DYNAMO_ENDPOINT}
    ports:
      - "8001:8001"
    depends_on:
      - dynamodb-qiita-local

```


# Rails
Rails用のプロジェクトフォルダを作成し、Gemfile,Gemfile.lockを作成します
```
mkdir backend && cd backend
touch Gemfile Gemfile.lock 
```

```:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'rails'
```

今回はapiモードでbackendフォルダにプロジェクトを作成します
```
rails new . --api
```
Gemfileが更新されるので以下を実行します

```
docker-compose build
docker-compose up
```

localhost:8080にアクセスして以下の画面が表示されていればOKです

![1675661760.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/e160e71a-2f84-122a-d23a-76e55d2260fa.png)



# dynamodb-local
こちらも以前にDockerでdynamodb-local環境を構築する記事を投稿していますが、

https://qiita.com/does_not_exist/items/c937edcab35cff5684a0

ここではRailsとdynamodb-localの疎通確認まで行います

今回も記事と同じくGUIからdynamodb-localを操作できるようにコンテナを2つ立てています
dynamodb-adminのエンドポイントをdynamodb-localに設定することで、GUIから操作できるようになります
そのエンドポイントを環境変数として.envに設定しています

また、dynamodb-localでdb操作をする上で必要なIAMの認証情報も設定します
dynamodb-localに接続するIAMユーザーは一対一であることにも注意します

```.env
DYNAMO_ENDPOINT=dynamodb-qiita-local:8000
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=ap-northeast-1
```

docker-compose upでコンテナを起動すると次のようなエラーが出る場合があります

```
WARNING: [sqlite] cannot open DB[1]: com.almworks.sqlite4java.SQLiteException: [14] unable to open database file
```

この時の解決方法はこちらの記事を参考にしました

https://qiita.com/etnk/items/fff02e8fbf6901e013f9

これはコンテナを起動した際に作成される./docker/dynamodbファイルへのアクセス権限がなくてエラーになっているので、以下を実行して権限問題を解消します

```
sudo chmod 777 ./docker/dynamodb
```

再度コンテナを起動し、localhost:8001にアクセスして以下の画面が表示されていればOKです

![1675662661.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/89b6cab2-4eda-ea4b-b989-49902a01246d.png)


# Railsとdynamodb-localの疎通確認

Gemfileにdynamoidを追加します

```:Gemfile
gem dynamoid
```

IAM認証をするためにaws.ymlとaws.rbを作成します

```backend/config/aws.yml
development:
  access_key_id: ENV['AWS_ACCESS_KEY_ID']
  secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
  region: ENV['AWS_DEFAULT_REGION']
  endpoint: http://dynamodb-qiita-local:8000
```

```backend/config/initializers/aws.rb
Aws.config.update(Rails.application.config_for(:aws).symbolize_keys)
```

次に疎通確認をするためにPostモデルを作成します

```backend/app/models/post.rb
class Post
  include Dynamoid::Document

  table name: :posts, key: :id, capacity_mode: :on_demand
  field :name, :string
end
```

ここまででGemfileが更新されているのと、
uninitialized constantというエラーを回避するためにRailsサーバを再起動する必要があるのでbuildとupをします

```
docker-compose build
docker-compose up
```

Railsが問題なく立ち上がることを確認したら、Railsコンソールに入りレコードを作成してみます

```
$ docker exec -it rails_qiita sh

# rails c

> a=Post.new
> a.id="1"
> a.name="hoge"
> a.save
```

作成に成功するとコンソールでは以下の表示がされます

![1675664600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/7de641c5-6e23-c8e4-2d1c-b06b8624df8c.png)

localhost:8001にアクセスしてみると、テーブルとレコードが作成されていることを確認できます

![1675664625.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/921ff9f1-4414-2393-a77c-2e59d3a8cb1f.png)

また、aws cliでもテーブルとレコードが作成できることを確認してみます

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/getting-started-step-1.html

```
// テーブル作成
aws dynamodb \
  --region ap-northeast-1 \
  --endpoint-url http://localhost:8000 \
    create-table \
  --table-name HogeTable \
  --attribute-definitions \
    AttributeName=userId,AttributeType=N \
    AttributeName=userName,AttributeType=S \
  --key-schema \
    AttributeName=userId,KeyType=HASH AttributeName=userName,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST

// レコード作成
aws dynamodb \
  --region ap-northeast-1 \
  --endpoint-url http://localhost:8000 \
    put-item \
  --table-name HogeTable \
  --item '
    {
      "userId": {
        "N": "1"
       },
      "userName": {
        "S": "ほげ太郎"
      }
    }
  '
```

確認できました

![1675665359.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/3ce79035-f7e7-e9e8-15c6-51dca48f9598.png)



# React
割愛


# おわりに
今後はdynamodb-localの使い方やreactとrailsの疎通などを学んでいきます


# 参考

## Rails関連

https://qiita.com/Nishi53454367/items/aee4cf0c346bc115be99#1-docker-composeymldockerfile%E3%81%AE%E4%BD%9C%E6%88%90

https://qiita.com/kazama1209/items/86c0adc8b6d38fceb36a#localhost3001%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9

## dynamodb-local関連

https://github.com/Dynamoid/dynamoid

https://www.takayasugiyama.com/entry/2020/12/01/023707

https://qiita.com/takuya0301/items/1bda712480b3b86bb93f

## Railsとdynamodb-localの疎通関連

https://tanaaaaka.hatenablog.com/entry/2017/07/06/141829