Dockerを使ってRails6+MySQL8.0のコンテナを作ろうとしたところ、エラーでまくったので
作り方とエラー時の対応策の備忘録です
ここをベースにしています。ただし、MySQLは8.0系です。これが曲者です。
環境
2019年11月現在の安定verを使用しています
- Mac OS
- Ruby2.6.5
- Rails6.0.1
- MySQL8.0
ホスト側のフォルダ構成
owner% tree -L 2 . ├── Dockerfile ├── docker-compose.yml └── src ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── babel.config.js ├── bin ├── config ├── config.ru ├── db ├── lib ├── log ├── node_modules ├── package.json ├── postcss.config.js ├── public ├── storage ├── test ├── tmp ├── vendor └── yarn.lock
作業
こっから実作業です
0 Docker for Mac インストール
ここからDocker for Mac を入れます。Docker hubのアカウントを作り、Docker for Macをダウンロードします。 ただし、容量が大きいのでストレージに注意してください(docker.app(2GB)+コンテナの容量が加わります)
1 プロジェクト作成
プロジェクトを作ります。プロジェクト名はなんでもいいです
$ mkdir sampleRails $ cd sampleRails
2 Dockerfile
次にDockerfile をこの階層に作成し、下記をコピペします
FROM ruby:2.6.5 # railsコンソール中で日本語入力するための設定 ENV LANG C.UTF-8 # yarn install(webpack用。これがないとrails起動しない)) # RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs # /var/lib/apt/lists配下のキャッシュを削除し容量を小さくできる RUN apt-get update -qq && \ apt-get install -y build-essential \ libpq-dev \ nodejs \ curl \ apt-transport-https \ wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn && \ rm -rf /var/lib/apt/lists/* # 作業ディレクトリの設定 RUN mkdir /app_name ENV APP_ROOT /app_name WORKDIR $APP_ROOT # gemfileを追加する ADD ./src/Gemfile $APP_ROOT/Gemfile ADD ./src/Gemfile.lock $APP_ROOT/Gemfile.lock # gemfileのinstall RUN bundle install ADD ./src/ $APP_ROOT
注)Rails6でwebpackerが標準になったことにより、Railsアプリの開発環境にyarnのインストールが必要です
curl -sS 〜 apt-get install -y yarn
あたりがyarnのインストールです
3 docker-compose.yml
次にdocker-compose.ymlをこの階層に作成します。(version3で作成しています)
注)簡易的にユーザアカウントをuser名,pass共にrootにしていますが、アカウントは適時変えてください。
version: '3' services: db: image: mysql:8.0 volumes: #ホスト側 : コンテナ にコピー - ./src/db/mysql_data:/var/lib/mysql - ./src/config/mysql/my.cnf:/etc/mysql/my.cnf environment: MYSQL_ROOT_PASSWORD: root #パスワード c: root #ユーザ名 ports: - "3306:3306" web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - ./src:/app_name ports: - "3000:3000" links: - db
4 Gemfile作成
次にGemfileをsrcフォルダを作成し、その下に配備します
$ cd src $ touch Gemfile
Gemfileのなかはひとまず下記でOKです(この後rails newした時に自動で追記されます) (railsのバージョンを変えたい場合はhttps://rubygems.orgのrailsから参考にしてください)
source 'https://rubygems.org' gem 'rails', '~> 6.0', '>= 6.0.1'
5 Gemfile.lock作成
次に空のGemfile.lockを作成します
$ touch Gemfile.lock
6 Railsプロジェクト作成
プロジェクトフォルダに戻って、rails newを行なって、ひとまずRailsプロジェクトを作成します
$ cd .. $ docker-compose run web rails new . --force --database=mysql --skip-bundle
7 database.yml
このままだとMySQLコンテナ設定不足のため、コンテナーを立ち上げようとしてもエラーになります
まず、/sampleApp/config/database.yml
を修正します
# MySQL. Versions 5.5.8 and up are supported. # # Install the MySQL driver # gem install mysql2 # # Ensure the MySQL gem is defined in your Gemfile # gem 'mysql2' # # And be sure to use new-style password hashing: # https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html # default: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root # docker-compose.ymlのMYSQL_ROOT_PASSWORD password: root # docker-compose.ymlのMYSQL_DATABASE host: db development: <<: *default database: sample_database # (後にこのDBについての権限設定時に使用。) # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: app_name_test # As with config/credentials.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is # ever seen by anyone, they now have access to your database. # # Instead, provide the password as a unix environment variable when you boot # the app. Read https://guides.rubyonrails.org/configuring.html#configuring-a-database # for a full rundown on how to provide these environment variables in a # production deployment. # # On Heroku and other platform providers, you may have a full connection URL # available as an environment variable. For example: # # DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase" # # You can use this database configuration with: # # production: # url: <%= ENV['DATABASE_URL'] %> # production: <<: *default database: app_name_production username: app_name password: <%= ENV['APP_NAME_DATABASE_PASSWORD'] %>
9 my.cnf設定
MySQLの設定ファイルを編集します。src/config/mysql/my.cnf
を作成します
$touch src/config/mysql/my.cnf
下記をコピペします(コメントは削除していいです)
# デフォルト認証プラグインの設定 [mysqld] default_authentication_plugin= mysql_native_password # MySQL8.0対応。Ruby_v2.6.5「caching_sha2_password」認証プラグイン未対応のため secure-file-priv = "" # secure-file-privにアクセスできず、mysqlコンテナが落ちるときは、これつける skip-name-resolve # 接続を受けた際に、認証の目的でクライアントのIPアドレスを逆引きする機能を無効にする設定
10 コンテナをビルドと起動
ここでMySQLとWebコンテナを作成します。docker-compose.ymlのある親フォルダーに移動し、
$docker-compose build コマンドでコンテナをビルドします
$cd .. (docker-compose.ymlまで移動) $docker-compose build #コンテナをビルド ~~build中~~ $ docker-compose up # コンテナの起動
11 MySQLの権限を付与
コンテナをビルドできました。ただし、このままだとMySQLの権限がなく、railsをデプロイしても権限なしエラーでデプロイできないです。
MySQLコンテナからMySQLのDatabaseに権限を付与します
新規ターミナルを開き、プロジェクトのカーレントフォルダまで辿ります。
'$docker ps'からMySQLのIMAGE名を調べます
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0fc0305e78d7 js_sample_date_web "bundle exec rails s…" 33 minutes ago Up 33 minutes 0.0.0.0:3000->3000/tcp js_sample_date_web_1 e25683e6bed5 mysql:8.0 "docker-entrypoint.s…" 47 hours ago Up 33 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp js_sample_date_db_1
この環境ではe25683e6bed5
ですので、$ docker exec -it e25683e6bed5 bash
とすることでコンテナの中に入ることができます。
そこからmysqlに接続して、データベースの権限を付与します
$ docker exec -it e25683e6bed5 bash #mysqlに接続 $ root@e25683e6bed5:/# mysql -u root -p #rootユーザを作成(IDENTIFIED BY ''は docker-compose.xmlで定義したMYSQL_ROOT_PASSWORDの値です) #'root'@'%'で全てのホストから接続可能なユーザー「root」を作成していますが、セキュリティ状よくないので実運用では’%’はホストIPを指定してください # GRANT ALL PRIVILEGES ON *.* として全てのDBに権限を与えていますが、これもDBを指定してください mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'root'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; # 設定を反映します mysql> FLUSH PRIVILEGES;
12 DB作成
新しいターミナルを開き、rails db:create
でrailsプロジェクトが参照するデータベースを作成します
$ cd (projectフォルダ) $ docker-compose run web rails db:create
13 http://localhost:3000/作成
お待たせしました。ブラウザからhttp://localhost:3000/
をアクセスして、いつものrailsプロジェクト作成したぜ画面が出れば成功です
終わりに
MySQL8.0はつまづきポイントが多いように思います。エラーでまくって大変でした。