Python
Ubuntu
Flask
docker

Docker+Flaskによるお手軽Webアプリ開発

そうだ、Webサービス作ろう!@環境構築編

Dockerについて

Dockerの仕組みそのものについては深くは触れません。私自身があまりよく理解してないですからね!

簡単に、私にとってのDockerとは、”使い捨ての仮想PCが簡単に手に入るツール”みたいな物です。

例えば「まっさらなUbuntuPCをください」と言えばまっさらなUbuntuPCが手に入る、例えば「アプリ(DBでもWebサービスでもなんでも)がセットアップ済みのPCをください」と言えば○○がセットアップ済みですぐに使える状態のPCが手に入る、といったイメージです。

今回の場合でいうと、「Python3+Flaskが入ってるPCをください」という訳ですね。

このとき、Docker公式のPC置き場(Docker Hub)を探しに行き、ちょうど良いPCを探してももちろん良いのですが、せっかくなのでまっさらなUbuntuを貰って、自分でカスタマイズ(Python3+Flaskをインストール)して使うことにしましょう。

ちなみに、ここで「こういうPCください」と言うところの”こういうPC”の部分、つまりは”カタログ上のあるPC”のことを、Docker用語ではイメージと呼び、指定した仕様に基づいて作られた”具体的なPC”のことをコンテナと呼びます。(まぁ厳密に言うと全然違いますが...イメージを掴むために)

Dockerのインストール

WindowsやMacOSの場合は、Docker公式HPからインストーラーをダウンロードして「次へ」「次へ」と進めれば基本的に問題ありません。

Docker for Windows
Docker for Mac

UbuntuやCentOSなどのLinuxに入れる場合は手順が多少異なりますが、基本的には公式のインストールガイドに則って進めていけば問題ありません。

Install Docker CE

インストールが完了したらひとまずPCを再起動し、ターミナルを立ち上げて下記のコマンドでエラーが出なければインストール完了です。

$ docker -v
Docker version 18.03.0-ce, build 0520e24

いざ環境構築

ベースとなるイメージ(Ubuntu)を用意

インストールが完了したら、早速今回の開発環境のベースとなる”まっさらなUbuntu”を用意します。

始めに現在PCにあるイメージを確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

上記のように、まだUbuntuのイメージがない場合は

$ docker pull ubuntu:latest

によりイメージをダウンロードします。

Python3+Flaskをセットアップ

ベースとなるイメージが取得できたら、実際に必要な環境をセットアップしていきます。

セットアップの方法には大まかに言って2種類あります。

  1. PCを立ち上げて(=コンテナを作って)、そこにインストールする方法
  2. PCの仕様書(=イメージ)に、所望の項目を付け加え、新しいイメージを作る方法

どちらの方法でも問題ないと言えば問題ないのですが、Dockerのコンセプトの一つである”環境の使い捨て”を考えると、「1.」のような一時的にしか使われないコンテナ内にインストールする方法はあまり推奨されません。なので、ここでは「2.」の方法で環境構築を行います。

ここで、「2.」を行うにもまた2種類の方法があります。

2.1. 実際にPCを立ち上げ(=コンテナを作って)、色々とセットアップした後、そのコンテナを新しいイメージとして保存する方法
2.2. 仕様書を書き上げ、仕様書に基づき構築する方法

なんとも歯切れの悪い説明になってしまいましたが、実際に行なっている様子を見ていただければ感覚を掴んでもらえると思います。

またしても、上記どちらの方法でも問題ないのですが、「2.2.」の方法には「仕様書を残せる」というメリットがあります。もちろん「2.1.」でも手順を厳密にメモしておけば問題ないのですが、仕様書という形で残っていると別の人がそのイメージを見る/使う際にそれがどのようにして作られた物なのかが明確になるという点と、再現性が高まるという二つのメリットがあります。そのため、ここでは「2.2.」の方法を用いて環境を構築します。

さて、前置きが長くなりましたが、いよいよ環境構築に入ります。と言っても非常に簡単で、下記のような仕様書を書いて、Dockerにビルドしてもらうだけです。

$ vi Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install python3 python3-pip -y

RUN pip3 install flask

これで新しいイメージの仕様書ができました。説明が逆転してしまいましたが、このような仕様書のことをDocker用語でDockerfileと呼びます。

あとは下記のコマンドでビルドして完了です。

$ docker build . -t hoge/fuga:1.0

初めてビルドするときは長々と色々なログが出力されます。気長に待って、

Successfully tagged hoge/fuga:1.0

と出たら完了です。

ちなみにhoge/fugaの部分は、新しいイメージの名前になるので、お好きな名前をつけましょう。:1.0の部分は、イメージのタグと呼ばれる部分で、主にバージョン名をつける場合が多いようです。

完了したら、下記のコマンドで新しく作ったイメージを確認してみましょう。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hoge/fuga           1.0                 e6a57212b2fa        6 days ago          442MB

表示されるリストの中に、先ほど作ったイメージがあることを確認できれば、環境の準備が整いました。

動作確認・コンテナの立ち上げ

イメージの作成が完了した所で、早速作ったイメージを元にコンテナを起動してみましょう。

$ docker run -it --rm hoge/fuga:1.0 /bin/bash
root@baadc7ca9bdd:/#

上記のようにユーザー名@ホスト名が変われば、無事コンテナが起動できた(PCを立ち上げてログインすることができた)ということになります。

ログインした状態で、

$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

となれば、無事Pythonのインストールが出来ているということになります。

以上の確認が終わったら、exitでコンテナからログアウトしましょう。起動したときに--rmのオプションをつけたため、コンテナはログアウトと同時に自動的に削除されます。

環境の準備が整った所で、Webアプリを動かしてみましょう。まずFlaskにおけるHello world的なサンプルアプリを用意します。

$ vi app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello world!!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

アプリができたら、次に先ほどセットアップしたイメージを基にコンテナを起動し、コンテナ内にこのファイルを取り込む(持ち込む、と表現した方がわかり易い?)工程が必要です。この方法として、FTPで送る等まで含めると様々ありますが、開発の用途で使う場合、コンテナ起動時に必要なファイルが入ったフォルダを”マウントさせる”という方法がおすすめです。

この方法は、「ローカルのとあるフォルダと、コンテナ(仮想PC)のとあるフォルダを”リンク”させる」とでも言えば良いでしょうか。

実際にやってみましょう。まずはマウントする用のフォルダを作り、そこの先ほどのapp.pyを移動します。

$ mkdir vol
$ mv app.py vol/

この時点で、作業ディレクトリ(web)はこんな感じになっています。

web
 |-Dockerfile
 `-vol
    `-app.py

この状態から、コンテナを立ち上げる際に下記の通りオプションを付けて起動してみます。

$ docker run -it --rm -p 5000:5000 -v $(pwd)/vol:/home hoge/fuga:1.0 /bin/bash

ここの-vの部分の、:を挟んだ左側がホスト側のフォルダ、右側がコンテナ内のフォルダを指定しています。コンテナにログインできたところで、マウントしたフォルダに移動してみてapp.pyが確認できれば、マウントが成功しているということになります。

アプリの起動

ここまでくれば、最後、アプリを起動してみて、アクセスできるかどうかを確認してみましょう。

$ python3 app.py
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

無事起動ができたら、適当なWebブラウザでhttp://localhost:5000/にアクセスしてみましょう。Hello world!!と表示されたページが表示されれば無事完了です。

最後に、ホスト側にあるapp.pyの中の`Hello world!!の部分を少し変えてみて、Webページを更新してみてください。すると表示がWebページの中身が変わっていると思います。これは、ホスト側のファイルとコンテナ内のファイルが同期しているから、と言うことになります。便利ですね。



以上で、Webアプリ開発環境の構築は終了です。
ありがとうございました。