lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

Mac環境のASP.NET Core MVCでdocker上のMySQLを使用する

概要

MacでのASP.NET Core MVC開発環境構築のためDockerで稼働させたMySQLに接続し開発を行います。

Macからdotnet cliのテンプレートを使用してプロジェクトを作成するとデフォルトでSQLiteがプロジェクトに内包される形で作成されます。
諸事情があり当初Windowsでプロジェクト作成後、Macでの開発を開始したためにSQLiteが内包されておらずDBがない状態だったので思考停止でDockerでMySQLを稼働させるに至りました。

ただ、docker上のMySQLへ接続する際のユーザの接続許可を%ワイルドカード)で指定してしまっているのであくまでローカルでの開発環境用です。
そもそもDocker上で本番DBを稼働させてる事例を僕は知らないけど...
127.0.0.1でユーザを作成しても接続ができなかった。※要検証)

目次

環境

  • MacOS Mojave Version 10.14.3
  • .Net Core SDK Version 2.2.104
  • Docker Version 18.09.2
    • Docker image : MySQL 5.7(公式)

参考リンク

成果物

github.com

Docker on MySQLの準備

コンテナの作成

# MySQLイメージの取得 ※すでに持ってたのであしからず...
$ docker pull mysql:5.7
#docker imageの確認
$ docker images
# コンテナの作成
$ docker run --name bolog-sample -e MYSQL_ROOT_PASSWORD=password -d -p 3306:3306 mysql:5.7
# コンテナ確認
$ docker ps
# コンテナにログイン ※1
$ docker exec -it <CONTAINER ID> bash
# MySQLへログイン ※2
$ mysql -uroot -p

※1、※2:ローカル環境にMySQLをインストールしていないためDockerコンテナ経由でMySQLへログインしている。

スキーマ・必要ユーザの作成

mysql> CREATE DATABASE BLOGSAMPLE;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE USER 'blog_user'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON BLOGSAMPLE.* TO 'blog_user'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

ちょっと記憶違いかもしれませんが'hogehoge'@'127.0.0.1'とした場合にローカルから接続ができなかったため%ワイルドカード)を使用しています。
ただしいろいろ試行錯誤している中でコンテナ作成時のポート番号の設定がミスっていたりする可能性があるので要検証です。(そのうち確かめます。)

ASP.NET Core MVCプロジェクトの準備

プロジェクトの作成

$ dotnet new mvc -n docker-mysql-sample -au Individual

この時点で作成されたプロジェクトにはSQLIteがん内包されているためビルドすれば動きます。

必要パッケージの追加

# DBマイグレーション用ライブラリ(パッケージ)
$ dotnet add package Microsoft.EntityFrameworkCore.Design
# MySQL接続用ライブラリ(パッケージ)
$ dotnet add package Pomelo.EntityFrameworkCore.MySql

接続文字列の追加・接続コードの編集

差分についてはこちらのコミットログを確認いただければわかりやすいかと。
 →add packages and connecting docker mysql · Lycheejam/blog-sample@4c7aa10 · GitHub

appsettings.jsonに接続文字列(DB接続に必要な情報)を追加します。

  • appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "DataSource=app.db",
    //MySQLConnectionを追加
    "MySQLConnection": "server=127.0.0.1;database=BLOGSAMPLE;user=blog_user;password=password"
  }
  //省略
}

デフォルトでSQLiteに接続されるよう設定されているのでDockerで動かしているMySQLに接続されるようStartup.csを編集します。

  • Startup.cs
public void ConfigureServices(IServiceCollection services) {
    //省略
    services.AddDbContext<ApplicationDbContext>(options =>
            //options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
            //上記をコメントアウトし下記を新規追加
            options.UseMySql(Configuration.GetConnectionString("MySQLConnection")));
    //省略
}

ASP.NET Core側の準備は上記で完了

実行

プロジェクトのビルド

# プロジェクトディレクトリにて
$ dotnet build

MySQL(Docker)にテーブルを作成

# プロジェクトディレクトリにて
$ dotnet ef database update

上記コマンドを実行しなかった場合

ビルド&実行後、画面にてRegister(ユーザ登録)を実行すると下記のエラーが発生します。
「DBにテーブル作ってね〜」と促されます。
ちなみに未確認ですがApply Migrationsボタンを押下することでマイグレーションしてくれるっぽい?

A database operation failed while processing the request.
MySqlException: Table 'BLOGSAMPLE.AspNetUsers' doesn't exist 
MySqlException: Table 'BLOGSAMPLE.AspNetUsers' doesn't exist 

Applying existing migrations for ApplicationDbContext may resolve this issue
There are migrations for ApplicationDbContext that have not been applied to the database

f:id:HM_Atlas:20190301005449p:plain

登録確認

画面からユーザ登録を実施し、登録が完了することを確認してください。
また、DBにてテーブルを確認すれば登録情報が確認できます。

雑感

エラー回避の前段として書いてたらただの手順メモになってしまった...
まあいいや。