iPhone/iPad実機からMacのdockerコンテナ環境にリクエストする
iOSアプリを開発するにあたって、APIを受けるサーバ側の開発環境を用意することにした。 Vagrantでもいいのだけど、Dockerにも触っておきたくて入れてみた時の備忘録的なアレです。 正直ネットワーク周りはあまり深く知らないので、もっとうまくやる方法がきっとあると思います。
まずはMacにdockerをインストール
dockerはLinuxカーネル機能を使っているため直接Macで使えないので、
dockerのdaemonを動かす専用の軽量VMとその管理ツール(boot2docker
)が用意されています。
Macから動かすには、このboot2docker
を通じて動かします。
ざっくりこんなイメージ。
Mac <==> VirtualBox(VM) <==> Docker container
boot2dockerの導入
まずMacにVirtualBoxを入れます。 Downloads – Oracle VM VirtualBox
次にこちらを参考にhomebrewからdockerとboot2dockerをインストールします。 qiita.com
初期化
- VMを作成。初回の1度のみ。
mac$ boot2docker init
VM起動
mac$ boot2docker up
環境変数の確認
VMが起動するたびに、VMの$DOCKER_HOSTが変動したりするので以下のコマンド結果を実行します。
mac$ boot2docker shellinit Writing /Users/edy/.boot2docker/certs/boot2docker-vm/ca.pem Writing /Users/edy/.boot2docker/certs/boot2docker-vm/cert.pem Writing /Users/edy/.boot2docker/certs/boot2docker-vm/key.pem export DOCKER_CERT_PATH=/Users/edy/.boot2docker/certs/boot2docker-vm export DOCKER_TLS_VERIFY=1 export DOCKER_HOST=tcp://192.168.59.103:2376
毎回手動で行うのも面倒なのでshellの*rcなどに書いておきます。
# to connect docker server if [ "`boot2docker status`" = "running" ]; then eval $(boot2docker shellinit 2>/dev/null) fi
状態の確認
mac$ boot2docker status running
ここまででとりあえずboot2docker
の導入は終わり。
dockerを使う
使えるイメージを確認する。最初は空。
mac$ docker images
imageの用意
dockerコンテナの元にする、使いたいimageを落とす (debian:wheezyの例)
$ docker pull debian:wheezy
search
サブコマンドでdocker hubから探せる
(例はdebian)
mac$ docker search debian
起動してみる
debian/wheezyから起動してみる。
-i
はinteractive
-t
はttyの割り当て
--name
はコンテナ名の割り当て
mac$ docker run -i -t --name www debian:wheezy /bin/bash
ポートを紐付けたい場合は-p
。
例はホスト側8080をゲスト側80番にフォワードしてる状態。
mac$ docker run -i -t -p 8080:80 --name www debian:wheezy /bin/bash
起動するとシェルに入る
root@cbc18d9ebc9c:/#
-d
でデタッチする
mac$ docker run -d -p 80:8080 --name www debian:wheezy /bin/bash
シェルに入りたいとき
mac$ docker exec -it www bash
状態確認
コンテナの存在確認はps
サブコマンドを使う。
停止されているコンテナも含めるときは-a
オプションを指定する。
mac$ docker ps -a #=> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES #=> cbc18d9ebc9c debian:wheezy "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago www
イメージづくり
Dockerfileを作る
できればここで頑張りすぎず、他のオーケストレーションツール(ansibleとかchefとか)に任せたほうが幸せな気がします。 下記では最新版のnginxを取ってくるためdotdebの設定を追加しています。
mac$ mkdir nginx mac$ cd nginx mac$ wget http://www.dotdeb.org/dotdeb.gpg mac$ vi Dockerfile FROM debian:wheezy MAINTAINER edy <xxxxxxxxxxx@gmail.com> RUN echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list RUN echo "deb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list.d/dotdeb.list RUN echo "deb http://mirrors.teraren.com/dotdeb/ stable all" > /etc/apt/sources.list.d/jp-mirror.list RUN echo "deb-src http://mirrors.teraren.com/dotdeb/ stable all" >> /etc/apt/sources.list.d/jp-mirror.list RUN echo "deb http://mirrors.teraren.com/dotdeb/ wheezy-php56 all" > /etc/apt/sources.list.d/php56.list RUN echo "deb-src http://mirrors.teraren.com/dotdeb/ wheezy-php56 all" >> /etc/apt/sources.list.d/php56.list ADD dotdeb.gpg /tmp/ WORKDIR /tmp RUN apt-key add dotdeb.gpg && \ apt-get update && \ apt-get upgrade -y && \ apt-get install -y nginx && \ apt-get clean && \ rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
こまかい記法はここを参考にしました。 www.atmarkit.co.jp
イメージをbuildする
mac$ docker build -t siny/debian:1.0 .
出来上がったら、イメージを指定して先ほどと同じようにrunします。
mac$ docker run -d -p 8080:80 --name www siny/debian:1.0
ポートフォワード設定
現状のネットワーク
ここまでの設定と状態を整理します。
LAN上のMacのIPは192.168.11.2
となっている状態で、こんな感じになります。
mac$ ifconfig ...略 vboxnet1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 ether XX:XX:XX:XX:XX:XX inet 192.168.59.3 netmask 0xffffff00 broadcast 192.168.59.255 mac$ boot2docker ip 192.168.59.103
iPhone [192.168.11.3] || ルータ [192.168.11.1] || [192.168.11.2] Mac [192.168.59.3] || [192.168.59.103] VirtualBox
まずMacのローカルポートをVMへフォワード
この状態でnginxにアクセスするには、Mac上からは192.168.59.103:8080
でアクセスしなくてはいけません。
なので、まずlocalhostのポートをVMのポートへforwardします。
mac$ VBoxManage controlvm "boot2docker-vm" natpf1 "nginx,tcp,127.0.0.1,8080,,80"
これでlocalhost(Mac)の8080番がboot2docker(VM)の80へforwardされるようになり、
127.0.0.1:8080
またはlocalhost:8080
でアクセスできるようになります。
iPhone [192.168.11.3] || ルータ [192.168.11.1] || [192.168.11.2] Mac [192.168.59.3] localhost:8080 || || [192.168.59.103] 192.168.59.103:8080 VirtualBox
MacのLAN側からもフォワード
そしてようやく本題の実機からのアクセスを行うため、Macのいずれかのportを更にフォワードさせます。 色々やりかたはあると思いますが、今回はMacにnginxを入れて、8080ポートをListenしてlocalhost:8080へforwardさせることにしました。
Macにnginxを入れる
==> Downloading https://homebrew.bintray.com/bottles/nginx-1.6.2.yosemite.bottle.1.tar.gz ######################################################################## 100.0% ==> Pouring nginx-1.6.2.yosemite.bottle.1.tar.gz ==> Caveats Docroot is: /usr/local/var/www The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that nginx can run without sudo. To have launchd start nginx at login: ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents Then to load nginx now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist Or, if you don't want/need launchctl, you can just run: nginx WARNING: launchctl will fail when run under tmux. ==> Summary 🍺 /usr/local/Cellar/nginx/1.6.2: 7 files, 920K
configファイル確認
mac$ nginx -t nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
リバースプロキシとしてlocalhostの8080番へフォワード
// 略 location / { proxy_pass http://127.0.0.1:8080; } }
最終的にはこんな感じ。
iPhone [192.168.11.3] || ルータ [192.168.11.1] || [192.168.11.2] 192.168.11.2:8080 <----- nginx listen Mac || <------ nginx forward [192.168.59.3] 127.0.0.1:8080 || || <------ virtualbox forward [192.168.59.103] 192.168.59.103:8080 VirtualBox
これで、iPhone実機から192.168.11.2:8080
にアクセスすると見えるようになりました。
試した時はDHCPなので、安定稼働させるにはIPを固定化するとか、内部DNS立てるかすればよいと思います。