概要
Docker上にRailsコンテナを構築する。
Rails Container <- Here
---------------------------------
Docker
---------------------------------
Vagrant (CentOS)
---------------------------------
VirtualBox
---------------------------------
LocalMachine (OS X)
関連ページ
前提となる環境
- Host
- OS: Mac OS X
- VirtualBox 4.2.26
- Vagrant 4.3.26
-
- OS: CentOS 7.1
- Docker 1.5.0-dev
-
- OS: CentOS 7.1
- MySQL Container (5.6.23)
- Data Container
目的
- Docker上で使い捨てのRailsコンテナを立ち上げる
- アプリケーションはNFS (ホスト共有ディレクトリ) 領域に配置
- データは永続コンテナに配置しても良いのだが、ホスト側でソース以外のファイルを編集する可能性を考慮して、ここではNFSを採用した
- DBはMySQL (MySQLコンテナ) を使用
- データは永続コンテナに配置
- ホストからゲストOSのIPを指定してRailsに接続できるようにする
- SSHサーバをインストールして、ホストOSからSSH接続を許可する
- ポートは3022を使用
- SSH接続には公開鍵認証を用いる (ここでは接続ユーザを"webapp"とする)
実行手順
ビルドファイルの作成
ゲストOS上でRailsコンテナを構築するためのDockefileを作成する。
$ mkdir -p ~/containers/rails
$ cd ~/containers/rails
~/containers/rails/Dockerfile
FROM centos:latest
MAINTAINER Naomichi Yamakita <n.yamakita@gmail.com>
## システムの更新
RUN yum -y update
RUN yum remove -y vim-minimal
# 一般的な開発ライブラリの構築
RUN yum install -y passwd wget hostname tar make gcc zlib-devel git sudo net-tools ntp vim-enhanced gcc-c++
# MySQL関連のライブラリ
RUN yum install -y libffi-devel.x86_64 readline-devel mysql mysql-devel
# SSH関連のライブラリ
RUN yum install -y openssl-devel openssh-server
## システムの設定
RUN cp -p /usr/share/zoneinfo/Japan /etc/localtime
RUN echo "PATH=\$PATH:/usr/local/bin" >> /root/.bashrc
RUN echo "export PATH" >> /root/.bashrc
## SSHの設定
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -C '' -N ''
RUN sed -ri 's/#RSAAuthentication/RSAAuthentication/g' /etc/ssh/sshd_config
RUN sed -ri 's/#PubkeyAuthentication/PubkeyAuthentication/g' /etc/ssh/sshd_config
RUN sed -ri 's/#PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
RUN sed -ri 's/#ClientAliveInterval 0/ClientAliveInterval 15/g' /etc/ssh/sshd_config
RUN sed -ri 's/#ClientAliveCountMax 3/ClientAliveCountMax 3/g' /etc/ssh/sshd_config
RUN echo 'root:root'|chpasswd
## "webapp"ユーザの追加
RUN sed -ri 's/Defaults requiretty/# Defaults requiretty/g' /etc/sudoers
RUN useradd -m -s /bin/bash webapp
RUN mkdir /home/webapp/.ssh
RUN chmod 700 /home/webapp/.ssh
RUN chown webapp:webapp /home/webapp/.ssh
ADD build/authorized_keys /home/webapp/.ssh/
RUN chmod 600 /home/webapp/.ssh/authorized_keys
RUN chown webapp:webapp /home/webapp/.ssh/authorized_keys
RUN echo 'webapp ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/webapp
RUN echo "LANG=en_US" >> /home/webapp/.bash_profile
RUN echo "export LANG" >> /home/webapp/.bash_profile
# 秘密鍵の登録
ADD build/id_rsa /home/webapp/.ssh/
RUN chown webapp:webapp /home/webapp/.ssh/id_rsa
RUN chmod 400 /home/webapp/.ssh/id_rsa
# Gitの設定
ADD build/.gitconfig /home/webapp/
RUN chown webapp:webapp /home/webapp/.gitconfig
## Vimの設定
RUN mkdir /home/webapp/repos
RUN cd /home/webapp/repos && \
git clone https://github.com/naomichi-y/vim.git
RUN chown -Rf webapp:webapp /home/webapp/repos
RUN ln -s /home/webapp/repos/vim/source/.vim /home/webapp/.vim
RUN chown -Rf webapp:webapp /home/webapp/.vim
RUN ln -s /home/webapp/repos/vim/source/.vimrc /home/webapp/.vimrc
RUN chown -Rf webapp:webapp /home/webapp/.vimrc
## Rubyのインストール
RUN cd /usr/local/src && \
wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.1.tar.gz && \
tar zxvf ruby-2.2.1.tar.gz && \
cd ruby-2.2.1 && \
./configure --disable-install-doc && \
make && \
make install
RUN echo 'gem: --no-document' > /usr/local/etc/gemrc
RUN yum install -y patch
RUN gem update --system
## Bundlerのインストール
RUN gem install bundler
## SSH、Railsの起動
EXPOSE 22 3000
ADD build/start_server /usr/bin/
RUN chmod +x /usr/bin/start_server
CMD ["/usr/bin/start_server"]
- GitやVimの設定を変更しているが、これらは各々の環境に合わせて変更すれば良い。
- 便宜上、SSHには公開鍵認証を用いているが、開発環境であればパスワード認証でも良いと思う。
Vagrantfileで参照しているファイルは次の通り。
~/containers/rails/build/.gitconfig
[user]
name = naomichi-y
email = n.yamakita@gmail.com
[mergetool]
keepBackup = true
[core]
editor = /usr/bin/vim
quotepath = false
[http]
sslVerify = false
~/containers/rails/build/authorized_keys
# SSHの公開鍵ファイル。ホストOSから接続するために必要。
***
~/containers/rails/build/id_rsa
# SSHの秘密鍵ファイル。コンテナからGitにファイルをコミットする際に使用
***
~/containers/rails/build/start_server
#!/bin/bash
## start rails
cd /var/www
bundle exec rails server -b 0.0.0.0 -d
## start sshd
/usr/sbin/sshd -D
***
ビルド
続いてDockerfileをビルドする。環境にもよるが、数十分の時間を要する。
$ docker build -t rails .
ビルドが完了したらコンテナを立ち上げる。
# -h コンテナのホスト名
# -v: ゲストOS (ホストOS) のNFS領域をコンテナへマウント
# --link: MySQLコンテナに接続できるようにする
$ docker run \
-h rails-local \
-p 3022:22 \
-p 3000:3000 \
--name rails \
-d \
-v /home/vagrant/Projects:/var/www \
--volumes-from=storage \
--link mysql:mysql \
rails
Dockerのプロセス一覧にrailsの名前が表示されているか確認。
[vagrant@localhost rails]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bc54058a045 rails:latest "/usr/bin/start_serv 6 seconds ago Up 4 seconds 0.0.0.0:3000->3000/tcp, 0.0.0.0:3022->22/tcp rails
6c43ca8325be mysql:latest "/usr/local/bin/star 2 days ago Up 36 hours 0.0.0.0:3306->3306/tcp mysql
続いてホストOSからRailsコンテナにSSH接続できることを確認する。
$ ssh -i ~/.ssh/id_rsa -p 3022 webapp@10.0.0.10
The authenticity of host '[10.0.0.10]:3022 ([10.0.0.10]:3022)' can't be established.
RSA key fingerprint is ***
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[10.0.0.10]:3022' (RSA) to the list of known hosts.
Last login: Thu Apr 9 23:59:33 2015 from 10.0.2.2
$
プロジェクトの作成
/var/www
は共有ディレクトリのため、この下にアプリケーションを作成する。
$ cd /var/www
$ rails new hello -d mysql
$ sudo mkdir /opt/rails
$ sudo chown webapp:webapp /opt/rails
$ bundle install --path=/opt/rails/vendor/bundle
...
Bundled gems are installed into /opt/rails/vendor/bundle.
ここではライブラリのインストール先をデータコンテナに設定した。理由は2点ある。
- アプリケーションディレクトリ (NFS領域) にパッケージインストールしようとすると何故かエラーが出て失敗した (URLを失念したが、他のサイトでも同現象が報告されていた)。
- コンテナという特性上、Gemはシステム領域にインストールでも良いのだが、開発中はライブラリの入れ替えが多く、その度にビルドするのが面倒。
最後にRailsを起動する。
bundle exec rails server -b 0.0.0.0
http://10.0.0.10:3000/ にアクセスできることを確認する。
自動起動の設定
vagrant up
時にRailsを起動したいのであれば、MySQLコンテナ 同様にプロビジョニングファイルの設定を追加する。
provision/always.sh
#!/usr/bin/bash
echo "start containers"
docker start mysql
docker start rails
vagrand reload
でrailsが起動していることを確認する。
$ vagrant reload
...
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: to force provisioning. Provisioners marked to run always will still run.
==> default: Running provisioner: shell...
default: Running: /var/folders/nm/m391v5jn1wsc1hpltn2gq3r40000gn/T/vagrant-shell20150405-2988-1du2a2q.sh
==> default: start containers
==> default: mysql
==> default: rails
...
$ vagrant ssh
# プロセスが動作しているか確認
$ ps ax|grep rails
ps ax|grep rai[vagrant@localhost ~]$ ps ax|grep rails
5756 pts/0 S+ 0:00 vim rails/Dockerfile
22328 pts/2 S+ 0:00 grep --color=auto rails```