この記事では、Dockerfileを使って、Dockerイメージからコンテナを起動する手順について解説します。
具体的には、以下のようなことを学べます。
- docker build -> docker runまでの流れ
- Dockerfileの書き方・設定内容
- Dockerfileを使ってイメージを作成する
簡単なサンプルは動かせたけど、少し複雑なことをしようとすると、手が止まってしまう。。という人に役に立てばうれしいです。
DockerまたはDocker toolboxがインストールされていることが前提ですので、まだの人は下の記事とかを参考に、Dockerをインストールしてください。
Docker Toolbox on Windowsのインストール手順と環境の構築簡単なDockerイメージをビルドしてみる
まず、全体像が分かった方が良いと思うので、さっそくDockerイメージをビルドしてみたいと思います。まず、適当なディレクトリを作成して、そこでビルドをしていきましょう。
例として、「c:\docker\sample001」で作業することにします。
ここに、「Dockerfile」という名前のファイルを作ります。名前はなんでもいいんですが、dockerコマンドは、デフォルトでこの名前を使うので。
中は以下のように記載します。
FROM ubuntu:latest
MAINTAINER pa-kun
RUN apt-get update && apt-get install -y apache2
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Dockerfileが用意出来たら、Dockerのコマンドプロンプトで、作業ディレクトリ(c:\docker\sample001)に移動し、
docker image build -t イメージ名[:タグ名] Dockerfileの配置ディレクトリ
を入力します。
Dockerfileの配置ディレクトリは、カレントディレクトリですので、例えば、
docker image build -t sample001:1.0 .
のように入力します。
ビルドを実行すると、ベースイメージのダウンロードや、RUNやCOPYの実行がステップごとに行われていることが分かります。
イメージができたかどうかはdocker image ls
コマンドで確認できます。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
sample001 1.0 f3ad3edd1505 45 hours ago 188MB
ここまで出来れば、Dockerイメージが出来上がっています。
では、docker run
コマンドで、このイメージからコンテナを起動してみます。
docker run --name <起動するコンテナ名> -d <元にするイメージ名>
という構文になります。「-d」はバックグラウンドで動かすという意味です。
以下の例はdocker run --name con_sample001 -d sample001:1.0
としました。
$ docker run --name con_sample001 -d sample001:1.0
cf2831d9c4aac720a5fcf2933ee1f28484eaf4af5e08e2b9a3ba241c01faf2dc
コンテナの起動に成功すると、「cf2831d9c4aac720a5fcf2933ee1f28484eaf4af5e08e2b9a3ba241c01faf2dc」といった文字列が表示されますが、これは、コンテナIDです。
無事起動できたかは、docker ps
コマンドで確認できます。これは、現在動いているコンテナを表示するコマンドです。
以下のように、コンテナが一つ、動いていることが分かります。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf2831d9c4aa sample001:1.0 "/usr/sbin/apache2ct…" 6 seconds ago Up 6 seconds 80/tcp con_sample001
さて、ここまでで、Dockerfileからイメージの作成、コンテナの起動まで出来ました。
ひと通りの流れが分かったところで、Dockerfileの中身について、詳しく見てみることにしましょう。
なお、起動はしたけど、なぜかつながらない。。という人は、以下の記事を参考に、どこがおかしいかを探ってみてください。
Dockerコンテナで起動したサーバにアクセスできないときの確認と対処方法Dockerfileの書き方・設定内容
dockerでは、Dockerfileにコマンドを書いていき、docker build
の引数として渡すことで、イメージをbuildしていきます。
DockerfileにはDoker独自のDSL(ドメイン固有言語)を使って、イメージの構成を定義していきます。
以下は、シンプルなDockerfileです。
FROM
でリポジトリからイメージを取得し、RUN
でイメージに対してモジュールのアップデートとapacheのインストールを行っています。
EXPOSE
はdockerから外のネットワークに対してポートを開放し、最後にCMD
を実行することで、コンテナをlive状態に維持しています。
FROMやRUNは「インストラクション(命令)」と呼ばれています。
様々なインストラクションが使えますが、まずは基本的なものを紹介します。
Dockerfileに記述できるインストラクション
詳しくは公式のDockerfileリファレンスを参照しても良いですが、以下で簡単に説明します。
FROM
は、作成するDockerイメージのベースになるイメージを指定します。
Dockerfileでイメージをビルドする場合には、最初にFROMで指定されたイメージをダウンロードしてから実行されるため、最初の行に記述されます。
FROMで指定するイメージはDockerHubというレジストリで公開されています。Dockerはデフォルトの取得先として、このDockerHubのレジストリを参照します。
「FROM ubuntu:latest」のように、
FROM <イメージ名>:<タグ名>
または
FROM <イメージ名>
で指定します。
RUN
は、Dockerイメージをビルドする際に、Dockerコンテナ内で実行するコマンドをそのまま記述できます。
上記の例のようにRUN apt-get update apt-get install -y apache2
と記述すると、イメージが取得された後、コンテナ内で「apt-get update && apt-get install -y apache2」が実行されるということです。
COPY
はDockerを動かしているホストPC上にあるファイルやディレクトリをDockerイメージ内にコピーします。
例えば、COPY html /var/www/html/
のように記述すると、dockerホストから、イメージ内のファイルシステムにコピーします。
COPYと似たインストラクションにADDというのがあります。後ほど解説します。
ADD
もCOPYと似たインストラクションで、ファイルやディレクトリをDockerイメージ内にコピー&配置します。
COPYとの違いは、ADDは、配置したときに、tarやgzなどの圧縮ファイルも解凍して配置してくれることと、dockerホスト上にないリモートのファイルも配置可能だということです。
つまり、ADD something.gz /tmp
としたら、/tmpに解凍して配置してくれます。
CMD
インストラクションは、RUNと似ていて、コンテナ内で任意のコマンドを実行することができます。
CMD ["echo", "Dockerfile CMD demo"]
のように記述すると、echoコマンドを実行することができます。
重要なのはその実行タイミング。
RUNは、イメージのビルド時に実行、コミットされますが、CMDはイメージからコンテナが実行されたときに一度だけ実行されます。また、実行できるのは1つのCMDだけで、Dockerfile中に何度記載しても、最後の1つのCMD以外は無視されます。
RUNでアプリケーションの更新や配置を行い、CMDでアプリケーションそのものを実行させると考えるとわかりやすいと思います。
ENTRYPOINT
インストラクションもCMDと同様、コンテナ実行時に一回だけ実行されます。
ENTRYPOINT ["echo", "Dockerfile ENTRYPOINT demo"]
のように記述することができます。
CMDとの主な違いは、CMDが、docker runの引数で実行コマンドを上書きできるのに対して、ENTRYPOINTは上書きされません。
そのため、ENTRYPOINTの方は、起動後も動き続けるタイプのコンテナに利用されることが多いです。