前回はDockerを操作できるようにする準備を整えるところまで行いました。
今回からは、Dockerのイメージの作成とコンテナの実行をやってみたいと思います。
目次
最終的な構成
目指す開発環境は、以下のコンテナを協調して動かせるようにする予定です。
- Webサーバのコンテナ
- アプリケーションサーバのコンテナ
- データベースサーバのコンテナ
今回はまずWebサーバのコンテナを動かしてみたいと思います。
Githubリポジトリ
関連するファイルはGithubにおいています(d-abe/dockers)。
必要ならcloneしてお使いください。
nginxのDockerイメージをつくる
nginxはオフィシャルのイメージもあるので、docker pull nginxとすればすぐ使えます。
が、今回は勉強がてらDockerfileを作ってイメージをビルドしてみたいと思います。
以下のようなDockerfileにしました。
FROM ubuntu:14.04 MAINTAINER d-abe <abe@flup.jp> RUN apt-get update && \ apt-get install -y -q nginx && \ rm -Rf /etc/nginx/sites-enabled/default && \ rm -rf /var/lib/apt/lists/* VOLUME ["/etc/nginx","/var/log/nginx"] EXPOSE 443 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
以下、少し中身を見ていきます。
FROM命令
DockerfileはまずFROM命令から始まらなければなりません。今回は、ubuntu:14.04にしました。
これはイメージがなければ自動的に公式リポジトリからダウンロードしてきて使います。
MAINTAINER命令
イメージの作成者情報を記入します。
RUN命令
続くコマンドを実行します。
RUNを一回実行するごとにCOMMITが走ってイメージが肥大化していくので、分ける必要性がない場合は上記のように1つの文としてまとめた方が良いようです。
VOLUME命令
Dockerコンテナ内の指定したパスをマウントできるようにする命令です。
これにより、ファイルの永続化を行ったりホストや他のコンテナから参照させたりすることができます。
EXPOSE命令
Dockerコンテナの指定したポートを開き他から参照できるようにします。
CMD命令
Dockerをrunした際に実行させるコマンドです。
ビルドしてイメージを作成!
では早速、ビルドしてみたいと思います。
カレントディレクトリにDockerfileのみ存在している状態でビルドコマンドを実行します(他のファイルなどがあるとdockerのホストに転送されるので無駄に時間がかかります!)。
$ docker build -t test/nginx ./ Sending build context to Docker daemon 2.048 kB Step 1 : FROM ubuntu:14.04 14.04: Pulling from library/ubuntu : Successfully built 994fadfe9aec $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE test/nginx latest 994fadfe9aec 43 seconds ago 206.1 MB ubuntu 14.04 3876b81b5a81 3 weeks ago 187.9 MB
無事、test/nginx というイメージが作成されました。
設定や表示コンテンツは?
Dockerfileを見て気付いた人もいるかもしれませんが、このままだとnginxの設定(ドキュメントルートとか)が行われていませんし実際に表示させるコンテンツはどのように配置したらいいのかが分からない状態だと思います。
ubuntuのapt-getでnginxを入れていますので、サイト設定は /etc/nginx/sites-enabled/ 内においてあるファイルが読み込まれます。そこで、実行時にここへ設定ファイルを置くことにします。
表示コンテンツについては設定ファイル内で /var/www とかにドキュメントルートを設定し、そのディレクトリをマウントして参照させます。
設定ファイル
設定ファイルは以下の内容を使います。今回はもっとも単純に静的なデータのみを配信させればOKとします。
server { listen 80 default_server; root /var/www; index index.html index.htm; server_name nginx; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } }
docker runとオプション
では設定ファイルや/var/wwwなどを考慮した上で docker run してみます。
まず、ファイルのツリー構造を見ておきましょう。
/Users/abe/dockers ├── conf │ └── static_nginx.conf ├── html │ └── index.html └── nginx └── Dockerfile
static_nginx.confは先ほどの設定ファイルです。
index.htmlは適当に以下のようなものを用意しました。
<html> <body> <h1>TEST!!</h1> </body> </html>
以下、コマンドは /Users/abe/dockers がカレントディレクトリだという前提なので自分の環境では読み替えてください。
$ docker run -p 8080:80 --name static_nginx -v /Users/abe/dockers/conf/static_nginx.conf:/etc/nginx/sites-enabled/default -v /Users/abe/dockers/html:/var/www -d test/nginx 017d2c013921a9057eeb30d048a6aa348dbc7f157373f379fca785a798016440
なんのこっちゃ?という感じだと思うのでオプションを見ていきましょう。
-pオプション
-pオプションはポートマッピングの設定を行います。
nginxコンテナはwebサーバを動かすので80番ポートをexposeしていますが、Macから直接このコンテナにアクセスできない(Mac=>docker machine=>コンテナとなっているため)のでdocker machineの8080番ポートにマッピングさせるようにしています。
こうすることで、Macからはdocker machineのIPをブラウザで開くことができるようになります。
--nameオプション
これはコンテナに任意の名前をつけるためのオプションです。
指定しないとdockerが自動的に名前をつけてくれます(英語の形容詞+名詞をランダムで選ぶ感じ)。
-vオプション
これはData Volumeの設定を行うオプションで、今回のように -v foo:bar と書く場合と -v hoge と書く場合とでは意味が違ってくるので注意が必要です。
-v foo:bar と書くと、ホスト(docker machine)のパスfooをコンテナのパスbarにマウントさせることができます。ここで注意が必要なのは、fooはdocker machineのパスであってMac上のパスではないということです!
しかし実際にマウントさせたいのはMac上のパスですよね?
方法はあります!(というか、ないと困る・・)
実は、docker-machineは起動した時にMac上の/Usersをdocker machine(boot2docker)の/Usersに共有フォルダとしてマウントしているのです。
なので、/Users以下のパスであればMac上のパスとして扱えることになります。
※どうしても他のパスを使いたい場合は、docker-machine ssh [マシン名]を実行してsshでログインし、手動で共有フォルダをマウントすればできると思います。
今回は、nginxの設定ファイルを/etc/nginx/sites-enabled/defaultとして認識できるようにするのと、HTMLのディレクトリを/var/wwwにマウントさせるようにしてみました。
-v hoge などとの違いについては以下の記事が参考になりました。
Docker の Data Volume まわりを整理する - Qiita
-dオプション
コンテナをバックグラウンドモードで起動します。
動作確認
ではブラウザで、開いてみよう・・・とその前に、docker machineのIPを知る必要があるので確認します。
$ docker-machine ip prl-dev 192.168.171.147
192.168.171.147ということが分かったので、ブラウザで「http://192.168.171.147:8080/」を開いてみます。
すると・・・
出ました!!
無事にコンテナを起動し、ドキュメントルートにローカルのディレクトリを指定できています。
次回は、phpをfpmで起動してnginxと連携させたいと思います。