LoginSignup
8

More than 3 years have passed since last update.

Dockerで既存アプリの開発環境を作成【Ruby2.6 + Rails5.2 + Mysql5.7】

Last updated at Posted at 2020-03-09

既存アプリの開発環境をDockerに。色々とハマりましたが、そこも含めて書いて行きます。

環境

Ruby:2.6.5
Rails:5.2.4
Mysql:5.7
OS: macOS Mojave 10.14.5

ディレクトリ構成

sampleApp ---- Dockerfile
           |-- docker-compose.yml
           |-- app
           |-- bin
           |-- config
                 |-- database.yml

既存アプリのルート直下にDockerfiledocker-compose.ymlを作成しました。

うまくいったやり方

Dockerfile
# app_nameの部分はそのままでOK
FROM ruby:2.6.5

RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs           

RUN mkdir /app_name 
ENV APP_ROOT /app_name 
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN gem install bundler
RUN bundle install
ADD . $APP_ROOT
docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_DATABASE: root
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
    ports:
      - "3305:3306"
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/app_name
      - ~/.ssh:/root/.ssh
volumes:
  mysql_data:
config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_general_ci
  pool: 5
  #以下の3行が重要
  username: root
  password:
  host: db
  #
  timeout: 5000

development:
  <<: *default
  database: sample_app_development #sample_appの部分は、アプリ名に応じて修正

test:
  <<: *default
  database: sample_app_test #sample_appの部分は、アプリ名に応じて修正
terminal
$ docker-compose build
$ docker-compose up -d
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

http://localhost:3000/ にアクセスして、アプリのトップページが表示さればひとまず成功。

遭遇したエラー

.envファイル内のスペース

.env
HOGE_KEY = age053nf3g3jk0 
HOGE_KEY=age053nf3g3jk0 #◯

RUN gem install bundler

Dockerfile
RUN gem install bundler #この行が無いとエラーがでたので追加した
RUN bundle install
ADD . $APP_ROOT

MYSQL_ALLOW_EMPTY_PASSWORD: 1

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: root
      MYSQL_ALLOW_EMPTY_PASSWORD: 1 #この行が無いとエラーがでたので追加した

db:createが通らない

ここでめっちゃハマった。まじきつかった。
docker-compose down --volumesからのdocker-compose up -d --buildで解決する的な情報があって、試してみたけどうまくいかず。
docker-compose.ymlenvironmentと、database.ymlの値をゴニョゴニョして(今の形にして)

terminal
$ docker-compose down --rmi all
$ docker-compose build
$ docker-compose up -d
$ docker-compose run web rails db:create

で解決。

ローカルの変更が反映されない

docker-compose.ymlweb>volumesの箇所が間違っていた。
Dockerfile内で作成したディレクトリapp_nameを記述することで解決。

コンテナを削除するたびにDBのデータが消える

名前付きボリュームを設定して解決。これでdownupした時、以前のデータが残ったままになりました。

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes: #ここと
      - mysql_data:/var/lib/mysql
.
.
volumes: #ここ!
  mysql_data:

DBのデータを永続化する方法には、
・名前つきボリューム
・匿名ボリューム
・ローカルのディレクトリのマウント、
の3つがあって、名前つきボリュームが一番良いらしい。

Dockerのデータを永続化!Data Volume(データボリューム)の理解から始める環境構築入門
Docker、ボリューム(Volume)について真面目に調べた

変な感じでコンテナを停止しちゃった後、再開できなくなる時がある

rails sの前にPIDを削除するように設定する

docker-compose.rb
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

ローカルからデータベースに接続できない

3306のポートは、ローカルのmysqlで埋まっているので、ポートを3305に変えて接続

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_DATABASE: root
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
    ports:
      #- "3306:3306"
      - "3305:3306"

TablePlusの設定例
 2020-03-11 18.08.23.png

RSpecのSystem Specが動かない

Dockerfileにchromeをインストールする記述を追加(不要な人もいるかもなので、記事冒頭の「うまくいった方法」には載せてないです。)

RUN apt-get update && apt-get install -y unzip && \
    CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
    wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ && \
    unzip ~/chromedriver_linux64.zip -d ~/ && \
    rm ~/chromedriver_linux64.zip && \
    chown root:root ~/chromedriver && \
    chmod 755 ~/chromedriver && \
    mv ~/chromedriver /usr/bin/chromedriver && \
    sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \
    sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \
    apt-get update && apt-get install -y google-chrome-stable

RUN mkdir /app_name 
.
.

Better Errorsが使えない

config/environments/development.rb
#以下を追加
if Rails.env.development?
  BetterErrors::Middleware.allow_ip! "0.0.0.0/0"
end

dockerで立ち上げたrailsサーバでもBetter Errorsを使えるようにする

ssh接続ができなくなった

volumes~/.ssh:/root/.sshを追記→パーミッションを変更

docer-compose.yml
version: '3'
#省略
  web:
    #省略
    volumes:
      - .:/app_name
      - ~/.ssh:/root/.ssh #この行を追加
volumes:
  mysql_data:

ローカルで設定した秘密鍵のパーミッションは引き継がれないので、手動で変更する必要があります。

$ docker-compose exec web /bin/bash
$ cd /root/.ssh
$ chmod 600 id_rsa

その他のサンプル

Rails6 + Postgres
Dockerfile
FROM ruby:2.6.5

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

#Rails6はyarnが必要!!
RUN apt-get update && apt-get install -y 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

RUN mkdir /app_name 
ENV APP_ROOT /app_name 
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN gem install bundler
RUN bundle install
ADD . $APP_ROOT
docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - psgl_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: password
    ports:
      - 5433:5432
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/app_name
volumes:
  psgl_data:
config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  #以下の3行が重要
  host: db
  username: root
  password: password
config/webpacker.yml
#check_yarn_integrity: true
check_yarn_integrity: false


DBのデータをローカルにマウントする場合
docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./dbdata:/var/lib/postgresql/data #ローカルのdbdataディレクトリにデータを保存して同期
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: password
    ports:
      - 5434:5432
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - "3000:3000"
    volumes:
      - .:/app_name
#トップレベルのvolumesは不要

参考

最後に

改善できるところがあったら指摘してもらえると嬉しいです。

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
What you can do with signing up
8