【rails5.2 + mysql5.7】docker上にrailsアプリケーションを立ててリモートDBと繋ぐ
先週くらいからようやくdockerに入門しました!(遅い・・)
本とか自分のPC上では軽く触ったことあったのですが、業務でがっつりdockerで環境構築をしたことはなかったです。
そして今回業務で環境構築する際に、
「どうせならdockerでやろう」
と思って作業してみたもののちょびっと詰まったところがあったのでこれから入門する人の参考になればと思いログとして残しておきます!
構成
rails5.2、mysql5.7で作ろうと思っていました。
dockerの公式のチュートリアルでもありますが、結構docker上にアプリケーションとDBの両方置いちゃうケースがあると思います。
なので僕も最初これで環境作ろうと思っていました。
ただ今回の環境構築では新規DBを作成ではなく既存のDBを使いたい!!
既存のDBをダンプしてそれを新規DBでリストアするか〜とも思いましたが、データ量かなり大きそうで断念。。。。
ということで結局この構成にしました。
初めての構成だったので本当にできるのか不安だったのでまずはローカルからリモートのDBに繋げられるかを確認。
リモートDBサーバーのホスト名(xxx:xxx:xxx:xxx)
ユーザー名(hoge)
データベース名(database_name)
$ mysql -h xxx:xxx:xxx:xxx database_name --port=3306 -u hoge -p
結果は
bash: mysql: command not found
それ以前の問題でしたwww
brewを入れているのでmysqlの5.7をインストールした後にもう一度実行しました
$ brew install mysql@5.7
$ mysql -h xxx:xxx:xxx:xxx database_name --port=3306 -u hoge -p bash: mysql: command not found
結果は変わらず・・
$ which mysql
と打っても何も出ないので、パスを通すことにしました。 (なぜこうなるのかは後で調べるつもりです) 僕は.bash_profileにいつも書くのでそこに追記します。
$ echo export PATH=/usr/local/opt/mysql@5.7/bin:$PATH > .bash_profile $ source .bash_profile $ which mysql /usr/bin/mysql
準備できた。
$ mysql -h xxx:xxx:xxx:xxx database_name --port=3306 -u hoge -p Access denied for user
おっふ、、、弾かれましたな。
インフラチームに聞いたところローカルからは直接繋げられないよ、とのことでした。
なので踏み台を利用して繋ぐ方針に変更。
トンネル掘って繋げれるようにしました。
(「sshポートフォワーディング」とかでググると出てくると思います)
僕の場合、ローカルから踏み台サーバーへは
ssh 踏み台サーバーのホスト名
でログインできていたので以下になりました。
$ ssh -NL 3307:db_host:3306 ssh_host $ db_hostはデータベースのホスト名 ssh_hostは踏み台のホスト名
接続確認
$ mysql -h 127.0.0.1 -P 3307 -u db_user -p > これでmysqlにログインできるはずです db_userはデータベースログインのユーザ名
やめたかったら
$ ps aux | grep ssh
とやると、フォワーディングしているプロセスが出てくるのでkillすればokです!
ここまできてようやく今回の構成が決まりました汗。
dockerからローカル経由してフォワーディング先のリモートDBに繋げそうですね。
コード
あとはdockerからローカルのところを実装すればうまくいきそうです!
なのでコードを書いていきましょう。チュートリアルと同じなので迷うこともないかなと思います。
まず作業するディレクトリを作り、その上でDockerfileとdocker-compose.ymlとGemfile、Gemfile.lockを作ります。
$ mkdir work $ cd work $ touch Dockerfile $ touch docker-compose.yml $ touch Gemfile $ touch Gemfile.lock
そして各々コードを記述していきます。
Dockerfileの中身 FROM ruby:2.5 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp
Gemfileの中身 source 'https://rubygems.org' gem 'rails', '5.2.0'
Gemfile.lockは空。
docker-compose.ymlの中身 version: '3' services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000"
コンテナ上でrails newします。
$ docker-compose run web rails new . --force --database=mysql
新しいファイルができたらconfig/database.ymlを修正します。 ここ最初どう書けば良いのか迷いましたが最終的にこれでいけました!
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: リモートDBのユーザー名 password: リモートDBのパスワード host: docker.for.mac.localhost port: 3307 development: <<: *default database:リモートDBのデータベース名
dockerからローカルのMacを見るときはdocker.for.mac.localhost
で見てくれるそうです!
あと今回、フォワーディングのポートを3307にしているのでport: 3307
にしています。
ここも適宜変更してください!
ここまでできたらあとは起動するだけです!
$ docker-compose up --build
localhost:3000にアクセスするとお馴染みの画面が表示されるはずです。
全然関係ない話。
今回初めて知ったのですが、Active Recordって使えるmysqlのバージョンがあったんですね笑。 ORマッパーもあるし、よくよく考えると当たり前なんですが意識したことが一度もなかったです!
というのも今回既存のDBのmysqlが5.0.9という状態で・・・アクセスしたら
Your version of MySQL (5.0.9) is too old. Active Record supports MySQL >= 5.1.10.
という見たことないエラー出てちょっと感動しましたw こういうところもしっかりみておきたいですね!
終わり。。