LoginSignup
26
33

More than 3 years have passed since last update.

開発環境において既存のRailsアプリにDockerを導入する方法(Rails、nginx、mysql)

Last updated at Posted at 2020-06-13

※ DockerでRailsの環境構築をする方法に関して新しい記事を書いたので、下記を参照ください。 (2021/1/21更新)


Dockerに興味があり、作成したポートフォリオに組み込もうと思い、様々な記事を見ながら導入を試みましたが、かなり苦戦を強いられました。
無事導入することができましたので、今回は既存のRailsアプリにDockerを導入する方法を書いていきたいと思います。

環境

  • Mac OS
  • Ruby2.5.7
  • Rails5.2.4
  • mysql5.7
  • nginx1.15.8

事前準備

  • OS上に Docker と docker-compose をインストールしてください。 以下のコマンドを実行して、それぞれ表示されればインストールできています。
$ docker -v
Docker version 19.03.8, build afacb8b

$ docker-compose -v
docker-compose version 1.25.5, build 8a1c60f6

ファイル構成

ローカルのファイル構成は最終的に以下の通りになります。

myapp
  |-- app
  |-- bin
  |-- config
  |-- containers
    |-- nginx
      |-- Dockerfile
      |-- nginx.conf
  |-- db
  |-- lib
  |-- log
  |-- public
  |-- storage
  |-- test
  |-- tmp
  |-- vendor
  |-- config.ru
  |-- docker-compose.yml
  |-- Dockerfile
  |-- Gemfile
  |-- Gemfile.lock
  |-- package.json
  |-- Rakefile
  |-- README.md

RubyのDockerfileを作成

myappはご自身のアプリケーション名に変えてください。

Dockerfile
FROM ruby:2.5.7

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

RUN mkdir /myapp

WORKDIR /myapp

ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock

RUN gem install bundler
RUN bundle install

ADD . /myapp

RUN mkdir -p tmp/sockets
RUN mkdir -p tmp/pids
  • From に記述している ruby:2.5.7 はご自身のGemfileに書いてあるrubyのバージョンに合わせてください。
  • RUN gem install bundler を記述しないと、bundle install が実行できず、以下のようなエラーが表示され、rubyのコンテナが起動できません。
ERROR: Service 'app' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 20

NginxのDockerfileを作成

containers/nginx/Dockerfile
FROM nginx:1.15.8

RUN rm -f /etc/nginx/conf.d/*

ADD nginx.conf /etc/nginx/conf.d/myapp.conf

CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

nginx.confを作成

containers/nginx/nginx.conf
upstream myapp {
  server unix:///myapp/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name localhost;

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;

  root /myapp/public;

  client_max_body_size 100m;
  error_page 404             /404.html;
  error_page 505 502 503 504 /500.html;
  try_files  $uri/index.html $uri @myapp;
  keepalive_timeout 5;

  location @myapp {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://myapp;
  }
}

docker-compose.ymlの作成

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_USER: user
      MYSQL_PASSWORD: 1234
      MYSQL_DATABASE: myapp_db
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "4306:3306"

  app:
    build: .
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/myapp
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
      - log-data:/myapp/log

  web:
    build:
      context: containers/nginx
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80

volumes:
  mysql-data:
  public-data:
  tmp-data:
  log-data:

database.ymlを編集

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch('MYSQL_USER') { 'root' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: <%= ENV['DB_DATABASE'] %>
  adapter: mysql2
  encoding: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_general_ci
  host: <%= ENV['DB_HOST'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>

puma.rbを編集

puma.rbの最下部に以下の記述を追加

config/puma.rb
app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

Gemfileの編集

Gemfileに以下の記述を追加します。

Gemfile
gem 'mysql2'

コンテナの起動

あとはコンテナを起動するだけです。
アプリケーションのあるディレクトリに移動し以下のコマンドを実行します。

$ docker-compose up -d

しばらく経つと、最後に以下のように表示され、コンテナの起動が完了します。

Creating myapp_db_1  ... done
Creating myapp_app_1 ... done
Creating myapp_web_1 ... done

次のコマンドを実行し、コンテナが起動できているか確認します。
以下のように表示されれば、コンテナの起動は成功しています。

$ docker-compose ps
     Name                   Command               State                 Ports              
-------------------------------------------------------------------------------------------
myapp_app_1   bundle exec puma -C config ...   Up                                       
myapp_db_1    docker-entrypoint.sh mysqld      Up      0.0.0.0:4306->3306/tcp, 33060/tcp
myapp_web_1   /bin/sh -c /usr/sbin/nginx ...   Up      0.0.0.0:80->80/tcp               

データベースの作成、マイグレーションファイルの読み込み

最後に以下のコマンドでデータベースの作成とマイグレーションファイルの読み込みをします。

$ docker-compose exec app rails db:create db:migrate

localhost:80にアクセスして、正しくに表示されればOKです。

コンテナの停止、削除

以下のコマンドでコンテナの停止、削除ができます。

$ docker-compose down

再び起動したい場合は先ほどと同様、 "dokcer-compose up -d" でOKです。

以下のコマンドでvolumeも一緒に削除できます。(Mysqlのデータも全て消えるので注意!!)

$ docker-compose down -v

Docker導入後の開発

Docker導入後の開発(rails g コマンド や budle install)を行うには Railsのコンテナの中に入る必要があります。
コンテナが起動された状態で、以下のコマンドを実行し、コンテナの中に入ります。

$ docker-compose exec app bash

ターミナル画面の左側の コンピューター名やユーザー名 が表示されている部分が以下のような感じに変わればコンテナに入ることができています。

root@f839434ad777:/myapp#

コンテナに入り、以下のコマンドで、Docker導入前の rails s -b 0.0.0.0 で見れていたログを表示することができます。

$ tail -f log/development.log

以下のコマンドでコンテナから出ることができます。

$ exit

参考記事

26
33
1

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
26
33