Code for final

ふぁいなる向けのコード置き場です。すでにコードじゃないこともいっぱい。

Windows10にDocker Desktop for WindowsをいれてLinuxコンテナで動かす手順(実践編)

Dockerの導入について以下の記事で書きましたが、ただwebサーバーを立てただけで、コンテンツを更新したりする手順とかわからなく、 このままだと実務で使うときに苦労すると思ったので実務を想定して必要そうな知識をまとめたいと思います。
ここでいう実務は開発、テストを想定しています。本番で運用するためにはもっといろいろと知識が必要ですのでご注意を。

final.hateblo.jp

コンテンツを適用する方法は2つある

基本編ではwebサーバーを立てて"It Works!"が出て満足していましたが、実務ではコンテンツをサーバに配置する必要があります。
Dockerではその手順として2つあります。

  • コンテナ内のファイルを差し替える
  • ホストのフォルダをコンテナ内のフォルダとリンクする

後者だけ覚えておけばなんとかなりそうな気もしますが、テストとかだとコンテンツを配るのが面倒なときとかに使えそうな気はしますので両方説明します。

コンテナ内のファイルを差し替える

試しにapache webサーバーのindex.htmlを書き換えてみます。

まずコンテナ同士が別々に動作していることがわかるようにもう一個apacheのサーバを立てます。 名前とポートを変えれば何個でも作成可能です。

> docker run -d -p 8080:80 --name httpd2 httpd

"localhost:8080"でアクセスしたら"It works!"と表示されると思います。

ではこのhttpd2の方のLinux環境に入るには"docker exec"コマンドをたたいてください。 httpd2のところは入りたいコンテナ名を指定するだけであとはおまじないみたいなものです。

>docker exec -it httpd2 bash

すると以下のようになると思います。(@の右はコンテナIDでコンテナ作成時にランダムで生成されるので環境によって異なります)
sshでつないだときと同様にLinuxコマンドが実行できます。

root@4d11a0179bc4:/usr/local/apache2#

なのでapacheのindex.htmlファイルはhtdocsの下にあるので以下のコマンドで確認できます。

root@4d11a0179bc4:/usr/local/apache2# cd htdocs
root@4d11a0179bc4:/usr/local/apache2/htdocs# ls
index.html
root@4d11a0179bc4:/usr/local/apache2/htdocs# cat index.html
<html><body><h1>It works! </h1></body></html>

これを書き換えればいいのですが、viとかvimとか入っていないので、Windows環境から転送するしかないです。
Windows環境に戻るために"exit"をたたきます。そうするとWindowsに戻ります。

以下のコマンドを実行してワークディレクトリを作っておきます。

>cd c:\
>mkdir docker_work
>cd docker_work

まずは書き換えるためにコンテナ(Linux)内からWindowsにindex.htmlを持ってきます。 以下のコマンドを叩いて取得します。 "4d11a0179bc4"は各自のものに変えてください。先程のdocker execのとこからコピーすると確実かと思います。

>docker cp 4d11a0179bc4:/usr/local/apache2/htdocs .\htdocs

"docker cp"コマンドでホスト(Windows)とコンテナ(Linux)間のファイルやり取りができます。
cpコマンド同様、コピー元 コピー先で指定します。 コピー元のコンテナは"コンテナid:Linuxファイルパス"で指定します。
注意すべきところはコンテナ側のパスを指定するときはコンテナ名(httpd2)ではなく、コンテナIDを指定します。 コンテナIDは"docker exec"で接続するか"docker ps"で確認できます。

これで"c:\docker_work"にhtdocsフォルダができ、index.htmlが取得されたと思います。
index.htmlを自由に編集してください。

編集が終わったら次は以下のコマンドでコンテナ側にコピーします。
さっきと逆でコピー先がコンテナになります。

>docker cp .\htdocs 4d11a0179bc4:/usr/local/apache2

これで"localhost:8080"にアクセスすると表示される内容が変わったと思います。
"localhost"にアクセスしても"It works!"のままだと思います。
これでコンテナが別々の環境で動作していることがわかったと思います。 "localhost"を変えたい場合はhttpdのコンテナを同様に書き換えてみてください。

コンテナの状態をイメージとして保存する

コンテナをイメージとして保存することでいつでも"docker run"コマンドでコンテナを生成することができるようになります。
さきほどの"localhost:8080"の環境をイメージとして保存したいと思います。

httpd2の環境を保存するために以下の"docker commit"コマンドで状態を保存します。

>docker commit httpd2 httpdex:1.0

このコマンドの意味はhttpd2環境をhttpdexというイメージ名のタグ1.0で保存するという意味です。
以下のコマンドを実行して3台目のサーバを立てます。イメージにはいまほど作成した"httpdex:1.0"を指定します。

>docker run -d -p 8088:80 --name httpd3 httpdex:1.0

これで"localhost:8088"にアクセスするとhttpd2のコンテナ("localhost:8080")と同じ内容が表示されると思います。
これで"localhost:8080"の内容がイメージとして保存されてたということが確認できました。

ホストのフォルダをコンテナ内のフォルダとリンクする

さきほどのでコンテナ内のファイルを書き換えることができたと思いますが、これだと更新する度に書き換える必要があって、開発中は現実的ではないと思います。
コンテナ(Linux)がホスト(Windows)のフォルダを参照してくれるように設定することができます。

次に以下のコマンドを実行してさきほど保存したイメージ"httpdex:1.0"をベースに4台目のサーバを立てます。 ※実行時に共有フォルダに追加するかと聞かれると思いますが、”Share it”を選択してください。(キャンセルすると失敗します)

>docker run -v c:\docker_work\htdocs:/usr/local/apache2/htdocs  -d -p 8888:80 --name httpd4 httpdex:1.0

"localhost:8888"でアクセスするとhttpd3と同じ結果になると思いますが、ここで"c:\docker_work\htdocs"にあるindex.htmlを編集してください。
再度アクセスすると変更した内容が反映されていると思います。ほかのサーバーは変更されてないのも確認できると思います。
このように"docker run"実行時に"-v ホストのフォルダ(Windows):コンテナのパス(Linux)"を指定することでリンクできます。
ちなみに-vを複数個指定することもできるみたいです。

これで開発に耐えうる環境が構築できますね。

カスタマイズしたコンテナイメージを配布する

上記でカスタマイズしたコンテナイメージをほかの人にテストしてもらう場合、渡す必要があります。
その場合はファイルとして出力できます。

まず以下のコマンドを実行してコンテナイメージを確認しましょう。

>docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpdex             1.0                 379506f88e8f        21 hours ago        166MB
httpd               latest              b2c2ab6dcf2e        11 days ago         166MB

保存したイメージをファイルに出力するには"docker save"コマンドを実行します。 以下のコマンドで"httpdex:1.0"のイメージを出力します。

>docker save -o httpdex-1.0.tar httpdex:1.0

"httpdex-1.0.tar"が出力されますのでこのファイルをほかの人に渡して"docker load"コマンドを実行してイメージファイルを取り込んでもらいます。

>docker load -i httpdex-1.0.tar

あとはdocker runコマンドでイメージ名"httpdex:1.0"を指定してもらえばほかの人の端末にも同じ環境が構築されます。

複数のコンテナを連携したサービスを構築する

以下にまとめました。

final.hateblo.jp

最後に

ここに書いたのは基本的なことなので詳細は必要に応じて調べてみてください。
でわ、素敵なDockerライフを。