前回の
WebアプリケーションをDocker化するときの考え方
Dockerの基本がわかったところで、
WebアプリケーションのDocker化の方針
Webアプリケーションを動作させるためには、
まず、
Dockerによる開発において、
Dockerは非常に有用なツールです。しかし、
Docker導入により解決したい課題
解決したい課題は状況により異なるため、
課題1:本番環境とローカル開発環境のOSが異なる
本番環境はLinuxサーバ上で動作しています。一方、
課題2:生成されるcpanfile.snapshotが異なる
CPANモジュールの管理にCartonを利用しています。しかし同じ内容のcpanfile
であっても、cpanfile.
と、cpanfile.
が異なることがあります。したがって、cpanfile.
を生成したいと考えています。
課題3:プロジェクトごとにミドルウェアのバージョンが異なる
複数プロジェクトの開発を並行して進めています。しかし、
課題4:DevとOps間のコミュニケーションコストがある
開発環境はアプリケーションエンジニア
課題の解決
これらの各課題について、
1つのコンテナに複数のWebアプリケーションやミドルウェアを詰め込むのか、
以上により、
PerlのWebアプリケーションをDocker化する方法
メインとなる本節では、
PerlがインストールされたDockerイメージの構築
まずは、
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -yq && \
apt-get install -yq --no-install-recommends \
build-essential \
curl \
ca-certificates \
tar \
bzip2 \
patch && \
apt-get clean && \
rm -rf /var/cache/apt/archives/* && \
rm -rf /var/lib/apt/lists/*
ENV PERL_VERSION 5.20.2
ENV PATH /opt/perl-$PERL_VERSION/bin:$PATH
ENV PERL_CARTON_PATH /cpan
RUN curl -sL http://git.io/perl-build > \
/usr/bin/perl-build
RUN chmod +x /usr/bin/perl-build
RUN perl-build $PERL_VERSION /opt/perl-$PERL_VERSION
RUN curl -sL http://cpanmin.us/ | \
/opt/perl-$PERL_VERSION/bin/perl - \
--notest App::cpanminus Carton
リスト2では、
Dockerfileと同じディレクトリで次のコマンドを実行すると、
$ docker build -t perl-5.20.2 .
本当にPerlがインストールされているかを確認するために、perl --version
を実行します。
$ docker run --rm -i -t perl-5.20.2 /bin/bash
root@0bf912ff086d:/# perl --version
-i
と-t
オプションにより、
PerlのWebアプリケーション向けのDockerfileの書き方
続いて、
Dockerfileの書き方は、
Bundled Container方式
Bundled Container方式のDockerfileをリスト3に示します。リスト2のDockerfileでビルドしたPerl入りのDockerイメージをFROMに指定しています。FROMによる継承を使わずに、
FROM perl-5.20.2
RUN apt-get update && \
apt-get install -yqq --no-install-recommends \
mysql-client-5.5 \
libmysqlclient-dev \
libssl-dev && \
apt-get clean && \
rm -rf /var/cache/apt/archives/* && \
rm -rf /var/lib/apt/lists/*
ENV APPROOT /code
RUN mkdir -p $APPROOT
WORKDIR /code
COPY cpanfile $APPROOT/cpanfile
RUN carton install
COPY ./ $APPROOT
EXPOSE 5000
CMD ["carton","exec","plackup","-a","script/local-server"]
リスト3ではまず、libmysqlclient-dev
などのCPANモジュールが依存するパッケージをインストールします。プロジェクト内のcpanfile
の内容によって、
次に、/code
ディレクトリ以下にWebアプリケーションコードが配置されるようにします。これ以降は/code
ディレクトリ以下で作業するため、
続いて、carton install
を実行します。ポイントは、carton install
の実行より先に、COPY
命令によりcpanfile
をDockerイメージ内に取り込んでいるところです。単純に考えれば、COPY
命令でWebアプリケーションコードをすべて取り込み、carton install
を実行すれば済みます。
COPY ./ $APPROOT
RUN carton install
しかし、COPY
命令は取り込むディレクトリ以下の内容が変化するとビルドキャッシュが無効になり、COPY
命令以下の命令はスキップされません。上記ではWebアプリケーションコードを変更するたびにcarton install
が一から実行されるため、cpanfile
だけ取り込むことにより、cpanfile
が変更されたときのみ、carton install
を実行するようにします。これは
最後に、CMD
命令によりplackup
を実行し、CMD
命令の内容は、docker run
コマンドの引数により上書きできます。したがって、
次のコマンドにより、plackup
はデフォルトで5000番ポートをListenするので、-p 5000:5000
を指定して、
$ docker build -t docker-sample .
$ docker run -d -p 5000:5000 docker-sample
Runtime Container方式
Runtime Container方式では、
リスト4にRuntime Container方式のDockerfileを示します。リスト3との違いは、COPY
命令によるWebアプリケーションコードの取り込みとcarton install
によるモジュールのインストールが省かれている点、VOLUME
命令により/code
と/cpan
をData Volumeとして指定している点です。
FROM perl-5.20.2
RUN apt-get update && \
apt-get install -yqq --no-install-recommends \
mysql-client-5.5 \
libmysqlclient-dev \
libssl-dev && \
apt-get clean && \
rm -rf /var/cache/apt/archives/* && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /code
EXPOSE 5000
VOLUME ["/code", "/cpan"]
WORKDIR /code
まず、
$ docker build -t docker-sample-runtime .
Runtime Container方式はあくまでPerlの実行環境のみを提供しています。リスト4のDockerfileをビルドしただけでは、carton install
は実行されません。
したがって、carton install
を実行する必要があります。docker run
には-v
オプションを付けて、--rm
オプションを付けることで、
$ docker run --rm -v ./:/code -v ./local:/cpan docker-samp le-runtime carton install
最後に、docker run
によりPlackサーバを起動します。
$ docker run -d -p 5000:5000 -v ./:/code -v ./local:/cpan docker-sample-runtime carton exec plackup -a script/localserver
両方式の比較
Dockerの思想の一つに、
しかしリスト3のDockerfileは、docker build
を実行しなければなりません。いくらcarton install
をスキップできるとはいえ、
そこで、
筆者は今のところ、
<続きの