参考
phusion/passenger-docker: Docker base images for Ruby, Python, Node.js and Meteor web apps
全体の流れ
- 開発モードでコンテナ化する ←今回の投稿
- コンテナからDBに接続できるようにする
- 本番モードでコンテナ化する
今回やること
- 開発モード(development)でRailsアプリをコンテナ化する
次回以降にやること
- RailsアプリのコンテナからDBに接続できるようにする
- 本番モード(production)でRailsアプリをコンテナ化する
もくじ
- Railsアプリを作成
- Dockerfileの作成
- nginxコンフィグを作成
- コンテナをビルド
- コンテナをローカルで起動
ソース一式
今回の投稿のために用意したソースは下記で公開しております。
qiita-rails-passenger-docker/1 at master · NaokiIshimura/qiita-rails-passenger-docker
ディレクトリ構成
今回の投稿のために用意した作業ディレクトリは以下の構成です。
ディレクトリ | 内容 |
---|---|
/ | Dockerfile |
/nginx | nginxコンフィグ一式 |
/rails-app | railsのソース一式 |
1. Railsアプリを作成
まずはコンテナ化するRailsアプリを用意します。
今回はアクセスした時に静的ページを表示するだけのアプリを用意しました。
2. Dockerfileの作成
Dockerfileについてはphusion/passenger-dockerリポジトリのREADMEを参考にRuby2.5を利用する設定としました。
今回は環境変数RAILS_ENV
にdevelopment
を指定してます。
今回は本番モード(production)で必要になる設定は省略してます。
##
# 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_env
にdevelopment
を指定してます。
今回は本番モード(production)で必要になる設定は省略してます。
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;
}
env SECRET_KEY=123456;
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アプリが表示されることを確認
補足
コンテナのビルドに成功してもRailsアプリへアクセスする際にエラーが発生することがあったので、エラー回避のために追加した設定について記録として残しておきます。
エラー回避1
以下はcannot load such file -- bundler/dep_proxy (LoadError)
を回避するために追加した記述です。
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>'
エラー回避2
以下はcannot load such file -- bundler/dep_proxy (LoadError)
を回避するために追加した記述です。
Gemfileを修正しても回避できますが、毎回Gemfileを書き換えるのは手間なのでtzdata
をインストールして回避することにしました。
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>'