MSのIDEであるVisualStudioではPythonやNode.js開発を可能にするツール類もリリースされており、VisualStudioをコーディングに使うことを考える。VisualStudioでコーディングをしてそのWebアプリを仮想マシンのLinuxで走らせてデバッグを行いたい。それがそれほどの手間にならずに行えたらコーディングにVisualStudioを使うのを一つの選択肢に入れようかという気になってくる。そこでDockerを使う。ASP.NETもLinux対応が始まっている。ASP.NETといえば開発はVisualStudioを使うのが標準だろうから、Linuxサーバで動かすASP.NETアプリをWindows上のVisualStudioで開発という話はやっぱり出てくるだろう。
Linuxサーバで動かすWebアプリをWindows上で書いてしまう。こんなことをする一定の価値はあるはず。
Windows上で書いたWebアプリをコンテナとして用意したLinuxサーバで簡単にデバッグできるかやってみる。DockerでWebアプリを動かすというのは前にもやっているが、イマイチ手順が整理できてなかったので改めて。
まずはWebアプリの用意から。簡単なサンプルをPythonで用意。"/"にアクセスすると"Hello."を返すだけのもので、Gunicorn + nginxで動かす。これhello.pyとしてプロジェクトのディレクトリ内に配置。
import os
import tornado.web
import tornado.wsgi
class HelloHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello.")
settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
}
application = tornado.web.Application([
("/", HelloHandler),
], **settings)
wsgi_app = tornado.wsgi.WSGIAdapter(application)
あとnginx設定ファイルとしてhello.confというファイルも作って同様に配置しておく。
server {
listen 80 default;
server_name example.org;
access_log /var/log/nginx/example.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
適当過ぎるWebアプリが用意できたので、WindowsにBoot2Dockerを入れてコマンドラインを立ち上げる。ここからはDockerの操作。
Dockerを使うにあたってイメージとコンテナという二つの概念がある。イメージがクラスでコンテナがインスタンスと考えられるかもしれない。OSイメージからコンテナをつくる、実際に環境として動くのが作られたコンテナの方。
Boot2Dockerで立ち上げたコマンドラインにDockerコマンドを入れていく。
docker pull ubuntu:latest
ubuntuイメージを用意。今回はサーバとしてubuntuを使うことにしておく。
docker run -it --name [new container name] ubuntu bash
ubuntuイメージを利用してコンテナを作成、同時に作成したコンテナでbashをとりあえず実行。
(作成したコンテナ内)
apt-get update;apt-get install -y nginx;rm /etc/nginx/sites-enabled/default;apt-get install -y python3-pip;pip3 install gunicorn;pip3 install tornado;
Webアプリサーバにするのに必要なソフトやライブラリをコンテナ内で用意。
ctrl + dでコンテナから抜ける
docker commit [container name] [new image name]
前までで使いまわしたい構成がコンテナとして用意できた。さらにその前でイメージからコンテナを作成したことからわかるように、コンテナのままでは同じ構成、状態を使いまわせず、コンテナを一旦イメージとしてコミットしておく必要がある。コミットが終了したらそのコンテナは用済み。
cd /c/Users/john/hello
hello.pyを保存してあるディレクトリへ移動(WindowsのパスをUNIX風に書き換えるc:\→/c/)。そこにコンテナ内で実行したいコマンドを列記したDockerfileを用意しておく。コマンドとしてはWebアプリを立ち上げるもの。Dockerfileの中身はあとに載せておく。
******
docker build -t [new image name] ./
Dockerfileをもとに新しいイメージをビルド。ここでWindowsで作っておいたプロジェクトのファイルをもろもろ、さっき必要なソフトをインストールしたコンテナから作成したイメージ内にコピーしたりソフトの設定したり。
docker run -d -p 80:80 --name [container name] [image name]
イメージからコンテナを用意して走らせる。
docker exec [container name] nginx
nginxをコンテナ内で走らせる。
Windowsのブラウザでhttp://192.168.59.103へアクセス。"Hello."が返ってくることを確認する。

******
Webアプリの立ち上げを含めたコンテナの用意ができているので、これを手軽に反復できるようにする。******~******内で使用しているdockerコマンドをshファイルにまとめる。ここではhello.shという名前にしておく。コンテナは作成時に指定の名前のものがすでに存在する場合は作成が実行されない。それを回避するためにすでに存在するコンテナを削除するためのコマンドも追加しておく。
cd /c/Users/foo/py_web
docker stop [container name]
docker rm [container name]
docker build -t [new image name] ./
docker run -d -p 80:80 --name [new container name] [image name]
docker exec b2 nginx
hello.pyをちょっと書き換えてみる。返す文字列を"Hello."から"Hello, again."へ。
Webアプリの書き換えを行ったので"sh hello.sh"を実行してLinuxサーバを再度立ち上げなおし、ブラウザでまたhttp://192.168.59.103へアクセスして返ってくる文字列をチェックする。おおよそ10秒ほどでコンテナが立ち上がり、アドレスへのアクセスが可能になった。

このhello.shをDocker上で実行、終了後のお掃除をするためのコマンドを書いたバッチファイルを用意するのもいいかもしれない。
@echo off
boot2docker ssh sh [project directory]/hello.sh
echo Server is running. http://192.168.59.103/
echo Press any key to stop server.
pause > NUL
echo Removing container...
boot2docker ssh docker stop [container name]
boot2docker ssh docker rm [container name]
pause
Dockerを使うことでWindowsから手軽にLinuxサーバのWebアプリを立ち上げることができた。今回の使い方においてはGUIありの仮想マシーンを使うよりだいぶテンポよくWindows上でLinuxサーバのWebアプリを立ち上げられそうであり、デバッグに使えそうである。
今回のDockerfileの中身
******
FROM [image name]
ADD . /usr/
WORKDIR /usr/
EXPOSE 80
RUN cp hello.conf /etc/nginx/conf.d/
RUN /etc/init.d/nginx reload
CMD gunicorn hello:wsgi_app
******
ADDは指定ファイルを指定ディレクトリへコピー
WORKDIRはワーキングディレクトリの指定(cdコマンドでは行わない)
EXPOSEで待ち受けポートの指定
あとはコマンド実行である