- 投稿日:2020-09-16T22:12:08+09:00
PHPでログイン機能を実装したら、ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)というエラーでハマった話
https://awesome-linus.com/2019/06/05/laravel-tutorial-todo/
こちらのサイト様の記事を参考にログイン機能を実装していたら、はまりました。
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)パスワードは使用していません。
ルートユーザーでアクセスしたら拒否されたというもの。
ログインと新規登録機能を実装し、アプリをWEBで開いた段階でこのメッセージが表示されました。$ mysql -u root ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)mysql -u rootでログインするとエラーが出るが、
$mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g.このように打ち込むとエラーが出ない。つまり、パスワードをYESにして、設定したパスワードをPHPのファイルのどこかに打ち込む必要があるのではないかと判断。
それっぽいファイルを探してみる。
database.php'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], # 以下省略'password' => env('DB_PASSWORD', ''),
この部分に注目した。
’’の間にパスワードを手動で入れればもしかしたら行けるのでは?
と思ったが、’’の中に手動でパスワードを打ち込んでもうまくいかない。DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=todo DB_USERNAME=root DB_PASSWORD=secretしやここのsecretで設定されているパスワードの部分を書き換えたらいけるのではと思い、
secretの部分を書き換えたりしたがうまくいかず。パスワードをYESで接続するにはどうしたらいいのだ。
仕方ないので方針転換して、rootユーザのパスワードをなしにすることにしました。
$mysql -u root -pパスワードを打ち込んで接続
mysql> SET PASSWORD FOR ユーザ名@ホスト名=password('新しいパスワード');新しいパスワードの部分を空欄にして設定。
パスワードを打ち込んでログインしてみます。無事に成功!
rootユーザのパスワードの設定を使用をYESにして、パスワードを設定する方法はわかりませんでしたが、
パスワードの設定をログインして書き換えることでうまく行きませんでした。またなにかエラーを解決しましたら、引き続きアウトプットしていきます。
- 投稿日:2020-09-16T18:29:19+09:00
ERROR: create _mysql-data: "_mysql-data" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.
はじめに
※MySQL、Dockerのタグを付けましたが今回の内容には直接は関係ないです。
エラー内容
Docker立ち上げようと
docker-compose up -d
したらERROR: create _mysql-data: "_mysql-data" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.というエラーが出てしまいました。みなさんこんな初歩的なミスはしないためかググってもなかなか同じ内容のエラーで悩んでる方が出てきませんでした。
原因
git pull 〇〇
でプロジェクトのURLをプルしたディレクトリ名をカタカナにしておりました。なので"[a-zA-Z0-9][a-zA-Z0-9_.-]"
という風にアルファベットか数字にしてねと怒られていたのでした。。
- 投稿日:2020-09-16T11:30:02+09:00
チームで共有するための『Rails 6 x MySQL 8』Docker環境構築手順
今回はRails 6とMySQL 8を組み合わせたWebアプリケーションのDocker環境を構築する手順について紹介します。
Rails 6からwebpackerが標準でインストールされるようになったり、MySQL 8からユーザー認証の方式が変わったりと環境構築でつまる部分がいろいろとあったため参考になればと思います。
複数人でもスムーズに開発ができるようにするためリモートリポジトリからcloneしてきたらdocker-compose upするだけでアプリケーションが立ち上がるという環境をゴールにします。
各種バージョンは以下の通りです。
- Ruby on Rails: 6.0.3.2
- Ruby: 2.7.1
- MySQL: 8.0.21
実行環境はDocker Desktop for Mac(バージョン 2.3.0.4)を利用しています。
Railsアプリケーションの準備
ディレクトリの作成・移動をします。
今回作成するRailsアプリケーション名はsample_app
とします。$ mkdir sample_app && cd $_rubyイメージを利用してローカル環境にGemfileを作成します。
-v
はバインドマウント(ホストとコンテナのディレクトリの同期)のオプションです。ホストのカレントディレクトリとコンテナのワークディレクトリを同期させることで、コンテナ上で作成されるファイルをホストに配置します。
$ docker run --rm -v `pwd`:/sample_app -w /sample_app ruby:2.7.1 bundle init作成されたGemfileの
gem "rails"
の部分をアンコメントし、railsのバージョンを指定します。Gemfile# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } - # gem "rails" + gem "rails", '~> 6.0.3.2'
rails new
を実行するDocker環境を構築するためDockerfileを作成します。Rails 6ではアプリケーションを作成する際に
rails webpacker:install
も実行されるのでyarnのインストールを忘れずにしましょう。
今回はnpm
を利用してyarn
をインストールします。DockerfileFROM ruby:2.7.1 RUN apt-get update -qq && \ apt-get install -y nodejs \ npm && \ npm install -g yarn # 作業ディレクトリを/sample_appに指定 WORKDIR /sample_app # ローカルのGemfileをDokcerにコピー COPY Gemfile /sample_app/Gemfile # /sample_appディレクトリ上でbundle install RUN bundle installDockerfileをビルドして作成されたイメージを利用してコンテナを起動し、コンテナ上で
rails new
をします。$ docker build -t sample_app . $ docker run --rm -v `pwd`:/sample_app sample_app rails new . –skip-bundle --database=mysql
docker-compose.yml
を作成します。今回は説明を簡略化するため、rootユーザーでMySQLに接続しています。
一般ユーザーで接続をする場合はMySQLのイメージに対して以下の環境変数を設定する必要があります。
環境変数 内容 MYSQL_USER ユーザー名 MYSQL_PASSWORD ユーザーパスワード データベースの情報は
mysql_data
という名前付きボリュームを作成して永続化します。docker-compose.ymlversion: '3' services: web: # Ruby on Railsが起動するコンテナ build: . ports: - '3000:3000' # localhostの3000ポートでアクセスできるようにする volumes: - .:/sample_app # アプリケーションファイルの同期 depends_on: - db command: ["rails", "server", "-b", "0.0.0.0"] db: # MySQLが起動するコンテナ image: mysql:8.0.21 volumes: - mysql_data:/var/lib/mysql # データの永続化 command: --default-authentication-plugin=mysql_native_password # 認証方式を8系以前のものにする。 environment: MYSQL_ROOT_PASSWORD: 'pass' MYSQL_DATABASE: 'sample_app_development' volumes: mysql_data: # データボリュームの登録上記の
docker-compose.yml
の補足説明をします。MySQLのDockerイメージでは
MYSQL_DATABASE
に設定された名前のデータベースを作成してくれます。
Ruby on Railsのdevelopment環境では[アプリケーション名]_development
というデータベースを利用するため、sample_app_development
をMYSQL_DATABASE
に登録しています。
これでrails db:create
を実行しなくてもdevelopment環境のデータベースを用意できます。MySQL 8からは認証方式が
mysql_native_password
からcaching_sha2_password
に変更されました。
MySQL 8標準のcaching_sha2_password
の認証方式だとデータベースへ接続できず、Railsアプリケーション起動時に以下のようなエラーメッセージが表示されてしまいます。Mysql2::Error::ConnectionError Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directoryそこで、
--default-authentication-plugin=mysql_native_password
で以前のmysql_native_password
の認証方式を利用するようにしています。次にRuby on Railsのデータベース接続設定を行います。
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: pass # (今回はrootなので)MYSQL_ROOT_PASSWORDと一致させる host: db # データベースのコンテナ名を設定するRailsアプリケーションの起動確認
Ruby on Rails 6とMySQL 8を組み合わせたDocker環境ができあがったので起動をしてみます。
$ docker-compose up
localhost:3000
にアクセスして以下の画面が表示されればOKです。データベースのデータの永続化についても確認をしてみます。
例としてscaffold
でevent
に関する機能を作成します。$ docker-compose exec web rails g scaffold event title:string $ docker-compose exec web rails db:migrate
localhost:3000/events/new
にアクセスし、例として『サンプルイベント』というレコードを登録してみます。コンテナを削除・起動してもデータが残っていればOKです。
$ docker-compose down $ docker-compose up $ docker-compose exec web rails c > Event.last.title => "サンプルイベント"テスト環境用のデータベースの作成
MYSQL_DATABASE
を利用してdevelopment環境のデータベースを作成することでdb:create
を実行することなくRailsアプリケーションを起動できるようにしました。しかし、テストコードで利用するtest環境のデータベース(
[アプリケーション名]_test
)が作られていないためこれだけでは開発環境としては不十分です。MySQLのDockerイメージでは
/docker-entrypoint-initdb.d
にスクリプト(.sql
、.sh
、.sql.gz
)を配置しておくとコンテナ起動時に実行してくれるという機能があります。1
この機能を活用してtest環境用のデータベースを作成します。スクリプトはアルファベット順で実行されるため、スクリプト間に依存関係がある場合はファイル名も意識してつけるようにしておきましょう。
$ mkdir docker-entrypoint-initdb.d && cd $_ $ vim 00_create.sql00_create.sql-- test環境用のデータベースを作成する CREATE DATABASE sample_app_test;なお、一般ユーザーのデータベースアクセス権は
MYSQL_DATABASE
に設定したデータベースのみとなっています。
ですので、一般ユーザーでデータベースに接続する場合はデータベースの作成だけでなく、以下のようなアクセス権の付与も実行する必要があります。01_grant.sql-- webappという名前の一般ユーザーを利用する場合 GRANT ALL ON `sample_app_test`.* TO webapp@'%';作成したスクリプトをコンテナ上で読み取れるようにするためバインドマウントを追加します。
docker-compose.ymlversion: '3' services: web: build: . ports: - '3000:3000' volumes: - .:/sample_app depends_on: - db command: ["rails", "server", "-b", "0.0.0.0"] db: image: mysql:8.0.21 volumes: - mysql_data:/var/lib/mysql + - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: 'pass' MYSQL_DATABASE: 'sample_app_development' volumes: mysql_data:データベースが自動作成されることを確認
dbコンテナを削除・起動し、自動でデータベースが作られるか確認をしてみます。
[アプリケーション名]_development
と[アプリケーション名]_test
のデータベースが存在していればOKです。# データベースの永続化情報も削除して0からデータベースを作成する $ docker-compose down --volumes $ docker-compose up $ docker-compose exec db mysql -uroot -ppass -D sample_app_development mysql> show databases; +------------------------+ | Database | +------------------------+ | information_schema | | mysql | | performance_schema | | sample_app_development | | sample_app_test | ← test用のdbが作成されている | sys | +------------------------+ 6 rows in set (0.00 sec)Railsアプリケーションからも正常に接続できます。
$ docker-compose exec web rails c > ENV['RAILS_ENV'] => "development $ docker-compose exec web rails c -e test > ENV['RAILS_ENV'] => "test"『clone → docker-compose up』だけで環境が立ち上がるようにする
DockerでRailsの開発環境を構築する方法としてよく見かけるのが以下のようなパターンです。
# コンテナを立ち上げる $ docker-compose up # データベースの作成 $ docker-compose exec web rails db:create # テーブルのマイグレーション $ docker-compose exec web rails db:migrateRailsアプリケーションとデータベースをdocker-composeで連携させ、アプリケーションで利用するデータベースはコンテナ上で構築するという方法です。
上記の方法でも問題はないのですが、この場合だと初回起動時にデータベースとテーブルの作成をコンテナ上で手動実行する手間がかかります。
複数人でDocker環境を共有する時のことを考えると、リモートリポジトリからアプリケーションファイルをcloneしてきたら
docker-compose up
をするだけで環境が立ち上がるのが理想です。共有メンバーに対して「初回起動時はデータベースの作成をコンテナ上で実施してね」とわざわざ伝えないといけない状況はできれば避けたいです。
ここからはリモートリポジトリからcloneしたら
docker-compose up
するだけでRailsアプリケーションが起動できるようにするための設定を行います。yarn installをコンテナ起動時に実行する
開発環境ではバインドマウト(ホストとコンテナのディレクトリの同期)を利用したソースコードの同期がよく利用されます。
リモートリポジトリからcloneしてきたアプリケーションファイルは
package.json
はありますが、node_modules
ディレクトリはありません。
そのため、cloneしたあとdocker-compose up
をするとnode_modules
がない状態のディレクトリがバインドマウントされます。その結果yarn install
の実行を促すエラーが発生し、アプリケーションが起動できません。======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ======================================== To disable this check, please change `check_yarn_integrity` to `false` in your webpacker config file (config/webpacker.yml). yarn check v1.22.5 info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.これを防ぐにはコンテナ起動時に
yarn install
を実行する必要があります。
たとえば以下のようにすることでコンテナ起動時にyarn install
を実行できます。docker-compose.ymlversion: '3' services: web: build: . + command: ["./start.sh"] - command: ["rails", "server", "-b", "0.0.0.0"] ports: - '3000:3000' volumes: - .:/sample_app depends_on: - db db: image: mysql:8.0.21 command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: 'pass' MYSQL_DATABASE: 'sample_app_development'start.sh#!/bin/bash -eu yarn rails server -b '0.0.0.0'シェルのパーミッションを変更します。
$ chmod 755 start.shコンテナを起動する際のコマンドでシェルを呼び出し、シェルの中で
yarn install
を実行するようにしています。
yarn install
実行後、rails server
でRailsアプリケーションが起動するため先ほどのエラーが解消されます。マイグレーションを自動実行できるようにする
テーブルのマイグレーションも
yarn install
と同様、コンテナ起動時に呼び出されるシェルスクリプトで実行するようにします。start.sh#!/bin/bash -eu yarn + rails db:migrate rails server -b '0.0.0.0'しかし、
docker-compose.yml
のdepends_on
を利用することでコンテナの起動順は制御できますが、コンテナの起動を待つということはできないため2、dbコンテナの起動準備が終わる前にdb:migrate
が実行されるとマイグレーションが正常に行われません。マイグレーションの自動化をするにはdbコンテナの起動を待ってから
db:migrate
が実行されるようにする必要があります。データベースの準備を待つ方法にはいくつかありますが、今回はwait-for-itを利用する方法を紹介します。
wait-for-it.sh
をカレントディレクトリに配置し、docker-compose.yml
を以下のようにするとデータベースの起動を待ってからスクリプトが実行されます。docker-compose.ymlversion: '3' services: web: build: . - command: [""./start.sh"] + command: ["./wait-for-it.sh", "db:3306", "--", "./start.sh"] ports: - '3000:3000' volumes: - .:/sample_app depends_on: - db db: image: mysql:8.0.21 command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: 'pass' MYSQL_DATABASE: 'sample_app_development'まとめ
以上でRails 6 + MySQL 8のDocker環境の構築手順の紹介を終わります。
コンテナ起動時にシェルを実行することで、複数人でDocker環境を利用する場合でもスムーズに開発環境を構築できるようにしました。
なお、今回はコンテナ起動時にシェルを呼び出すことでyarn install
やdb:migration
を確実に実行するようにしましたが、コンテナ起動時のコマンドの制御はEntrykitと呼ばれるツールでも行えます。EntrykitについてはRailsのDocker環境にEntrykitを導入し、bundle installを自動実行させる方法で紹介していますので、興味のある方はご覧になってください。
- 今回のまとめ
- Rails 6からはyarnのインストールも事前に行う必要がある
- MySQL 8の認証エラーが発生した場合は標準の認証に戻すことで解決する
- コンテナ起動時にシェルを実行することでテーブル作成等の自動化が可能になる
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!
参考記事
- 投稿日:2020-09-16T03:08:04+09:00
EclipseにMySQLデータベースを紐づける!
Eclipseの初期設定で必要なデータベースの紐づけ!
参考動画 ➡ https://youtu.be/cqg1Eg-u4s4
webサーバーも設定したら、いよいよWebアプリケーションの作成が可能になります?
webサーバーの設定はこちらを参考に ➡ https://qiita.com/iwasaki-hub/items/cd1bf0545be6bde9360a