RubyOnRailsコンテナを Docker Image に固める

Docker Image とは

Docker Image とはDockerが動作するホストであれば動作することの出来る、Docker コンテナを実行するパッケージをまとめたものです。例えばコンテナをVMの様に扱い、コンテナの中から環境を構築してそれをDocker Image ファイルとして書き出します。するとそのファイルを転送すればいつでも環境を再構築することが可能になります。

今回はCentOS上でRubyOnRailsのコンテナを構築し、それをDocker Image に固めたいと思います。これ系の記事はQeetaにたくさんあるのですが、ほとんどがMac上での方法でCentOS上での方法を解説した記事がありませんでした。固めたDocker Image 自体はどちらでも動くと思うのですが、Mac上でのDocker Image の固め方がCentOSでは上手くいかなかったのです。

準備

最新版のDockerとdocker-composeをインストールします。バージョンが古いと失敗することがあります。

諸々の必要なパッケージをインストール
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
リポジトリを追加
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Docker CEをインストール
sudo yum install -y docker-ce
sudo systemctl start docker
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

手順1

Dockerfileを作成します。CentOSをVMの様に使います。

$ cat Dockerfile
FROM centos:7

# update
RUN yum -y update && yum clean all

# set locale
RUN yum reinstall -y glibc-common && yum clean all
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Japan /etc/localtime

# editor install
RUN yum install -y vim && yum clean all

docker-compose.ymlを作成する。DBにはMySQL8.0を使用します。

$ cat docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  centos:
    build: .
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local

コンテナ起動。

docker-compose up -d

以上でCentOS7コンテナとDBコンテナを作成しました。次からはRailsの環境をCentOS7コンテナに入って作成していきます。尚、DBコンテナのDocker Imageエクスポートに関してはこの後触れることはないので、この時点で実施しても構わないのですが、後でまとめてやる事にします。

手順2

基本的には以前書いたRails環境構築の記事の通りです。まずはrbenvをインストールします。

yum update -y
yum install -y git
yum install -y bzip2 gcc openssl-devel readline-devel zlib-devel make
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

パスを通します。

# vi /root/.bashrc
export PATH="$PATH:/root/.rbenv/bin"
eval "$(rbenv init -)"
# source /root/.bashrc
# rbenv -v
rbenv 1.1.2-30-gc879cb0

Rubyをインストールします。

# rbenv install 2.7.1
# rbenv global 2.7.1
# ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

Railsをインストールします。

# gem install bundler
# bundle init
# gem install rails

いつものパッケージ群
# yum -y install gcc-c++
# gem install sassc -v 2.4.0
# yum -y install epel-release
# curl -sL https://rpm.nodesource.com/setup_14.x | bash -
# yum -y install nodejs
# npm install -g yarn

MySQLパッケージをインストールする。

railsとmysqlを繋ぐmysql2をインストールするのに必要なもの
# yum install -y mysql-devel

Railsプロジェクトを作成する。

プロジェクト作成。「bundle install」は後で、データベースはmysqlを指定
# rails new labo --database=mysql --skip-bundle --skip-test --skip-active-storage
# cd labo
# bundle install

config/database.ymlを編集。ホスト名はdocker inspect コンテナIDで取得。

# cat config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: 172.18.0.2
※一部抜粋

DBを作成する。

# rails db:create
Created database 'labo_development'
Created database 'labo_test'
# rails webpacker:install
# rails server -b 0.0.0.0

これでRailsの環境を作成できました。次はようやくイメージに書き出します。

Docker Image 書き出し

いよいよ「コンテナからイメージを作成→イメージをファイルに書き出し」という手順を解説していきます。

コンテナを元にイメージを作成する
# docker commit -m "MySQL8.0 Image" 【mysqlのコンテナID】 イメージ名
# docker commit -m "Rails6.0 Image" 【railsのコンテナID】 イメージ名
イメージが追加されます
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
rails6              latest              93cd214aa574        32 seconds ago      1.18GB
mysql8              latest              107b24c47d66        3 minutes ago       544MB
イメージをファイルに書き出します
# docker save rails6 > rails6.tar
# docker save mysql8 > mysql8.tar
# ls
Dockerfile  docker-compose.yml  mysql8.tar  rails6.tar

書き出したファイルは次の方法でインポート可能です。

# docker load < mysql8.tar
# docker load < rails6.tar
# docker images

下記のコマンドで起動すれば先ほどのrails環境を再現する事ができ、すぐに開発を始められます。

# docker run -d -p 3006:3006 --name mysql mysql8
# docker run -itd -p 3000:3000 --name rails rails6

以上です。

終わりに

Qeetaなどの記事ではDockerfileまで落とし込んで、「これを実行すれば動きます」みたいな手法がほとんどでした。恐らくそれがベストプラクティスだと思います。サーバは常に最小構成が理想なので、コンテナにも同様の事が言えます。しかしVMの様にコンテナを扱える事もDockerの強みです。上手くいかなければ簡単に掃除出来ますし、完成したらイメージファイルに書き出すだけで再利用が可能です。

要約するとわざわざQeetaの記事通りにDockerfileを作る事に固執する必要は無いという事です。なぜならVMの様にコンテナの中から環境を自力で作る方が速いこともあるからです。今回の様にDocker Image に書き出して再利用することも可能です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA