20200623のMySQLに関する記事は8件です。

【Rails】 本番環境MySQLデータを開発環境に入れた後に消す方法

はじめに

本番環境にMySQLのデータを開発環境に入れる時には特にエラーもなくインプットすることができたのですが、消す時になってエラーが発生してハマってしまいました。
少し珍しいケースかもしれませんが、他の方の参考になればと思いまとめることにしました。

関連リンク

そもそも本番環境のMySQLのデータをどうやって開発環境に入れるのかという記事は下記をご参照ください。

エラー

開発環境でDB自体を削除するコマンドを実行したところ、、、

$ rails db:drop

エラーActiveRecord::ProtectedEnvironmentErrorが出ました。。。

このエラーの意味は、

本番環境のDBを操作しようとしているが問題ないですか?

という警告のようなもので、環境変数を入れると操作を続けることができるよ。と言ってます。

そもそも開発環境なんですけど、なんで本番環境と出るんですか??

rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate:reset => db:drop => db:check_protected_environments
(See full trace by running task with --trace)

結論

先に結論から書いてしまいますが、

Rails5では MySQLに環境変数を格納しており、本番環境のデータをそのまま開発環境に入れたことにより、MySQLの環境変数に本番環境の変数が格納されてしまったため、上記のエラーがでてしまいました。

なので、解決する方法としては、MySQLの環境変数を本番環境のものから開発環境のものに書き換えればいいということです。

解決手順

MySQLに接続します。

$ mysql -h db -u root -p

存在するデータベースを確認します。

$ show databases;

対象のデータベースを指定します。

$ use *******;

データベースないのテーブルの一覧を表示します。

$ show tables;

テーブル一覧の中にar_internal_metadataがあると思います。
この中に、環境変数を格納しています。

+---------------------------------------------------+
| Tables_in_scm_development                         |
+---------------------------------------------------+
| ar_internal_metadata                              |
| ...                                               |
+---------------------------------------------------+

ar_internal_metadataの中身をみてみると、

$ select * from ar_internal_metadata;

見つけましたproductionの文字を。

+-------------+-------------+---------------------+---------------------+
| key         | value       | created_at          | updated_at          |
+-------------+-------------+---------------------+---------------------+
| environment | production  | 2020-01-10 09:37:29 | 2020-01-10 09:37:29 |
+-------------+-------------+---------------------+---------------------+

このproductiondevelopmentへ修正します。

$ update ar_internal_metadata set value='development'

もう一度、ar_internal_metadataの中身をみてみると、

$ select * from ar_internal_metadata;

環境変数はdevelopmentに変更できました。

+-------------+-------------+---------------------+---------------------+
| key         | value       | created_at          | updated_at          |
+-------------+-------------+---------------------+---------------------+
| environment | development | 2020-01-10 09:37:29 | 2020-01-10 09:37:29 |
+-------------+-------------+---------------------+---------------------+

MySQLから抜けて

$ exit

もう一度、DBを削除するコマンドを実行。すると成功しました!

$ rails db:drop

まとめ

つらつらと手順を書いたので、人によっては理解しづらいかもしれませんが、困っている誰かの役に立てばなーと思います。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「数GBのdumpいつ終わるんやろか」

TL;DR

  • プログレスバー表示するには pv使ったらいいよ
  • brew install pvでインストールできるよ
  • mysqldump <parameters> | pv --progress --size 100m > dumpfile.sql

さあdumpだ

「よーし、mysqldump叩くぞー」
「userとhost、databaseとport指定して、と」

MYSQL_PWD=$DUMP_DB_PASSWORD mysqldump -u $DUMP_DB_USER -h $DUMP_DB_HOST -P $DUMP_DB_PORT --set-gtid-purged=OFF --column-statistics=0 > $DUMP_FILE

「そんでもってこいつを.shファイルにして、」
「よし、これでいつでもdumpし放題や!」

「よっしゃ、叩くでー」

$  sh dump.sh

「楽しみやな」

「…」

$  sh dump.sh

「…」

「そういや、このDBって確か数GBのサイズやったな・・・」

「…」

$  sh dump.sh

「(果たしていつ頃終わるんやろか・・・・)」

せや!

「せや!プログレスバーを表示したればええんや!」

mysql dump progressbarで、検索っと」

mysql - Does mysqldump support a progress bar? - Stack Overflow
image.png

「ほう、pvってのを使ってやればええんか」

「macはbrewでインストールできるんやな。 brew install pvでインストールして、っと!」

「あとはこいつに組み込んでやるだけ・・・」

「どうやら、大体のファイルサイズを指定するとそいつを100%で表示してくれるみたいや」

「確か2GBくらいあったはずや」

MYSQL_PWD=$DUMP_DB_PASSWORD mysqldump -u $DUMP_DB_USER -h $DUMP_DB_HOST -P $DUMP_DB_PORT --set-gtid-purged=OFF --column-statistics=0 $DUMP_DATABASE | pv --progress --size 2000m  > $DUMP_FILE

「よし、こいつを実行や!」

$ sh dump.sh
[>                                                                              ]  0%

「く、長い・・・。でもプログレスバーを得たワイなら待てる。待てるはずや。」

$ sh dump.sh
[=====================================================================>         ] 95%

「終わる、終わるぞーーー!」

[================================================================================] 109%

「あ、あれ、、、」

[================================================================================] 149%

「(こいつ一体なんGBのデータ持ってるんや・・・!?)」

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker+Rails6+MySQL+Nginx環境構築メモ

はじめに

弊社では未だにdockerを導入しておらず、このままだとマズいと思ったので勉強も兼ねて環境構築してみました。
ミスや間違った説明をしている箇所があるかもしれませんが、優しくご指摘頂けると助かります。
既に環境構築系の記事は出ていますが、実際試しても上手くいかないことがあったので自分の経験もまとめておきます。

流れ

  • "rails new"でプロジェクト作成
  • "git init"でローカルリポジトリ作成
  • GitHubにてリモートリポジトリ作成
  • リモートリポジトリにプッシュ

-----ここから書きます-----
- EC2インスタンス作成
- gitインストール
- dockerインストール
- docker起動
- リモートリポジトリをプル

  • イメージのビルド(docker-compose build --no-cache)
  • コンテナ作成,起動(docker-compose up -d)
  • マイグレーション(docker-compose exec sample-app_web_1 bundle exec rails db:migrate)

gitのインストール

Gitをインストールします

$ sudo yum install git
$ git clone https://github.com/satou-yuuki/sample-app.git

dockerのインストール

AWS公式に従ってDockerをインストールします
参考:https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html

$ sudo yum update -y
$ sudo amazon-linux-extras install docker
$ sudo systemctl start docker.service または sudo service docker start
$ sudo usermod -a -G docker ec2-user
一度ターミナルを抜けるとグループが追加されていると思います

docker-composeのインストール

docker公式に従ってdocker-composeをインストールします
参考:https://docs.docker.com/compose/install/

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

docker-compose build

$ docker-compose build --no-cache

docker-compose up

$ docker-compose up -d

rails db:migrate

$ docker exec sample-app_web_1 bundle exec rails db:migrate

ブラウザから確認

ブラウザで http://host/users を確認するとエラー画面が表示されてしまったのでログを確認します。

Started GET "/users" for 111.239.186.32 at 2020-06-22 00:17:50 +0000
Cannot render console from 111.239.186.32! Allowed networks: 127.0.0.0/127.255.255.255, ::1
Processing by UsersController#index as HTML
  Rendering users/index.html.erb within layouts/application
  User Load (0.4ms)  SELECT `users`.* FROM `users`
  ↳ app/views/users/index.html.erb:16
  Rendered users/index.html.erb within layouts/application (Duration: 3.8ms | Allocations: 1537)
[Webpacker] Compiling...
[Webpacker] Compilation failed:
yarn run v1.22.4
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.


error Command "webpack" not found.

Completed 500 Internal Server Error in 1573ms (ActiveRecord: 0.9ms | Allocations: 23784)



ActionView::Template::Error (Webpacker can't find application in /sample-app/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}
):
     6:     <%= csp_meta_tag %>
     7: 
     8:     <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     9:     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    10:   </head>
    11: 
    12:   <body>

app/views/layouts/application.html.erb:9

ググった結果以下のコマンドを実行で解決しました。
babelやpostceeなど各種設定ファイルの生成とyarn addを実行してくれるようです。
ただ設定ファイルはrails newした時点で存在していたのでyarn addする必要があるみたいですね。

yarn add @rails/webpacker@4.2.2 from "."
yarn add --dev webpack-dev-server from "."

$ docker exec bundle exec rails webpacker:install
    conflict  config/webpacker.yml
Overwrite /sample-app/config/webpacker.yml? (enter "h" for help) [Ynaqdhm] n
        skip  config/webpacker.yml
Copying webpack core config
       exist  config/webpack
   identical  config/webpack/development.js
   identical  config/webpack/environment.js
   identical  config/webpack/production.js
   identical  config/webpack/test.js
Copying postcss.config.js to app root directory
   identical  postcss.config.js
Copying babel.config.js to app root directory
   identical  babel.config.js
Copying .browserslistrc to app root directory
   identical  .browserslistrc
The JavaScript app source directory already exists
       apply  /usr/local/bundle/ruby/2.5.0/gems/webpacker-4.2.2/lib/install/binstubs.rb
  Copying binstubs
       exist    bin
   identical    bin/webpack
   identical    bin/webpack-dev-server
File unchanged! The supplied flag value not found!  .gitignore
Installing all JavaScript dependencies [4.2.2]
         run  yarn add @rails/webpacker@4.2.2 from "."
yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.13: The platform "linux" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > webpack-dev-server@3.11.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...
success Saved 0 new dependencies.
Done in 49.21s.
Installing dev server for live reloading
         run  yarn add --dev webpack-dev-server from "."
yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "linux" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0".
warning " > webpack-dev-server@3.11.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[4/4] Building fresh packages...
success Saved 1 new dependency.
info Direct dependencies
└─ webpack-dev-server@3.11.0
info All dependencies
└─ webpack-dev-server@3.11.0
Done in 4.67s.
Webpacker successfully installed ? ?

もう一度ブラウザから確認するとユーザー一覧画面が表示されていました!
ログを見るとwebpackでコンパイルされていることが分かります。

Started GET "/users" for 111.239.186.32 at 2020-06-22 00:24:31 +0000
Cannot render console from 111.239.186.32! Allowed networks: 127.0.0.0/127.255.255.255, ::1
   (17.7ms)  SET  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
Processing by UsersController#index as HTML
  Rendering users/index.html.erb within layouts/application
  User Load (8.9ms)  SELECT `users`.* FROM `users`
  ↳ app/views/users/index.html.erb:16
  Rendered users/index.html.erb within layouts/application (Duration: 10.6ms | Allocations: 731)
[Webpacker] Compiling...
[Webpacker] Compiled all packs in /sample-app/public/packs
[Webpacker] Hash: 15d1bb7b54cf6326b9ba
Version: webpack 4.43.0
Time: 2988ms
Built at: 06/22/2020 12:24:36 AM
                                     Asset       Size       Chunks                         Chunk Names
    js/application-9afcbb5693aa87623e69.js    124 KiB  application  [emitted] [immutable]  application
js/application-9afcbb5693aa87623e69.js.map    139 KiB  application  [emitted] [dev]        application
                             manifest.json  364 bytes               [emitted]              
Entrypoint application = js/application-9afcbb5693aa87623e69.js js/application-9afcbb5693aa87623e69.js.map
[./app/javascript/channels sync recursive _channel\.js$] ./app/javascript/channels sync _channel\.js$ 160 bytes {application} [built]
[./app/javascript/channels/index.js] 211 bytes {application} [built]
[./app/javascript/packs/application.js] 749 bytes {application} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 552 bytes {application} [built]
    + 3 hidden modules

Completed 200 OK in 5083ms (Views: 5073.4ms | ActiveRecord: 8.9ms | Allocations: 6105)

まとめ

勉強して分かったことを追記していく予定です。一旦ここまで。
誰かの参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Metabase+MySQLをdocker-composeで立ち上げる

こんばんは、@0yanです。
OSSのBIツール「Metabase」のDockerイメージからコンテナを立ち上げ、ローカルホストのMySQLサーバーに接続しようと思っていたのですが、DockerコンテナからローカルホストのMySQLサーバーに接続するのに苦戦したため方針変更。
docker-composeでMetabaseのDockerイメージとMySQLのDockerイメージから立ち上げることにしました。
本記事はそのやり方をまとめたものです。

環境

  • Windows 10 Pro
  • Docker Desktop for Windows 2.3.0.3
  • PowerShell

構成

ディレクトリの構成は以下のようにしました。

├── db
|   ├── data
|   ├── sql
│   └── my.cnf
|
├── app
│   └── data
|
└── docker-compose.yml

各種ファイルの作成

①docker-compose.yml

MySQLとMetabaseは公式イメージを使用します。

docker-compose.yml
version: '3'

services:

  db:
    image: mysql:5.7
    container_name: mysql-server
    environment: 
      MYSQL_ROOT_PASSWORD: xxxx
      MYSQL_DATABASE: test_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      TZ: 'Asia/Tokyo'
    ports:
      - 3306:3306
    volumes:
      - ./db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./db/data:/var/lib/mysql
      - ./db/sql:/docker-entrypoint-initdb.d

  app:
    image: metabase/metabase:latest
    container_name: metabase
    ports:
      - 3000:3000
    volumes:
      - ./app/data:/mnt/data

②my.cnf

MySQLで日本語を使用したいので、文字コードの設定をしてます。

my.cnf
[mysqld]
character-set-server=utf8

[client]
default-character-set=utf8

コンテナ立ち上げ

docker-compose.ymlがあるディレクトリで以下のコマンドを実行、起動します。

PS > docker-compose up -d
Creating mysql-server ... done
Creating metabase     ... done

PS > docker-compose ps                                                                            Name                 Command             State                 Ports
--------------------------------------------------------------------------------------
metabase       /app/run_metabase.sh          Up      0.0.0.0:3000->3000/tcp
mysql-server   docker-entrypoint.sh mysqld   Up      0.0.0.0:3306->3306/tcp, 33060/tcp

Metabase起動

1分程度待機した後、ブラウザでlocalhost:3000にアクセスすると下の画面が表示されますので「開始しましょう」をクリックします。
image.png

下の画面で管理者情報を登録して「次へ」をクリックします。
image.png

下の画面で「データベースを選択する」をクリックし、MySQLを選択します。
image.png

下の画面が表示されますので、下表の内容を入力します。
image.png

項目          入力内容   
名前           任意の名前 
ホスト          db     
ポート          3306
データベース名      test_db
データベースユーザー名 user
データベースパスワード password

下の画面で「次へ」をクリックします(匿名の情報収集は許容する場合のみオンにしてください)。
image.png

下の画面で「Metabaseを使い始める」をクリックします。
image.png

MySQL接続確認

起動すると下の画面になります。
右上の「照会する」をクリックします。
image.png

下の画面で「ネイティブクエリ」をクリックします。
image.png

下の画面で接続したデータベースの名前(上表でご自身が付けた名前。私はテストデータベースという名前にしました)をクリックします。
image.png

下の画面になりますので、任意のSQL文を入れてみてください。
image.png

なお、複数のSQL文を同時実行はできません(例えば以下のようなSQL文はNGです)。
一文ずつ実行するようにしてください。

create table employee (employee_no integer, employee_name varchar(30));
insert into employee values (1, 'Taro Yamada');
select * from employee;

さいごに

「会社の数字をMetabaseでビジュアル化する」という目標のもと、
- docker
- docker-compose
- MySQL
と学んできましたが、やっと現実化できそうです。
今度はこの内容をEC2上で実行したいと思います。

参考記事

docker-compose でMySQL環境簡単構築

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Equalumがやって来た!(展開編2)

今回は各機能の検証と少し複雑な(?)FLOWを作ってみる!

前回の検証で、Equalumを使うと複雑なコーディングを実施しないで、データベースを含むSQL周辺の基本が抑えられていれば、誰でもリアルタイム・ストリーミングをデータ処理のプロセスに活用出来る事が確認出来ました。そこで今回はこのデータ処理を便利に行う為に、標準で提供されている幾つかのオペレーターに関する基本的な検証を行ってみたいと思います。

まずはJOINから・・

JOINはデータベースを取り扱った経験をお持ちの方であれば、その概要や留意点についての基本的な情報は理解されていると思いますので、この場ではそれらの詳細についての解説は割愛させて頂き、Equalumではどう使うのか?について検証して行きます。
まずは、前回同様にEvent Stream形式のソース側を2個用意します。
j1.jpg

j2.jpg

次にOperatorメニューからJOINを選択します。

j3.jpg
j4.jpg

先ほど設置したEvent Streamを接続します。

j5.jpg

JoinにあるEditボタンを選択して必要事項を設定します。

j6.jpg
修正が必要な個所が赤字で指示されますので、適宜それらを修正して行きます。今回はidとtsが衝突していますので、この場所で編集作業を行います。編集は、各項目の右端にある編集アイコンを選択して行います。
j7.jpg
j8.jpg

JOINのタイプはプルダウンメニューで選択できます。今回はInnerで検証してみます。
次にConditionの項目にJOINの条件を設定します。今回はデータのIDで強制的に突合させてしまいます。

j9.jpg

最後に、ストリーミング処理ならでは(?)の条件を忘れずに設定しておきます。

j10.jpg
Time Windowについては調整項目になる様ですが、今回の小規模環境では1を設定して検証しました。

次にターゲットのデータソースを定義します。

j11.jpg

ここまでくれば、Joinとターゲットを接族してターゲット側のEditボタンを選択して、前回同様の設定を行って行けばOKです。テーブル定義もこの場所で自動的にSQL文を生成してくれますので、問題が無ければ確認してそのまま利用できますが、今回の検証では事前定義したテーブルに着地させる事にします。
j12.jpg

この状態で、前回の検証同様に上流側のデータソースにPythonで自動的にデータを連続挿入し(2つのテーブルにそれぞれ1秒間隔で)、その結果をストリーミング処理しながら下流側のデータソースのテーブルに反映させます。(シンプル&力技でのJOINですので、出来上がりは美しくないかもしれませんが・・・そこは基本機能の検証という事でご容赦の程。。)
j13.jpg

まずは、下流側のターゲットソース上のテーブルを確認します。
j14.jpg

上流側のテーブルを確認します。
j15.jpg

j16.jpg

データ数が少なかったので、上流側のテーブルに挿入が始まってから終わるまでの時間が一瞬で終了し、ほぼ同時に下流側のストリーミングJOIN処理も出来上がってしまいましたので呆気なく検証は終了です。

たぶん一番使いそうなTransformを検証

次にTransformを検証してみます。
この検証では、シナリオとして消費税のカラムを現状のデータフローに対して「後付け」で設定して下流側のテーブルに反映させてみる事にします(その位の準備は事前に・・・という話もありますが・・・)
まずは、最上流のデータソースの準備をいつも通りに行い、OperatorからTransformを選択してFlowを接続します。
T1.jpg
次に「+」ボタンを選択し
T2.jpg
取り扱うフィールドを追加します。
T3.jpg
T4.jpg
基本的にこの設定で新たなカラムが「この段階で設定される」事になります。
T5.jpg
カラムの順番は右側の上下ボタンで調整が可能です。
T6.jpg
T7.jpg
これで右下のOKボタンを選択し、ターゲットのデータソース(この場合もFlow設定すると上流側である今回のTransform情報をベースにプロトタイプを作成してくれますので、その情報を活用してテーブルを生成する事が可能です)を設定し、今まで同様に1秒毎にデータを自動生成して上流側に挿入すれば、そのアクションを自動検知して今回設定した手順の処理を行い、下流側のターゲットテーブルを即時生成していく形になります。
上流側に自動挿入されたデータはこんな感じになります。
image.png

Tax項目を途中追加して生成された下流側のテーブルはこんな感じになります。
image.png

今回のまとめ

駆け足になりましたが、今回はJOINとTRANSFORMの検証を行いました。
複雑なkafka系コーディングや、Spark連携等の作業を考える必要なく、かなり高度なリアルタイム・データストリーミングをデザイン出来る可能性は感じて頂けたかと思いますが、次回の検証では

さらに複雑(?)な流れ

の作成に挑戦してみたいと思います。

ゼロコーディングで高度なkafka/Spark連携のストリーミング環境を構築!

専用の最適化・専用実装を行ったDeepなkafkaの世界には負けるかもしれませんが、誰でもかなり早いkafkaストリーミングでのデータ連携・活用環境が作れる!という点においては、非常に可能性を秘めた環境であると言えるでしょう。

バッチ処理しか選択肢が無い時代は過去の話になりました。
今をデータ活用で変えるのであれば、その選択肢は必然的にリアルタイム・ストリーミングになると思います。
データで今を変えて未来を創る!!
これがDxにおけるデータ・ドリブンの真骨頂なのだと思います・・・

Equalumがやって来た!(前半完結編1)に続く

謝辞

本検証は、Equalum社の特別の許可を得て実施しています。この貴重な機会を設定して頂いたEqualum社に対して感謝の意を表すると共に、本内容とEqualum社の公式ホームページで公開されている内容等が異なる場合は、Equalum社の情報が優先する事をご了解ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【MySQL】MySQL 8 でユーザー作成しGRANTで権限追加する際にエラーが発生

ターミナル
## MySQLに root で接続
$ mysql -uroot -p

## ユーザー作成
> CREATE USER 'homestead'@'localhost' IDENTIFIED BY 'XXX';

## ユーザーに全権限追加
> GRANT ALL ON *.* TO 'homestead'@'localhost' IDENTIFIED BY 'XXX';
>> エラー発生

## 権限の変更をデータベースに反映
FLUSH PRIVILEGES;

GRANTでエラー発生
原因:MySQL8.0ではGRANT構文でユーザを作成できない
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
解決策

ターミナル
## MySQLに root で接続
$ mysql -uroot -p

## ユーザー作成
> CREATE USER 'homestead'@'localhost' IDENTIFIED BY 'XXX';

## ユーザーに全権限追加
> GRANT all ON *.* TO 'homestead'@'localhost';

## 権限の変更をデータベースに反映
> FLUSH PRIVILEGES;
log
## MySQLに root で接続
$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.19 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

## ユーザー作成
mysql>
mysql> CREATE USER 'homestead'@'localhost' IDENTIFIED BY 'XXX';
Query OK, 0 rows affected (0.00 sec)

## ユーザーに権限追加
mysql> GRANT ALL ON *.* TO 'homestead'@'localhost' IDENTIFIED BY 'XXX';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'XXX'' at line 1
>> エラー発生

参考記事:https://www7390uo.sakura.ne.jp/wordpress/archives/456

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(自分用)Flask_7(Flaskからデータベースを開く)

項目

  1. Flaskからデータベースを開く
    (今日は疲れてるのでこれだけで)

1.Flaskからデータベースを開く

python
from flask import Flask, render_template
import pymysql
app = Flask(__name__)

def getConnection():
    return pymysql.connect(
        host='localhost',
        db='mydb',
        user='root',
        password='',
        charset='utf8',
        cursorclass=pymysql.cursors.DictCursor
    )

@app.route('/')
def select_sql():
    connection = getConnection()

    sql = "SELECT * FROM players"
    cursor = connection.cursor()
    cursor.execute(sql)
    players = cursor.fetchall()

    cursor.close()
    connection.close()

    return render_template('view.html', players = players)
  • python側に関しては基本的には今までの組み合わせ
  • 前回やったimport pymysqlでPython内でMySQLを使えるようにしている
  • def getConnection():return pymysql.connect()で、getConnection()を呼び出した時に、dbを呼び出す材料が手に入るようになっている
  • connection = getConnection()connectionに呼び出す情報を入れて
  • 下の幾つかは前回と同じ動き
  • そんでFlaskの手順でreturnに代入した変数を入れてhtml側でも使えるようにしている
view.html
{% for player in players %}
    <p>{{ player }}</p>
{% endfor %}
  • なんの変哲もないpy側から渡された変数をfor文で表示する儀式
  • これ入れればとりあえずOK

あとは普通にFlaskを起動すれば完了(一応下に起動のあれも載せておく)

ターミナルとか
$ cd <作業ディレクトリが入ってるフォルダ名とか>
$ FLASK_APP=<作業pyディレクトリ名> FLASK_ENV=development flask run

2.終わりに

  • かなり短い
  • 48時間で3時間しか寝てないぽいのでちょっと今日は休む
  • SQLでデータ削除とかAWS本格的に借りて動かすのとかは明日(今日?)にお預け
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

リモートデバッグ可能なNginx, Spring Boot, MySQLの開発環境をDockerで作った

前置き

最近、WebサイトをSpring Bootで開発しています。以前に投稿した記事のような開発環境が欲しくなってきましたので調査しました。前回とほぼ同じ形式で執筆します。

動作環境

   
OS macOS Catalina 10.15.5
Docker docker desktop community 2.3.0.3 (45519)
Spring Tool Suite Version: 4.5.1.RELEASE

Spring Bootプロジェクト

InteliJ + Kotlin + gradleとしたいところですが、現在携わっている環境に近い構成でやっていこうと思います。
モダンJavaだとこの組み合わせ減ってると思います:sob::sob:

  • Spring Boot 2.2
  • Java OpenJDK 11
  • STS 4
  • Maven 3.6.3

構築イメージ

まずは構築する環境を説明します。
構成の図解.png

以下のコンテナを作成します。

  • MySQL
    • ホストOSのMySQL Workbenchでアクセスできる(localhost:3306)
  • Spring Boot
    • ホストOSのブラウザでアクセスできる(localhost:8080)
    • STS(Eclipse)からリモートデバッグできる(localhost:5005)
  • Nginx
    • HTTPSでアクセスできる(https://devnokiyo.example.com)
    • ただし、GitHubにソースコードを公開する関係で自己署名SSL証明書)

もちろん、コンテナ間も通信を行います。

構成

GitHubに公開しています。併せてご覧ください。
前述の記事同様にDocker周りだけを管理したいディレクトリと永続化だけを管理したいディレクトリに分けました。
以降、粛々とファイルとその説明が続きます。「とにかくGitHubのコードを動かしたい」方はこちらまで飛んでください:airplane_departure::airplane_departure::airplane_departure:

$ tree
├── README.md
├── docker                          # DockerやDocker Compose
│   ├── containers                   # 各コンテナ(イメージ)
│   │   ├── mysql                     # MySQL 5.7
│   │   │   ├── Dockerfile             # MySQL 5.7のDockerファイル
│   │   │   ├── initialize_data.sql    # 初期セットアップでユーザとサンプルデータを作成するスプリプト
│   │   │   └── my.cnf                 # 初期セットアップで反映するmy.cnf
│   │   ├── nginx                     # Nginx 1.19.0
│   │   │   ├── Dockerfile             # NginxのDockerファイル
│   │   │   └── nginx.conf             # 初期セットアップで反映するnginx.conf
│   │   └── spring                    # OpenJDK 11 (Spring Boot構築用)
│   │       └── Dockerfile             # Spring Boot構築用のDockerファイル
│   ├── docker-compose.yml          # Docker Composeファイル
│   └── environments                # 環境変数定義 
│       ├── common.env               # 各コンテナ共通
│       └── db.env                   # DB接続用MySQL関連
└── volumes                         # 永続化するリソース
    ├── app                          # Spring Bootのプロジェクト (以下、特筆点するディレクトリ/ファイルのみコメント)
    │   ├── .m2                       # Mavenのローカルリポジトリ
    │   ├── mvnw                      # Maven Wrapper 今回はこれを使ってSpring Bootを起動する
    │   └── src                        # ソースコード
    │       └── main
    │           └── resources            # この配下にstaticディレクトリを作成しない (静的ファイルはNginxで返す)
    ├── db                           # MySQLのデータ このディレクトリは最初は無し
    └── web                          # Nginxのファイル
        ├── ssl                       # SSL証明書
        │   ├── privkey.pem            # 秘密鍵
        │   └── server.crt             # サーバー証明証
        └── static                    # 静的ファイル置き場

Composeファイル

docker/docker-compose.yml
version: '3'
services:                                          # 各コンテナ(サービス)
  db:                                               # MySQLのコンテナ 「db」と命名
    build: containers/mysql                          # Dockerファイルのパス
    env_file:                                        # 環境変数
      - ./environments/common.env                     # 各コンテナ共通
      - ./environments/db.env                         # DB接続用MySQL関連
    volumes:                                         # 永続化
      - ../volumes/db/data:/var/lib/mysql             # MySQLのデータ
    ports:                                           # 開放ポート
      - 3306:3306                                     # ホストOSのWorkBenchでDBを参照する目的
  app:                                              # Spring Bootのコンテナ 「app」と命名
    build: containers/spring                         # Dockerファイルのパス
    env_file:                                        # 環境変数
      - ./environments/common.env                     # 各コンテナ共通
      - ./environments/db.env                         # DB接続用MySQL関連
    # 実行するコマンド(後述)
    command: ./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005"
    volumes:                                         # 永続化
      - ../volumes/app:/app                           # Spring Bootのプロジェクト
      - ../volumes/app/.m2:/root/.m2                  # Mavenのローカルリポジトリ
    ports:                                           # 開放ポート
      - 8080:8080                                     # ホストOSからNginxを通さずTomcatを直接参照する目的
      - 5005:5005                                     # IDEでリモートデバッグする目的
    depends_on:                                      # 起動する順番
      - db                                            # 「db」の後で起動
  web:                                              # Nginxのコンテナ 「web」と命名
    build: containers/nginx                          # Dockerファイルのパス
    env_file:                                       # 環境変数
      - ./environments/common.env                    # 各コンテナ共通
    volumes:                                        # 永続化
      - ../volumes/web/static:/usr/share/nginx/www/  # 静的ファイル (Spring Bootプロジェクトのresouce/staticには配置しない)
      - ../volumes/web/ssl:/etc/nginx/cert/          # SSL証明書
      - ../volumes/web/log:/var/log/nginx/           # Nginxのログ
    ports:                                          # 開放ポート
      - 443:443                                      # HTTPS この開発環境はHTTPSのみ想定
    depends_on:                                     # 起動する順番
      - app                                          # 「app」の後で起動

db(MySQL)コンテナ

Dockerファイル

docker/containers/mysql/Dockerfile
# MySQL 5.7
FROM mysql:5.7

# 初期セットアップで利用するmy.cnfをイメージへコピー
# アーカイブを展開する必要などが無ければADDで無くてCOPYで良い。
COPY my.cnf /etc/mysql/conf.d

# 初期セットアップで実行したいスクリプトをイメージへコピー
COPY initialize_data.sql /docker-entrypoint-initdb.d

コピーするファイルの概要

ホスト イメージ 概要
docker/containers/mysql/my.cnf /etc/mysql/conf.d/ 文字コード
docker/containers/mysql/initialize_data.sql /docker-entrypoint-initdb.d/ Spring Bootアプリ向けDBアカウント/サンプルデータ

Docker Comopseから設定される環境変数

docker/environments/common.env
TZ=Asia/Tokyo
docker/environments/db.env
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=spring
MYSQL_PASSWORD=spring

Docker Comopseから設定される永続化

ホスト コンテナ 概要
volumes/db/data /var/lib/mysql MySQLのデータ

app(Spring Boot)コンテナ

Dockerファイル

docker/containers/spring/Dockerfile
FROM openjdk:11

# 永続化でマウントされるパスをワーキングディレクトリに指定
WORKDIR /app

Docker Comopseから設定される環境変数

docker/environments/common.env
TZ=Asia/Tokyo
docker/environments/db.env
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=spring
MYSQL_PASSWORD=spring

Docker Comopseから設定される永続化

ホスト コンテナ 概要
volumes/app/ /app Spring Bootのプロジェクト
GitHubに公開しているものは予めサンプルアプリが入っています)
volumes/app/.m2 /root/.m2 Mavenのローカルリポジトリ
./mvnw cleanを実行するとプラグイン/ライブラリなどを毎回ダウンロードしてしまうことを防ぎます。

Docker Comopseのcommand

こちらのコマンドについて少し補足します。

./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005"
コマンド 概要
./mvnw Java -jarによる起動は開発中のコードが更新されたときの自動リロードが無効になってしまうので、Mavenで起動することにしました。Maven WrapperがあればMavenをインストールする必要がないので、mvnwを採用しました。
address=*:5005 JDWPのポートを指定しますが、 ホストOSからコンテナへアクセスするには*:5005とする必要があります。ポート番号しか書いていないネット情報が多いのでご注意ください:skull_crossbones::skull_crossbones:

web(Nginx)コンテナ

Dockerファイル

docker/containers/nginx/Dockerfile
FROM nginx:1.19.0

# 初期セットアップで反映するファイルをコピー
COPY nginx.conf /etc/nginx/conf.d/app.conf
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

コピーするファイルの概要

ホスト イメージ 概要
docker/containers/nginx/nginx.conf /etc/nginx/conf.d/app.conf 後述

WEBサーバーの設定

トリッキーな設定は無いと思いますが簡単に補足します。
GitHubに公開しているものはSSL証明書については「*.example.com」の自己署名SSL証明書(所謂「オレオレ証明書」)を利用しています。筆者の環境ではLet's EncryptのSSL証明書を利用しています。

docker/containers/nginx/nginx.conf
server {
  listen 443 ssl;
  server_name devnokiyo.example.com;

  ssl_certificate     /etc/nginx/cert/server.crt;
  ssl_certificate_key /etc/nginx/cert/privkey.pem;
  ssl_prefer_server_ciphers on;

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;

  root /app/public;
  try_files $uri /;
  client_max_body_size 10m;
  error_page 404             /404.html;
  error_page 505 502 503 504 /500.html;

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-CSRF-Token $http_x_csrf_token;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://app:8080;
  }

  # Spring Bootの静的ファイルはNginxで返す。
  location ~* .*\.(jpg|gif|png|css|js|ico|svg) {
      root /usr/share/nginx/www;
      access_log off;
  }
}

Docker Comopseから設定される環境変数

docker/environments/common.env
TZ=Asia/Tokyo

Docker Comopseから設定される永続化

ホスト コンテナ 概要
volumes/web/static/ /usr/share/nginx/www/ 静的ファイル
volumes/web/ssl/ /etc/nginx/cert/ SSL証明書
volumes/web/log/ /var/log/nginx/ ログ

実行してみましょう!

Docker Composeで起動

だいぶ簡単でしたが各ファイルの説明が終わりましたので実行して確認します。

  1. GitHubから一式ダウンロードします。
  2. dockerディレクトリへ移動します。

    $ cd docker
    
  3. ビルドします。(初回なので起動でも構いません)

    $ docker-compose build --no-cache
    Building db
    Step 1/3 : FROM mysql:5.7
    ---> 9cfcce23593a
    Step 2/3 : COPY my.cnf /etc/mysql/conf.d
    ---> 4af29808e20c
        :
        :
    Successfully built b074e2d8831d
    Successfully tagged docker_web:latest
    
  4. 起動します。

    $ docker-compose up
    Creating network "docker_default" with the default driver
    Creating docker_db_1 ... done
    Creating docker_app_1 ... done
    Creating docker_web_1 ... done
    Attaching to docker_db_1, docker_app_1, docker_web_1
    db_1   | 2020-06-22 23:04:49+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started.
        :
        :
    db_1   | Version: '5.7.30'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
        :
        :
    app_1  | [INFO] Scanning for projects...
    app_1  | Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.8.RELEASE/spring-boot-starter-parent-2.2.8.RELEASE.pom
    app_1  | Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-dependencies/2.2.8.RELEASE/spring-boot-dependencies-2.2.8.RELEASE.pom
        :
        :
    app_1  | [INFO] Attaching agents: []
    app_1  | Listening for transport dt_socket at address: 5005
    app_1  | 
    app_1  |   .   ____          _            __ _ _
    app_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    app_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    app_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    app_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
    app_1  |  =========|_|==============|___/=/_/_/_/
    app_1  |  :: Spring Boot ::        (v2.2.8.RELEASE)
    app_1  | 
    app_1  | 2020-06-22 23:07:31.526  INFO 74 --- [  restartedMain] com.example.demo.DemoApplication         : Starting DemoApplication on e5dd9a4954d8 with PID 74 (/app/target/classes started by root in /app)
        :
        :
    app_1  | 2020-06-22 23:07:37.683  INFO 74 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    app_1  | 2020-06-22 23:07:37.686  INFO 74 --- [  restartedMain] com.example.demo.DemoApplication         : Started DemoApplication in 6.781 seconds (JVM running for 8.41)
    

ブラウザからアクセス

hostsファイルにdevnokiyo.example.comをループバックIPで設定してhttps://devnokiyo.example.com にアクセスします。不正な証明書ということでエラーが出ると思いますが便宜上例外を許可してください。以下はChromeの例ですが表示自体はされています。

ブラウザの警告.png
nginxへアクセス.png
Nginxを経由でWebサイトにアクセスできています:thumbsup:
なお、ポポデザイン様のテンプレートを利用させて頂きました。感謝申し上げます。

前述のとおり筆者専用環境ではLet's EncryptのSSL証明書を利用しています。ご参考までに正常な証明書扱いの画像も載せておきます。独自ドメインを所有しておりhoge.devnokiyo.comで取得した例になります。
スクリーンショット 2020-06-23 1.32.32.png

Tomcatへアクセス

Nginxの設定の誤りで動作不良になることもあると思いますので、Tomcatへの直接アクセスも許可しています。念のためアクセスできるか確認します。
http://localhost:8080 にアクセスします。レイアウトが崩れています:thermometer_face::thermometer_face::thermometer_face:
しかし、静的ファイルはNginxから返されるように設定しているので問題ありません:bangbang:
Tomcatにアクセス.png

ホストOSからMySQLへ接続を確認

ホストOSのMySQL Workbenchから以下にアクセスします。

ホスト名 127.0.0.1
ポート 3306
ユーザー spring
パスワード spring

無事できていますね:thumbsup:
DB_確認_1.png

TomcatからMySQLへ接続を確認

Docker Composeで定義したコンテナ間でMySQLへ接続できるか確認します。
https://devnokiyo.example.com/formへアクセスしてお問い合わせしてみます。
お問い合わせ.png
送信ボタンを押下します。
お問い合わせ完了.png
再度MySQL Workbenchでテーブルを参照するとレコードが1行増えていますね:thumbsup:
DB_確認_4.png

リモートデバッグする

Spring BootをDockerでコンテナ化しましたが、ブレークポイントを利用できないと不便です。STS(Eclipse)からTomcatのコンテナをアタッチしてデバッグできるようにします。

準備

STS(Eclipse)のメニューからRun -> Debug Configurations...を選択します。Remote Java ApplicaiondemoプロジェクトをDebugします。
リモートデバッグの準備.png

ブレークポイントを設定

RootControllerの29行目にブレークポイントを設定しました。
ブレークポイントを設定
http://devnokiyo.example.com/formへアクセスするとブレークポイントで処理が止まります。
ブレークポイントで停止中.png

自動リロード

ソースコードを修正したときに毎回ビルドするのは面倒なので、Spring Boot Devtoolsの自動リロードを利用します。前述のとおりJava -jarによる起動は開発中のコードが更新されたときの自動リロードが無効になってしまいますが、Maven WrapperでSpring Bootを起動しているので自動リロードできます。

ソースコード修正

以下のアクションメソッドを追加してみます。コントローラークラスのファイルを保存するとリロードされます。

RootController.java
@GetMapping("/hoge")
public String hoge() {
    return "root/index";
}

ソースコード修正

自動リロード中

コンソールをみるとリロードの状況がわかります。1行目が初回起動時の日時で2行目以降が自動リロードの挙動になります。

app_1  | 2020-06-23 00:09:00.911  INFO 40 --- [  restartedMain] com.example.demo.DemoApplication         : Started DemoApplication in 6.459 seconds (JVM running for 8.092)
app_1  | 2020-06-23 00:21:51.379  INFO 40 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
app_1  | 2020-06-23 00:21:51.379  INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
app_1  | 2020-06-23 00:21:51.389  INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
app_1  | 2020-06-23 00:36:13.585  INFO 40 --- [       Thread-5] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
app_1  | 2020-06-23 00:36:13.588  INFO 40 --- [       Thread-5] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
app_1  | 2020-06-23 00:36:13.651  INFO 40 --- [       Thread-5] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
app_1  | 2020-06-23 00:36:13.755  INFO 40 --- [       Thread-5] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
app_1  | 
app_1  |   .   ____          _            __ _ _
app_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
app_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
app_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
app_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
app_1  |  =========|_|==============|___/=/_/_/_/
app_1  |  :: Spring Boot ::        (v2.2.8.RELEASE)
app_1  | 
app_1  | 2020-06-23 00:36:14.036  INFO 40 --- [  restartedMain] com.example.demo.DemoApplication         : Starting DemoApplication on e5dd9a4954d8 with PID 40 (/app/target/classes started by root in /app)
app_1  | 2020-06-23 00:36:14.037  INFO 40 --- [  restartedMain] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
app_1  | 2020-06-23 00:36:14.500  INFO 40 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
        :
        :
app_1  | 2020-06-23 00:36:15.884  INFO 40 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
app_1  | 2020-06-23 00:36:15.907  INFO 40 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
app_1  | 2020-06-23 00:36:15.908  INFO 40 --- [  restartedMain] com.example.demo.DemoApplication         : Started DemoApplication in 1.965 seconds (JVM running for 1644.96)
app_1  | 2020-06-23 00:36:15.911  INFO 40 --- [  restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged
app_1  | 2020-06-23 00:36:30.177  INFO 40 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
app_1  | 2020-06-23 00:36:30.178  INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
app_1  | 2020-06-23 00:36:30.183  INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms

修正後の確認

https://devnokiyo.example.com/hogeにアクセスしてトップページと同じページが表示されることを確認します。
自動リロード済み

終わりに

前回同様に基礎的なコマンドの説明よりは「筆者はこうやった」的なことをメインに記事を書いてみました。JVM系はRubyやGoと比較するとDocker周りの情報が少ない印象です。(点々とした情報はあるのですが、線になっている情報は少ない雰囲気です。)
ひととおりの手順を習得できたので、どのくらい開発環境として使っていけるか運用してみようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む