11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【M1 mac 】Docker Rails + MySQL【環境構築〜Hello World】

Last updated at Posted at 2019-05-30

はじめに

DockerでRuby on rails + Mysqlの環境を作っていきます。

環境構築の仕方を知らないとDockerは書けないと思うので、Docker上で動かして環境構築しながらDockerfile及びdocker-composeの記述を追加していこうと思います。

rails sで起動確認できるところまでやってみます。

Docker導入

Docker Desktop for Apple silicon
ダウンロードって書いてるところわかる?

↓これはまだintel Macしか無理っぽい

$ brew install --cask docker

バージョン確認はこのコマンド

$ docker -v

MySQL8.xインストール

$ brew install mysql

どうしてもMySQLのインストールに詰まっている方は、ver5.7をインストールしましょう。

$ brew install mysql@5.7
$ brew link mysql@5.7 --force

導入はすばやく終了!

環境構築

作業フォルダを作ってそこにDockerfiledocker-compose.ymlを作成します。
(後にこのフォルダにrailsファイルを生成していく形になります。)

Dockerfileにバージョンを記述してください。

ちょっと古い2.4.6を使ってみます。

FROM ruby:2.4.6

バージョンはこちらを参考にしました。
https://hub.docker.com/_/ruby

今回はバージョンを自分で決められるのでrailsファイル作る前からバージョン書いてますが、もうすでにrailsファイルがある場合はgemfile見てそのバージョンを記述してくださいね

次にdocker-compose.ymlを書きます。

docker-compose.yml
version: '3.8'
services:
  mysql: #ここはただの名前なのでdbとかdatabaseとかでもよい
    image: mysql:latest
        platform: linux/x86_64 #M1の場合これ必要
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "3306:3306"
    volumes:
      - "./mysql-data:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: root
  app: #コンテナの名前です
    build: .
    volumes:
      - ".:/app"
    ports:
      - "3000:3000"
    tty: true
    depends_on:
      - mysql

何を書いているのか上から順に説明しますね。

version

docker-composeのバージョンについてはこちらを参考にしてください。
https://docs.docker.com/compose/compose-file/

mysql

バージョンはこちらを参照してください。
https://hub.docker.com/_/mysql
環境構築で挫折しがちなバージョン8以降でやっていきます。
最新版がいいときはmysql:latestと書くこともできます。

※追記
これM1用で必要な部分

platform: linux/x86_64

mysql8以降を使う場合は必ずこれを記述してください。

command: --default-authentication-plugin=mysql_native_password

Mysql8から認証プラグインがcaching_sha2_passwordになるのでmysql_native_passwordに代えてあげる作業をしなければなりません。
ここがmysql8の環境構築でネックになる部分なのですが、Dockerではこの一行だけで解決してくれます。

なお、5.7を使う場合はこの記述は必要ありません。
↑で貼ったリンク先にその辺のことも書かれていて、サンプルコードもあります。

ports4306:3306左側がローカルでDocker上のポートで紐づけています。
あとでsequel proに繋ぐやり方を書くのですが、左の4306を使うことになります。

volumesは、docker環境で作成したデータベースのデータの保存先を決めています。
$ docker-compose upしたとき、指定しているmysql-dataという名前のフォルダがローカルに生成され、ここにdocker環境で作成したデータベースのデータが保存されます。
コンテナを消してしまったとしても前回作成したmysql-dataフォルダが残っていれば、再度コンテナを立ち上げたときに前回までのデータベースがそのまま生かされます。

MYSQL_ROOT_PASSWORD: rootは、mysqlのusernameとpasswordをrootに指定しています。
あとでdatabase.ymlをそのように修正しますね。

app

build: .は動かすDockerfileのディレクトリを指します。

今回はdocker-compose.ymlと同じディレクトリにあるので.としてますが、

例えばdockerフォルダの中のDockerfile.devというファイル名の場合は、

build:
  context: ./docker
  dockerfile: Dockerfile.dev

と書きます。ということは、

build: .
# これは
build:
  context: .
  dockerfile: Dockerfile
# これの略だったんですね。

volumes".:/app"左側の.がローカルのディレクトの位置です。
docker-compose.ymlがあるディレクトリにこれからrailsファイルを生成するので.になっています。
右側の/appはDockerのコンテナ内のappフォルダ内を指しています。
これでローカルのディレクトリとDockerコンテナ内のディレクトリを紐付けました。

portsはmysqlのときと同じで"3000:3000"はローカルのポート3000とDockerコンテナ内のポート3000を紐付けています。

tty: trueこれは書いといてください!

depends_on: mysqlこれは、appとmysqlは別々に起動している形になっているので、appがmysqlにアクセスできるようにしています。

Docker動かしてみる!

一度これで動かしてみたいと思います。

$ docker-compose up
# 中略
Recreating dockerrails_app_1 ... done
Attaching to dockerrails_app_1

こうなっていれば動いてます!

今動いてるdockerrails_app_1の中に入りたいですよね。
(dockerrailsこれはローカルのフォルダ名ですので各自違うと思います。)

もう一つターミナルを開いて次のコマンドを打ちます。

$ docker exec -it dockerrails_app_1 /bin/bash

これで入れます。

docker-compose.ymlがルートディレクトリにあれば、

$ docker-compose exec app bash

これで入れます。

# exitで出れるので試してみてください。

docker-compose.ymlはルートにないとめんどくさそうな気がするので毎回ルートに置いてます。

中に入れたらlsコマンドでどんなフォルダがあるのか確認してみてください。

# ls
app  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

今作ったappというフォルダ内に展開していきたいので、cdコマンドでappフォルダの中に入ります。

# cd app

これでapp#に変わったと思います。

これDocker起動してdockerrails_app_1に入ったときに自動的にappフォルダ内に入りたいですよね。

**安心してください!**後でガッと実装しますので。

再度lsコマンドで確認してみるとDockerfiledocker-compose.ymlがいるはずです。

いよいよrailsのファイル達を生成していくのですが、まずrailsをインストールするところから始まります。

app# gem install rails

インストールが完了したらrailsファイルを生成します。

mysqlの開発環境にするので、次のコマンドを流します。

app# rails new . -d mysql

これでファイルが生成されました。

まずはdatabase.ymlを修正します。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  #下の二つを修正します。
  password: root
  host: mysql

host: mysqlのmysqlは、docker-composeで指定した名前です。
docker-compose.ymlmysql:と命名してdepends_on: mysqlでマウントしましたよね。

さてrails起動してみますかー。

app# rails s -b 0.0.0.0

怒られるんですよね。

nodejsをインストールしないとダメなんです。

次の二つのコマンドを流してください。

app# apt-get update
app# apt-get install nodejs

インストール中(Y/n)を聞かれるので迷わずY!と答えてください。

後でDockerfileの書き方で触れるので頭の片隅においといてください。

色々と手動で環境構築しているのですが、最終的にすべて自動でしてくれるようにします!

今やっていることはDockerfileに書いていくことになりますのでなんとなくでいいので覚えててください。

このままでも起動はするのですが、mysqlコマンドが使えないのでmysql-clientをインストールしてあげます。
インストール中(Y/n)を聞かれるので迷わずY!

app# apt-get install mysql-client

データベース作ってあげてrailsを起動してあげます。

app# rails db:create
app# rails s -b 0.0.0.0

無事起動できましたか??

Dockerfile書くぞ!

はい本題ですw

Dockerを動かしてから環境構築するときどんなインストールコマンドを使ってきましたか?

gem install rails
apt-get update
apt-get install -y nodejs
apt-get install -y mysql-client

これらのコマンドを使って環境構築しました。

-yというのはインストール中に(Y/n)を聞かれた時にYと答えましたよね。そのyです。

これで止まることなく自動でYを選択してくれてどんどん進んでいきます。

これらのコマンドをDockerfileではこう書きます。

RUN gem install rails

RUN apt-get update && \
    apt-get install -y nodejs mysql-client

\バックスラッシュを使うことで改行して書くことができます。

次にbundle installも自動でするようにします。

WORKDIR /app
COPY Gemfile ./
COPY Gemfile.lock ./
RUN bundle install --jobs=4 --retry=3

WORKDIRでパスを指定することによって、Docker内での作業ディレクトリを指定することができます。

これでDockerを起動してdocker-compose exec app bashを叩いたとき直接appフォルダ内に入ってくれるようになります。

そして、ローカルのGemfileGemfile.lockをDockerコンテナ内のルートディレクトリ(先程/appに指定したので/app内)にコピーします。

その後bundle installを流しています。

パスは変数で指定した方が吉です。

↓で書いてみます。

こちらが今回作ったDockerfileです。

FROM ruby:2.4.6

ENV LANG=C.UTF-8

ENV WORK_DIR="/app" \
    CONTAINER_ROOT="./"

RUN apt-get update && \
    apt-get install -y nodejs mysql-client && \
    gem install rails

WORKDIR $WORK_DIR
COPY Gemfile Gemfile.lock $CONTAINER_ROOT
RUN bundle install --jobs=4 --retry=3
docker-compose.yml
version: '3.7'
services:
  mysql:
    image: mysql:8.0.16
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "4306:3306"
    volumes:
      - "./mysql-data:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: root
  app:
    build: .
    volumes:
      - ".:/app"
    ports:
      - "3000:3000"
    tty: true
    depends_on:
      - mysql

DockerfileENV LANG=C.UTF-8を追加しています。

これはDockerコンテナ内で日本語をDockerさんに受け入れてもらうための記述です。

その下にcommand: "rails s -b 0.0.0.0"を記述するとrails起動までしてくれますがrailsを停止したときにDockerまで停止させてしまう(Dockerは停止させない設定が必要)のでDockerを起動させてから別ターミナルでrailsを起動するようにしましょ。

Dockerfileを書き換えたので再構築しましょう。--buildオプションを使います。

$ docker-compose up --build

よくあるエラー

rails s -b 0.0.0.0で下記のエラーが発生した場合、

A server is already running. Check /app/tmp/pids/server.pid.

ローカルの作業ディレクトリ/tmp/pids/server.pidを削除すれば解決します。

Dockerコンテナ立ち上げ時、毎回削除するようにできますが今回の記事では対象外とします。

Sequel Proで接続

スクリーンショット 2019-05-30 23.44.10.png

これで繋がります。

Passwordの部分はrootですね。

おわり

このくらいのボリュームなら緊急時でも何も見ずにプリッと書けますよね。(そんな緊急時があるのか?)

でもこれは基礎の「き」なのでコンテナのサイズが大きかったりします。。。

例えばベースイメージにAlpine Linuxを使ったりすると実は半分のサイズになったりします。

スクリーンショット 2019-05-30 23.48.18.png

上がalpineで同じ環境内容で動かしたものになります。

下がこの記事で書いたDockerコンテナです。

alpineにするとまた環境構築のコマンドが違ってくるのでそちらに関して書こう・・・と思ったのですが、もうすでに詳しく書かれている記事があるのでやめときます。

有料ですが500円でDocker書けるようになるならコスパよすぎです。

はい、寝ますおやすも

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?