LoginSignup
6
5

More than 5 years have passed since last update.

passenger-dockerでRailsアプリをコンテナ化する(1. 開発モードでコンテナ化する)

Last updated at Posted at 2018-03-25

passenger-rails.png

参考

phusion/passenger-docker: Docker base images for Ruby, Python, Node.js and Meteor web apps

全体の流れ

  1. 開発モードでコンテナ化する ←今回の投稿
  2. コンテナからDBに接続できるようにする
  3. 本番モードでコンテナ化する

今回やること

  • 開発モード(development)でRailsアプリをコンテナ化する

次回以降にやること

  • RailsアプリのコンテナからDBに接続できるようにする
  • 本番モード(production)でRailsアプリをコンテナ化する

もくじ

  1. Railsアプリを作成
  2. Dockerfileの作成
  3. nginxコンフィグを作成
  4. コンテナをビルド
  5. コンテナをローカルで起動

ソース一式

今回の投稿のために用意したソースは下記で公開しております。
qiita-rails-passenger-docker/1 at master · NaokiIshimura/qiita-rails-passenger-docker

ディレクトリ構成

今回の投稿のために用意した作業ディレクトリは以下の構成です。

ディレクトリ 内容
/ Dockerfile
/nginx nginxコンフィグ一式
/rails-app railsのソース一式

passenger-rails-102.png

1. Railsアプリを作成

まずはコンテナ化するRailsアプリを用意します。
今回はアクセスした時に静的ページを表示するだけのアプリを用意しました。

passenger-rails-101.png

2. Dockerfileの作成

Dockerfileについてはphusion/passenger-dockerリポジトリのREADMEを参考にRuby2.5を利用する設定としました。
今回は環境変数RAILS_ENVdevelopmentを指定してます。
今回は本番モード(production)で必要になる設定は省略してます。

Dockerfile
##
# phusion/passenger-docker
# https://github.com/phusion/passenger-docker

##
# Getting started

# Ruby images
FROM phusion/passenger-ruby25:latest

# ...put your own build instructions here...

##
# Nginx

# Using Nginx and Passenger
RUN rm -f /etc/service/nginx/down

# Using Nginx and Passenger
RUN rm /etc/nginx/sites-enabled/default
ADD nginx/webapp.conf /etc/nginx/sites-enabled/webapp.conf

# Configuring Nginx
ADD nginx/secret_key.conf /etc/nginx/main.d/secret_key.conf
ADD nginx/gzip_max.conf /etc/nginx/conf.d/gzip_max.conf

##
# Rails application

# Set correct environment variables.
ENV RAILS_ENV development

# Your application should be placed inside /home/app.
COPY --chown=app:app rails-app /home/app/webapp

# bundlerのインストール
# 実行しなかった場合、Railsアプリにアクセスした時に以下のエラーが発生する
# cannot load such file -- bundler/dep_proxy (LoadError)
RUN gem install bundler

# tzdataのインストール
# 実行しなかった場合、Railsアプリにアクセスした時に以下のエラーが発生する
# tzinfo-data is not present.
# Please add gem 'tzinfo-data' to your Gemfile
# and run bundle install (TZInfo::DataSourceNotFound)
RUN apt-get update && apt-get install -y \
  tzdata

# タイムゾーンをJSTに設定
ENV TZ=Asia/Tokyo

# bundle install
WORKDIR /home/app/webapp
RUN bundle install

# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Use baseimage-docker's init process.
CMD ["/sbin/my_init"]

3. nginxコンフィグを作成

Dockerfileと同様にphusion/passenger-dockerリポジトリのREADMEを参考にRuby2.5を利用する設定としました。
今回はパラメータpassenger_app_envdevelopmentを指定してます。
今回は本番モード(production)で必要になる設定は省略してます。

nginx/webapp.conf
server {
  listen 80;
  server_name www.webapp.com;
  root /home/app/webapp/public;

  # The following deploys your Ruby/Python/Node.js/Meteor app on Passenger.

  # Not familiar with Passenger, and used (G)Unicorn/Thin/Puma/pure Node before?
  # Yes, this is all you need to deploy on Passenger! All the reverse proxying,
  # socket setup, process management, etc are all taken care automatically for
  # you! Learn more at https://www.phusionpassenger.com/.
  passenger_enabled on;
  passenger_user app;

  # If this is a Ruby app, specify a Ruby version:
  passenger_ruby /usr/bin/ruby2.5;

  # Ensures that RAILS_ENV, NODE_ENV, etc are set to "staging"
  # when your application is started.
  passenger_app_env development;

}
nginx/secret_key.conf
env SECRET_KEY=123456;
nginx/gzip_max.conf
gzip_comp_level 9;

4. コンテナをビルド

$ docker build -t rails-image .

...
Successfully built f1dc75a6cd5b
Successfully tagged rails-image:latest

5. コンテナをローカルで起動

$ docker run -p 3000:80  rails-image

ブラウザでhttp://localhost:3000にアクセスしてRailsアプリが表示されることを確認

passenger-rails-101.png

補足

コンテナのビルドに成功してもRailsアプリへアクセスする際にエラーが発生することがあったので、エラー回避のために追加した設定について記録として残しておきます。

エラー回避1

以下はcannot load such file -- bundler/dep_proxy (LoadError)を回避するために追加した記述です。

Dockerfile
RUN gem install bundler

指定がなかった時には以下のエラーが発生してました。

cannot load such file -- bundler/dep_proxy (LoadError)
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:135:in `require'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:39:in `require'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:888:in `block (2 levels) in expand_dependencies'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:887:in `each'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:887:in `block in expand_dependencies'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:874:in `each'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:874:in `expand_dependencies'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:806:in `converge_locked_specs'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:247:in `resolve'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:170:in `specs'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:237:in `specs_for'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/definition.rb:226:in `requested_specs'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:108:in `block in definition_method'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:20:in `setup'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler.rb:107:in `setup'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/setup.rb:20:in `<top (required)>'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
  /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:456:in `activate_gem'
  /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:323:in `block in run_load_path_setup_code'
  /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:461:in `running_bundler'
  /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:322:in `run_load_path_setup_code'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:100:in `preload_app'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:156:in `<module:App>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:30:in `<module:PhusionPassenger>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<main>'

参考:Getting "bundler: failed to load command: rake" after upgrading to ruby 2.5.0 · Issue #8978 · travis-ci/travis-ci

エラー回避2

以下はcannot load such file -- bundler/dep_proxy (LoadError)を回避するために追加した記述です。
Gemfileを修正しても回避できますが、毎回Gemfileを書き換えるのは手間なのでtzdataをインストールして回避することにしました。

Dockerfile
RUN apt-get update && apt-get install -y \
  tzdata

指定がなかった時には以下のエラーが発生してました。

tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install (TZInfo::DataSourceNotFound)
  /usr/local/rvm/gems/ruby-2.5.0/gems/activesupport-5.1.5/lib/active_support/railtie.rb:22:in `rescue in block in <class:Railtie>'
  /usr/local/rvm/gems/ruby-2.5.0/gems/activesupport-5.1.5/lib/active_support/railtie.rb:19:in `block in <class:Railtie>'
  /usr/local/rvm/gems/ruby-2.5.0/gems/railties-5.1.5/lib/rails/initializable.rb:30:in `instance_exec'
  /usr/local/rvm/gems/ruby-2.5.0/gems/railties-5.1.5/lib/rails/initializable.rb:30:in `run'
  /usr/local/rvm/gems/ruby-2.5.0/gems/railties-5.1.5/lib/rails/initializable.rb:59:in `block in run_initializers'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:228:in `block in tsort_each'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:431:in `each_strongly_connected_component_from'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:349:in `block in each_strongly_connected_component'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:347:in `each'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:347:in `call'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:347:in `each_strongly_connected_component'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:226:in `tsort_each'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/tsort.rb:205:in `tsort_each'
  /usr/local/rvm/gems/ruby-2.5.0/gems/railties-5.1.5/lib/rails/initializable.rb:58:in `run_initializers'
  /usr/local/rvm/gems/ruby-2.5.0/gems/railties-5.1.5/lib/rails/application.rb:353:in `initialize!'
  /home/app/webapp/config/environment.rb:5:in `<top (required)>'
  config.ru:3:in `require_relative'
  config.ru:3:in `block in <main>'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.0.4/lib/rack/builder.rb:55:in `instance_eval'
  /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.0.4/lib/rack/builder.rb:55:in `initialize'
  config.ru:1:in `new'
  config.ru:1:in `<main>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `eval'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `preload_app'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:156:in `<module:App>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:30:in `<module:PhusionPassenger>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<main>'
6
5
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
6
5