技術

自作プログラムをDockerコンテナとして配布しよう

こんにちは。

今回はDockerのコンテナ作成についてになります。

Dockerは、開発、インフラ問わず全てのITエンジニアにとって当たり前の存在となりました。

でも、大抵の人は Docker Hub にあるイメージを使っているだけじゃないでしょうか。今回は、自分で作成したプログラムや環境をDockerコンテナとして配布する利点とその方法を紹介します。

この記事が役に立つ人

Dockerコンテナを配布することになった人
Dockerを使ったことはあるけどコンテナを作ったことがない人

Dockerで配布する利点

具体的な方法の前に、Dockerコンテナを配布する利点について考えてみます。

Dockerコンテナで配布する利点とは何でしょうか? どうしてDockerはここまで一般的なものになったのでしょうか?

それは、Dockerコンテナだと複雑な動作環境を簡単に提供できるからです。

あるプログラムを作成して、それを他の人に使ってもらいたい状況があるとします。そのプログラムの動作条件が例えば、Python3.6以上、一般的でないライブラリがいくつか必要で、更に内製のJavaのツールとも連携しているためJavaの動作環境も必要だとしたらどうでしょうか。

動作条件

  • Python 3.6以上
  • library1 ver x.xx以上
  • library2 ver x.xx以上
  • library3 ver x.xx以上
  • Java 8

動作条件はこのような感じになります。

利用方法には、この環境があれば、位置引数が2つとオプション引数 -a, -b のプログラムが動きますよと記載されているとします。

python hello.py XXX YYYY -a AAA -b BBB

ユーザからしたら、こんなプログラムを配布されても全く使う気が起きません。動作環境を整えるだけで一苦労です。

しかし、これをDockerコンテナとして配布すれば、ユーザは環境を気にすることなく docker run コマンドを実行するだけOKになります。

docker run hello XXX YYYY -a AAA -b BBB

これだと、Dockerがインストールされていればいいだけなので、ユーザも使う気は起きるのではないでしょうか。

Dockerで配布する方法

Dockerコンテナとして配布する手順は、

  1. Dockerfile作成
  2. ビルド
  3. プッシュ(アップロード)

です。

環境構築時は、Dockerコンテナを立ち上げてそのコンテナに入って、パッケージupdateやinstallなどしていき、その時実行して成功したコマンドを Dockerfile に記載していくのが基本になります。そして環境構築が一通り終わったら、そのコンテナは破棄して、Dockerfileからビルドしたものを配布します。

docker commit で、環境構築完了後のコンテナを、そのままイメージとして保存して、アップする方法もあります。これだと Dockerfile作成やビルドの面倒くさい工程をすっ飛ばすことができます。

しかし、この方法は一般的には推奨されていません。部署内への配布等ならこの方法でも構わないと思いますが、不特定多数に配布する場合は、再現性や怪しいプログラムが動いていないことを証明する観点からも、Dockerfileからのビルドを提供するのが一般的です。

Dockerfile作成

まずは、Dockerfile を作成します。Dockerfileは、動作環境の構築手順書のようなものです。ベースとなる環境、OSなどを記載して、そこに行う動作を記載していきます。

もし納品とかで、サーバの構築手順書や構成図を下さいと要求されたら、Dockerfileを渡すのが一番理にかなっています。

それでも、相手が非エンジニアだったり社内フォーマットで既定がある場合は、ExcelやPowerPointを要求されかもしれませんが・・・

Dockerfileの記述方法は、そんなに複雑なものではありません。書式は限られています。FROM, WORKDIR, RUN, CMD, ENTRYPOINT ぐらいがわかれば、だいたいのDockerfileはなんとなくわかるかと思います。GitやDockerHubにサンプルがいくらでもあるので、それらを参考にすれば、すぐ書けるようになります。

各命令の詳細はネット上にくらでもありますが、ここでも簡単に紹介しておきます。

FROM

Dockerfileの最初に書く命令です。ベースとなるイメージ(環境、OS)指定します。docker commit コマンドで作成したオリジナルのイメージも指定できますが、基本はしない方がいいでしょう。Docker Hubにあるオフィシャルのイメージから選ぶべきです。

自分が配布するプログラムの基本となる動作環境のオフィシャルページからバージョン指定で選べばいいでしょう。例えば、Python3.6環境なら、公式ページにいって、TAGS画面でFilterに 3.6 と入力すれば該当イメージが表示されます。

バージョンの右にある -xxx という記載はOSです。Dockerでは、alpineなどの軽量OSが使われることが多いです。

FROM python:3.6.9-alpine3.9

と書けば、Python3.6環境のイメージができあがります。これをベースに、ファイルコピーやコマンド実行等を記載していって、自分が配布するイメージを作っていきます。

混合環境、例えばPythonとNodes.jsの環境が欲しいという場合は、公式のイメージはないので(誰かが作った奴はあるかもしれませんが)どちらか一方のイメージをFROMで指定して、もう片方の動作環境をRUNでインストールコマンドを実行していきます。

WORKDIR

Dockerコンテナ上のカレントディレクトリを指定します。RUNやCMDでパスが通っていないコマンドを実行する前などに使います。合わせて、USERでユーザ指定することもあります。

RUN

シェルコマンドの実行を行います。Dockerfileで一番使われる命令だと思います。

FROMで指定したイメージにはないパッケージをインストールしたり、wgetやgitコマンドで必要なファイルをダウンロードしたりするのに使います。

FROMで指定したOSのコマンドに合わせます。例えばパッケージインストールコマンドは、alpineだと

RUN apk add xxxx

となります。

手拍子で、普段なれている RUN yum install xxx とか RUN apt-get install XXX とか書いてしまいがちなので注意が必要です。

CMD/ENTRYPOINT

docker run コマンドで、コンテナ生成時に実行されるコマンドを指定するのに使います。Dockerfile内で1つしか書けません。複数書いた場合は、最後の命令が実行されます。

冒頭の例のように、コンテナ生成時に hello.py を実行したい場合は、下記のように書きます。

ENTRYPOINT [“python”,”/xxx/hello.py”]

tara
tara
Dockerfileの命令の紹介は以上になります。

他にもADDやCOPY、ENV、LABELなどがありますが、ここでは省略します。

ビルド

Dockerfileができたら、いよいよビルドです。

docker build -t イメージ名 .

でビルドできます。

RUNでパッケージインストールしたりしていると時間がかかります。

が、2回目からはすぐに終わります。これはキャッシュが生成されているからです。

ただ注意が必要なのは、キャッシュが使われているということは中身が変わらないということでもあります。例えば、Dockerfile内で git clone や git pull をしている場合、キャッシュを参照するので、リポジトリが更新されても再ビルドしたコンテナには反映されません。

この場合は、下記コマンドでキャッシュを使わないでビルドする必要があります。

docker build –no-cache=true -t イメージ名 .

当然、初回のように時間がかかります(涙)

プッシュ(アップロード)

ビルドが成功したら、プッシュ(アップロード)して完了です。

その前に、とりあえずビルド済みのイメージがあるか確認します。

docker images

以下は、プッシュ先によって微妙に違います。が、やることはログインしてプッシュです。

一番、使われるであろう Docker Hub は下記のようになります。

docker login
docker push DockerHubユーザ名/イメージ名:タグ

AWS ECR は、AWSコンソールのECRのページにコマンドがあります。 GCPの Container Registry は、使ったことがないのでちょっとわかりません。すみません。。。

まとめ

以上、Dockerコンテナの作り方についての紹介でした。参考になれば幸いです。

まとめ
  • Dockerコンテナを作るのは、複雑な動作環境ごと配布するため
  • 配布の際はDockerfileを作る
  • DockerfileのFROMは公式イメージを使う
  • ビルド時はキャッシュに注意
ABOUT ME
tara
tara
年収360万円でIT業界のキャリアスタート
SES -> Web業界 -> 大手メーカー -> フリーランス
と経験してきて、現在は年収1000万円を越えました。

エンジニアのキャリアアップに役立つ情報を発信していきます。