方針
- Dockerを使ってRails環境を構築する
- base OSとしてCentOSを利用1
- Rubyは2.3.4を利用2
- railsをはじめとするbundler gemは全てシステム(docker Container内)へインストール3
- Rails projectのソースはコンテナ外部(ホストOSとの共有領域)に作成
環境構築
Docker imageの作成
次のDockerfileを用意します。
FROM centos
MAINTAINER takaeda
# set ruby version to be installed
ENV ruby_ver="2.3.4"
RUN yum -y update
RUN yum -y install epel-release
RUN yum -y install git make autoconf curl wget
RUN yum -y install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel sqlite-devel bzip2
RUN yum clean all
# install ruby & bundler
RUN git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
RUN git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build
RUN echo 'export RBENV_ROOT="/usr/local/rbenv"' >> /etc/profile.d/rbenv.sh
RUN echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile.d/rbenv.sh
RUN echo 'eval "$(rbenv init --no-rehash -)"' >> /etc/profile.d/rbenv.sh
RUN source /etc/profile.d/rbenv.sh; rbenv install ${ruby_ver}; rbenv global ${ruby_ver}
RUN source /etc/profile.d/rbenv.sh; gem update --system; gem install --no-ri --no-rdoc rails; gem install bundler
# make workdir for rails projects
RUN mkdir -p /work
以下の作業はこのDockerfileを置いたディレクトリで実行することを想定しています。
[host]$ ls
Dockerfile
[host]$
docker buildでイメージを生成。
[host]$ docker build -t takaeda/rails .
Sending build context to Docker daemon 3.072kB
Step 1/15 : FROM centos
.
.
.
Successfully built 62b21f9aa104
Successfully tagged takaeda/rails:latest
[host]$
ここで、-t
オプションで指定したtakaeda/rails
というタグ名は適当に変更してください。
Docker Containerの起動
Docker Containerを起動します。
[host]$ docker run -i -d -p 8080:3000 -v "${PWD}:/work" --name 'rails' takaeda/rails
214542b4f2755d1d8f01c7f856cfc208f0e67b775d113e37cffa5b56e3e4a264
[host]$
docker runのオプションの説明
`-i` => attachされなくてもSTDINを維持 `-d` => バックグラウンド実行 `-p HostPort:ContainerPort` => ContainerPortをHostPortへ割り当て `-v HostVolume:ContainerVolume` => ホストのディレクトリ(HostVolume)とコンテナ内のディレクトリ(ContainerVolume)を共有 `--name name` => コンテナ名(適当に)ここでは、ホストポートを8080に4、ホストボリュームを現在のディレクトリ${PWD}に割り当てましたが、これらは手元の条件に合わせて適宜変更してください。
以上で環境構築は完了です。
新しくRails projectを作成する場合
前節で`rails'と名付けて起動したDocker Container内に入ります。
[host]$ docker exec -it rails /bin/bash
[root@214542b4f275 /]#
/work
ディレクトリへ移動してrails new project
などと実行して新しいRails projectを作成してください。
[root@214542b4f275 /]# cd /work
[root@214542b4f275 work]# rails new project
create
create README.md
create Rakefile
create config.ru
create .gitignore
create Gemfile
.
.
.
Bundle complete! 16 Gemfile dependencies, 70 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
run bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
[root@214542b4f275 work]#
ここでいつもどおり:-) project/Gemfile
を編集して# gem 'therubyracer', platforms: :ruby
の行をコメントアウトします。
[root@214542b4f275 work]# vi project/Gemfile
.
.
# See https://github.com/rails/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby # この行をコメントアウト
.
.
あとはproject
ディレクトリに移ってrails server
を起動するだけです。
[root@214542b4f275 work]# cd project
[root@214542b4f275 project]# rails s
=> Booting Puma
=> Rails 5.1.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.4-p301), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Host環境からcurl -i --head http://localhost:8080
などとして接続を確認してください。
[host]$ curl -i --head http://localhost:8080
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
ETag: W/"9af74e9d7d13613de8018a96f1a1658e"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 8f71bbdd-dcc4-4c03-a6cd-a348d6884ee1
X-Runtime: 0.028164
既存のRails projectを使う場合
先ほどと同様、まずはDocker Containerへ入ります。
[host]$ docker exec -it rails /bin/bash
[root@214542b4f275 /]#
ここでは、既存のRails 4.0.5のprojectが/work/project
に展開されているとします。
/work/project
ディレクトリへ移動してbundle install
を実行します。
[root@214542b4f275 /]# cd /work/project
[root@214542b4f275 project]# bundle install
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this application for all non-root users on this
machine.
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Fetching rake 12.0.0
.
.
.
Fetching rails 4.0.5
Installing rails 4.0.5
Bundle complete! 10 Gemfile dependencies, 47 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
[root@214542b4f275 project]#
もしここで次のようなエラーが表示された場合はこちらへ。
rbenv: version `2.2.2' is not installed (set by /work/project/.ruby-version)
エラーがなければrails server
を起動して問題がないことを確認します。
[root@214542b4f275 project]# rails s
/usr/local/rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/activesupport-4.0.5/lib/active_support/values/time_zone.rb:283: warning: circular argument reference - now
=> Booting WEBrick
=> Rails 4.0.5 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2017-06-09 07:16:45] INFO WEBrick 1.3.1
[2017-06-09 07:16:45] INFO ruby 2.3.4 (2017-03-30) [x86_64-linux]
[2017-06-09 07:16:45] INFO WEBrick::HTTPServer#start: pid=581 port=3000
サーバがうまく起動しない場合は自力でトラブルシュートしてください。
Rails projectで利用するRubyのバージョンに制約がある場合
既存のRails pojectディレクトリでbundle install
したときに次のようなエラーが表示される場合があります。
rbenv: version `2.2.2' is not installed (set by /work/project/.ruby-version)
これはrbenv local
で「このRails projectで使われるRubyのバージョンが特定のバージョンに限定されている」ケースと考えられます。ここで.ruby-version
ファイルを消してbundle install
を実行するのはいささか乱暴です。
素直にこの制約に従うべく、Docker Containerの中で次の作業をおこなってください。
[root@214542b4f275 project]# rbenv install `cat .ruby-version`
sha256sum: the --quiet option is meaningful only when verifying checksums
Try 'sha256sum --help' for more information.
Downloading ruby-2.2.2.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.bz2
Installing ruby-2.2.2...
Installed ruby-2.2.2 to /usr/local/rbenv/versions/2.2.2
[root@214542b4f275 project]# gem install bundler
Fetching: bundler-1.15.1.gem (100%)
Successfully installed bundler-1.15.1
Parsing documentation for bundler-1.15.1
Installing ri documentation for bundler-1.15.1
Done installing documentation for bundler after 4 seconds
1 gem installed
[root@214542b4f275 project]# bundle install
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this application for all non-root users on this
machine.
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Fetching rake 12.0.0
.
.
.
Installing rails 4.0.5
Bundle complete! 10 Gemfile dependencies, 47 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
ここまでエラーが出なければ、あとはサーバーを起動してください。
[root@214542b4f275 project]# rails s
/usr/local/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.0.5/lib/active_support/values/time_zone.rb:283: warning: circular argument reference - now
=> Booting WEBrick
=> Rails 4.0.5 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2017-06-09 07:48:27] INFO WEBrick 1.3.1
[2017-06-09 07:48:27] INFO ruby 2.2.2 (2015-04-13) [x86_64-linux]
[2017-06-09 07:48:27] INFO WEBrick::HTTPServer#start: pid=15572 port=3000
-
2017/06/19時点での最新版は7.3.1611 ↩
-
Rails4と5の両方をカバーするには最低でもruby 2.2.2が必要となります。なお、Ruby 2.3.4とRails 4との相性については検証不足です。すみません。 ↩
-
一般には、
bundle install --path vendor/bundle
などとしてrails projectディレクトリ以下にbundler gemをインストールすることが多いのですが、その方法だとVagrantやVirtualBoxといった仮想マシンとのファイル共有下で開発を行う場合(筆者の環境がそれです)、rakeとかrails serverの起動とかがいちいち遅くて本当に酷いです。これは共有ファイルへのI/O速度が低いのが原因です。ですので、ここではbundler gemをシステム側(docker container内)へインストールすることにしました。なお、プロダクトをデプロイする時にbundle install --deployment
としてrails projectディレクトリ以下にbunder gemをインストールしてやれば特に問題はないかなと思います。 ↩ -
MacやMS WindowsでVirtualBox等VMを介してDockerを利用している場合、このホストポートはVMのポートとなります。手元のブラウザから
http://127.0.0.1:8080
やhttp://localhost:8080
などとしてRailsプロジェクトへアクセスする場合は、VMとHost OS (Mac, MS Windows)間でのポートフォーワードの設定が必要となります。 ↩