LoginSignup
22
16

More than 5 years have passed since last update.

Dockerを使って古いRails+MySQLを塩漬けした話

Last updated at Posted at 2017-01-03

7年前に書いたRuby 1.8 + Rails 1.2.6 + MySQL 5.0のアプリがあり、ほとんど使ってないけど、たま~に使うので、扱いに困っていました。

そこで、今動いているミドルウェアのバージョンをそのままにDockerでコンテナ化して、どんな環境にも移動できるようにしました。これでどこでも昔のバージョンのまま動き続けることができる、いわるゆ塩漬けです!

それを紹介します。

Dockerの実行環境

  • CentOS Linux release 7.1.1503
  • Docker version 1.10.3, build 3999ccb-unsupported

塩漬け対象アプリの構成

  • ミドル
    • Ruby1.8.7
    • Ruby on Rails 1.2.6
    • MySQL 5.0.77
  • アプリ
    • bitbucketにあるレポジトリを/usr/local/myappにcloneして動作させる
  • データ
    • MySQLにあるデータベースの中のテーブル一式

DBのコンテナ化

Dockerfileの準備

MySQLの公式には5.0のイメージはなかったため、lsdriscollさんを参考にしつつ公式のCentOS 5.11のイメージをベースに自分で作ることにしました。

ファイル構成

 └ myapp-db
     ├ Dockerfile
     ├ initial.sql
     └ my.cnf

Dockerfileの内容

FROM centos:5.11
MAINTAINER fetaro@xxx.com
RUN yum -y install mysql-server-5.0.95-5.el5_9
COPY my.cnf /etc/my.cnf
COPY initial.sql /initial.sql
RUN  mysql_install_db --datadir=/var/lib/mysql --user=mysql
USER root
CMD ["mysqld_safe", "--init-file=/initial.sql", "--user=mysql"]

initial.sqlの内容

GRANT ALL PRIVILEGES ON *.* to root@'localhost' IDENTIFIED BY 'xxxx' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON myapp_production.* to myapp@'%' IDENTIFIED BY 'xxx';
GRANT ALL PRIVILEGES ON myapp_production.* to myapp@'localhost' IDENTIFIED BY 'xxx';
FLUSH PRIVILEGES;
CREATE DATABASE IF NOT EXISTS myapp_production DEFAULT CHARACTER SET utf8;
(以降テーブルの作成など)

my.cnfの内容

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
old_passwords=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
port=3306

イメージのビルド

Dockerfileのあるディレクトリで

docker build -t fetaro/myapp-db .

-t はイメージの名前指定。「DockerHubのユーザ名/」を頭につけるのが作法っぽいです。

確認

docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
fetaro/myapp-db             latest              2af6e1f44b8c        32 minutes ago      381.3 MB
docker.io/centos              5.11                b424fba01172        4 months ago        284.1 MB

ベースになっているcentosと自分で作ったmyapp-dbが見えます。

コンテナの生成&起動

docker run --name myapp-db  -d  fetaro/myapp-db

確認

# docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES
767b41356fa6        fetaro/myapp-db    "mysqld_safe --init-f"   33 minutes ago      Up 33 minutes                                myapp-db

このMySQLはポート指定していないため、外部からはアクセスできません。
しかし、Dockerのリンク機能を使って、次に作るWebアプリコンテナとリンクを結び、Docker内部で通信するようにするため問題ありません。

Webアプリのコンテナ化

Dockerfileの準備

ruby 1.8.7が動くベースイメージをDocker Hubから探し、docker.io/nvulane/ruby1.8.7を採用することにしました。

ファイル構成

 └ myapp-web
     └ Dockerfile

Dockerfileの内容

FROM docker.io/nvulane/ruby1.8.7
MAINTAINER fetaro@xxxx.com
WORKDIR /usr/local/
RUN apt-get install -y
RUN gem install rake  -v 0.8.7 --no-ri --no-rdoc
RUN gem install rails -v 1.2.6 --no-ri --no-rdoc

# アプリをbitbucketから取得して/usr/local/myappに展開(一行で書くのが作法)
RUN wget --no-check-certificate https://fetaro:xxxxxx@bitbucket.org/fetaro/myapp/get/master.zip \
  && unzip master.zip -d tmp \
  && mv tmp/* myapp \
  && rm -f master.zip

# 起動する時にプロジェクトホームにいる必要があるので移動
WORKDIR /usr/local/myapp/
CMD ["ruby", "script/server", "-e", "production"]

EXPOSE 3000

ポイントとして、Dockerは1コマンドごとにファイルシステムの差分を管理していくので、まとめて作業する場合はRUNを何行も書くのではなく1行で書くのが作法とのこと。そのためgitからアプリ取得して展開するところは1行で書いています。

イメージのビルド

Dockerfileのあるディレクトリで

docker build -t fetaro/myapp-web .

-tはイメージに名前を付けている。

確認

docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
fetaro/myapp-db             latest              2af6e1f44b8c        37 minutes ago      381.3 MB
fetaro/myapp-web            latest              abc6e670ee65        About an hour ago   488.9 MB
docker.io/centos              5.11                b424fba01172        4 months ago        284.1 MB
docker.io/nvulane/ruby1.8.7   latest              b9b3d6f40baf        5 months ago        451.8 MB

新たにruby1.8.7のイメージとmyapp-webのイメージができていることがわかる。

コンテナの作成&起動

docker run --name myapp-web -d -p 3000:3000 -t --link myapp-db:myapp-db fetaro/myapp-web

ポイントは--linkにてmyapp-dbコンテナとリンクしているところ。これによりmyapp-webコンテナの/etc/hostsに myapp-dbのエントリが追加され、アプリからはmyapp-dbというホスト名で接続できます。

確認

CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES
6c40992e1373        fetaro/myapp-web   "ruby script/server -"   36 minutes ago      Up 36 minutes       0.0.0.0:3000->3000/tcp   myapp-web
767b41356fa6        fetaro/myapp-db    "mysqld_safe --init-f"   38 minutes ago      Up 38 minutes                                myapp-db

myapp-webとmyapp-dbが起動していることが分かります。

これで完成!ポート3000にアクセスすればアプリが使えます。

さいごに

この構成では、データの更新はmyapp-dbコンテナの中を直接更新する作りになっているため、コンテナを壊すと更新したデータは消えます。今回は塩漬けアプリでほとんど更新が無いためこの方式を採用していますが、データを外出ししたい場合はdockerのボリュームやデータコンテナを使うほうがよいでしょう。
また、docker compose等を使って二つのコンテナをまとめて管理したほうがよいらしいですが、次回以降のテーマとします。
あと、実行ユーザがかなり適当でrootでwebを動かしているので、これは変えたほうが良いさそうですが、めんどうなのでこのままで。

Docker初心者なので、いろいろ間違っているかもしれません。ツッコミ等があればどしどし下さい m(_ _)m

参考にしたドキュメント

Docker公式ホームページ
Docker ドキュメント日本語化プロジェクト
オライリージャパン出版「Docker」

22
16
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
22
16