LoginSignup
14
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は不要

参考

最後に

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

14
8
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
14
8