Docker Toolbox環境でハマってから解決するまでの話


Windows 10 HomeでDocker Composeを始める

はじめに

この記事はWin10 Proユーザである私が、Win10 HomeでDocker Composeを使うにあたってハマったこと解決方法をご紹介する記事です。
Docker Toolboxを使い始めた人のお役に立てると幸いです。

やりたいこと

  • Win10 HomeでPHPのフレームワークLaravelを使ってWebサーバを動かす。
  • Dockerのオーケストレーションはdocker-composeを利用する。
  • docker-composeはLaravel向け全部入りプロジェクトであるLaradockを利用する。
  • ホストマシンの外からLaradockのサービスへアクセスする。

前提条件

  • Virtual Boxがインストールしている
  • Docker Toolboxがインストールしている
  • docker run hello-worldが動作することを確認している
  • Laradockのセットアップが終わっており、workspaceコンテナにexecできる(参考記事: @souichirou 殿のdockerコンテナの中に入って作業をしたい時)

いざ実践

作業手順

以下の手順で作業を行います。
なお手順末尾に「」があるものは私のハマりポイントです。

  1. composerコマンドの参照先リポジトリを近くに変更し、快適な環境を準備する(任意)
  2. composerの依存解決を並列化し、快適な環境を準備する(任意)
  3. Laravelのインストール
  4. LaravelのWEB画面を開発マシンで表示する
  5. LaravelのWEB画面を開発マシンの外から表示する

1. composerコマンドの参照先リポジトリを近くに変更し、快適な環境を準備する(任意)

PHPのパッケージ管理機能を提供してくれるcomposerですが、デフォルトのリポジトリがpackagist.orgまで距離があるため、日本国内からのアクセスが早いpackagist.jpに変更します。
※Packagist JPについてはこちらから

workspaceコンテナ内での操作
root@(container-id)# composer config -g repos.packagist composer https://packagist.jp

2. composerの依存解決を並列化し、快適な環境を準備する(任意)

composerはパッケージリポジトリへのアクセスが並列化されておらず、Laravelのように依存関係が多いフレームワークのインストールではかなりの時間がかかる傾向がある。
@Hiraku殿のprestissimoを導入し、依存解決を並列化します。

workspaceコンテナ内での操作
root@(container-id)# composer global require hirak/prestissimo

3. Laravelのインストール

Laravelのインストールを以下のコマンドで実行します。

workspaceコンテナ内での操作
root@(container-id)# cd /var/www
root@(container-id)# composer create-project --prefer-dist laravel/laravel ./

cd /var/wwwする理由はLaradockのデフォルトのWEBサーバであるnginxでは、/var/wwwLaravelが配置されている前提となっているため。

4. LaravelのWEB画面を開発マシンで表示する

まず私がハマったポイントは、まさかの画面を表示する時でした。

手順3を行うことでLaravelのセットアップが完了し、LinuxやWin10 Pro上でDockerを使っている場合はhttp://localhostで以下のようなLaravelの初期画面が表示されるはずです。

しかし、Win10 Home + Docker Toolboxでは一筋縄ではいきません。

本手順におけるハマりポイント
Win10 Home + Docker Toolboxを使う場合は、Docker上のサービスはlocalhostとして動作しません。(VirtualBox上のVMで動いているため)
私はWin10 ProとLinuxでしかDockerを触っていなかったためここでハマりました。

解決方法
Docker Toolboxを利用する際は、Docker Quickstart Terminalというアプリをインストールしているはずです。
このアプリを起動した直後に表示される以下の画面をご覧ください。

表示する際に必要となるVirtualBox内のdefaultマシンのIPアドレスが記載されています。
(ここでは192.168.99.100
このIPアドレスを指定してWEBブラウザでアクセスすることで表示できます。
WEBブラウザに以下のURLを指定してアクセスしてみましょう。

http://(Docker Quickstart Terminalに記載されているIPアドレス)

私の場合(192.168.99.100)は以下の通りです。

http://192.168.99.100

このように指定することでWin10 Home + Docker Toolboxの組み合わせでLaravelの初期画面が表示されます。

5. LaravelのWEB画面を開発マシンの外から表示する

次に私がハマったポイントは、開発マシン以外からDocker Toolboxで動いているサービスにアクセスする時でした。

仮に開発マシンのIPアドレスが192.168.0.1であるとしましょう。
LinuxやWin10 Pro上でDockerを使っている場合は開発マシン以外からは以下のURLでサービスが見えるはずです。

http://192.168.0.1

しかし、Win10 Home + Docker Toolboxでは一筋縄ではいきません。(2回目)

Docker ToolboxでDockerコンテナを動かす際は、VirtualBox上で動作しているdefaultマシン内でDockerを立ち上げており、このdefaultマシンに設定されているNICはNATホストオンリーアダプタの2つだけです。
仮にdefaultマシンにブリッジアダプタを割り当てる場合、defaultマシンに独自のIPアドレスが振ることでアクセスできそうな気がします。

しかし以下の利用により、NICに変更を加えることを避けることにしました。

  • ブリッジ接続によってdefaultマシンにIPを振りたくない(ローカルIPアドレスがもったいない)
  • 「DockerといえばホストマシンのIPで動くものだ!」というイメージがあるため
  • defaultマシンに変更を加えたくない(人の作ったVMを修正したくない)
  • 開発マシンの外側(他人)に対して、Docker Toolboxの存在を意識させたくないため

解決方法

「開発マシンへの通信をポートフォワードでdefaultマシンに流し込む」

つまり以下のイメージです。

Win10 HomeのDocker Toolboxに含まれているdocker-machineコマンドを利用して実現します。

Docker Quickstart Terminalアプリを立ち上げて、以下のコマンドを実行してください。

DockerQuickTerminalアプリでの操作
docker-machine ssh default -g -L 8080:192.168.99.100:80

このコマンドを実行することでdefaultマシンにSSHポートフォワードをします。

-gオプション

ローカル以外のマシンから来た通信に対してもポートフォワードしてくれます。

-Lオプション

ポートフォワードの設定です。
ホストマシンのポート8080番に来た通信を、defaultマシンのポート80番へ転送することが可能となります。
上記の操作例では-L 8080:192.168.99.100:80と指定しておりますが、これはコロン:区切りで以下のように指定します。

-L (ホストマシン側の紐づけるポート番号):(転送先マシンのIPアドレス):(転送先マシンのポート番号)

これにより、ホスト以外のマシンから(ホストマシンのIP):8080を宛先として指定することで、defaultマシンへ通信が到達するようになります。

ホストマシンの外(別のPC等)のWEBブラウザで以下のURLを指定することで表示できるようになりました。

ホストマシンの外(別のPC等)からWEBブラウザで確認

http://(ホストマシンのIPアドレス):8080

以上、めでたしめでたし。

余談1

手順1と手順2については、コンテナを再度立ち上げしたら消えてしまうので、workspaceのDockerfile後半に下記の通り追加することをお勧めします。

workspace/Dockerfile
###########################################################################
# Check PHP version:
###########################################################################

RUN set -xe; php -v | head -n 1 | grep -q "PHP ${LARADOCK_PHP_VERSION}."

###
# 追加設定 ここから
###

# composerのpackagistを近くに変更
RUN composer config -g repos.packagist composer https://packagist.jp

# composerコマンド並列化
RUN composer global require hirak/prestissimo

###
# 追加設定 ここまで
###

#
#--------------------------------------------------------------------------
# Final Touch
#--------------------------------------------------------------------------
#

余談2

手順5でポートフォワードですが、-fオプションをつけることでバックグラウンドでフォワードしてくれるようになります。