Vue.jsとDjango-Rest-Frameworkで神経衰弱アプリを作ってみる【その4】~DockerでMySQL構築およびDBマイグレーション編~

[<< その3](https://qiita.com/Butterthon/items/23b7c0794b5aca4182e9) | [その5 >>](https://qiita.com/Butterthon/items/b87e3cd2d68deff6ce87)

# DockerでMySQLコンテナ作成
プロジェクト直下にdockerフォルダを作成して、そのまた直下にdb_dataフォルダ(別な名前でも良い)とdocker-compose.ymlを作成

```
concentratio # プロジェクトルートディレクトリ
├── config 
│   └── ...
│   
├── docker 
│   ├── db_data # データ永続化用
│   └── docker-compose.yml
└── ...
```

```docker/docker-compose.yml
version: '2'
services:
  db:
    image: mariadb:latest
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    environment:
      - MYSQL_ROOT_USER=root
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=concentratio
      - MYSQL_USER=user
      - MYSQL_PASSWORD=user
    volumes:
      - db_data:/var/lib/mysql # db_dataフォルダの名前を変更している場合は、変更後のフォルダ名で書き換える
      - ./db_data:/docker-entrypoint-initdb.d # db_dataフォルダの名前を変更している場合は、変更後のフォルダ名で書き換える
      - ./db_data:/etc/mysql/conf.d # db_dataフォルダの名前を変更している場合は、変更後のフォルダ名で書き換える
    ports:
      - '3333:3306'

volumes:
  db_data:
    driver: local
```
<font color="red">db_dataフォルダを/docker-entrypoint-initdb.dにマウントしているので、db_dataフォルダに任意のSQLファイルを置いておくと、コンテナ起動時(初回起動時?)にそのSQLファイルを実行してくれます。</font>
　
### dockerコンテナ起動
cdコマンドで`docker`ディレクトリに移動してから`docker-compose up -d`でMySQLコンテナ起動。

```
docker$ docker-compose up -d
Creating docker_db_1 ... done
```
ちなみに
停止は`docker-compose stop`（もしくは`docker stop コンテナID or コンテナ名` ）
削除は`docker-copose down -v`(もしくは`docker rm コンテナID or コンテナ名`)

### MySQLコンテナが起動しているか確認する
```
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
03dd318a2ad7        mariadb:latest      "docker-entrypoint.s…"   29 seconds ago      Up 29 seconds       0.0.0.0:3333->3306/tcp   docker_db_1
```

### MySQL workbenchで接続してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/ce32cff6-c893-0857-f443-ffe96ff61d84.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/60a6cdaa-e12a-9a8b-21dd-dfd14d1e0a0f.png)
接続できたっぽい

# DBマイグレーション
### mysqlclientとdjango-environをpipインストール
```
pip3 install django-environ mysqlclient
```

### .envファイル作成
```
concentratio # プロジェクトルートディレクトリ
├── config 
│   └── ...
│   
├── docker 
│   └── ...
│
├──.env
│
└── ...
```
``` .env.default
DEBUG=True
DATABASE_URL=mysql://user:user@127.0.0.1:3333/concentratio
```

### settings.pyを編集
```config/settings.py
.
..
...
import environ # 追加(django-environをインポート)
.
..
...
# 追加
ENV_FILE = os.path.join(BASE_DIR, '.env') # .envファイルのパス
ENV = environ.Env()
ENV.read_env(ENV_FILE) # django-environで.envファイルを読み込む
...
..
.
# 追加
DATABASES = {
    'default': ENV.db()
}
DATABASES['default']['ATOMIC_REQUESTS'] = True # ATOMIC_REQUESTSをTrueにするとview全体がトランザクションになる（viewの処理中に例外が発生した場合、それまでのDB操作がロールバックされる）。
...
..
.
```

### DBマイグレーション
```
python3 manage.py makemigrations
python3 manage.py migrate
```

migrateコマンドは諸々OKが出ていれば大丈夫です。

```
$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK
```

### 再度MySQL workbenchで確認
djangoの管理テーブルが作成されてます。
DBマイグレーション完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/7543b28e-3eff-2da6-9794-b02c268142be.png)

### スーパーユーザを作成
`python3 manage.py createsuperuser`でスーパーユーザを作成できる。

```
$ python3 manage.py createsuperuser
Username : admin # 適当に設定（今回はadminとする）
Email address: admin@admin.co.jp # 適当に設定（今回はadmin@admin.co.jpとする）
Password: # 適当に設定（今回はadminとする）
Password (again): # 適当に設定（今回はadminとする）
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y # パスワードが簡単だよって警告が出てますが、構わず「y」
Superuser created successfully.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/eb985175-d501-96dd-9565-576ec4fea7cb.png)

ユーザが作成されました。
以上。

[<< その3](https://qiita.com/Butterthon/items/23b7c0794b5aca4182e9)