概要
前記事に引き続き Docker公式ドキュメントのPart2の内容を整理
Part2 containers
Introduction
Dockerの方式でアプリをビルドしていく.
アプリケーションのヒエラルキーの下層部分であるコンテナから始めます.
コンテナの上層はserviceと呼ばれ、production環境でコンテナがどのように振る舞うのかを定義します. (Part3で取り上げる).
ヒエラルキーの最上層はスタックと呼ばれ、全てのserviceのやり取りを定義します.(Part5で取り上げる).
- Stack
- Services
- Container(このパートで取り上げる)
Your new develop environment
今まで,もしPythonアプリケーションを作る際に、まず最初にマシン上にPythonのランタイムをインストールしていました.
しかし,このやり方はマシンの環境が作成するアプリを期待通りに動作させる必要を生じさせた.
Dockerで、ユーザはイメージとして可搬性のあるPythonランタイムを利用できます.
これにより,ユーザが作成するビルドはアプリケーションコードと同様にPythonイメージも含むことができ,ランタイムと依存関係を全て保証できます.
Define a container with Dockerfile
Dockerfile はコンテナ内の環境で起こることを定義します.
ネットワーク・インタフェースへのアクセスと,ディスクドライブはこの環境内で仮想化され,システム内の他のものとは隔離されるため,ユーザは外部とやり取りするためにポートを指定し,どのファイルをコンテナ環境内にコピーするか指定します.
指定したあと,Dockerfileで定義されたアプリがどのような環境でも正常に振る舞うことを保証されます.
Dockerfile
新たなディレクトリにDockerfileを作成し,簡単なPythonアプリの環境を定義する.
# Use an official Python runtime as a parent image FROM python: 2.7-slim # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app Add . /app # Install any needed packages specified in requirements.txt RUN pip install --trusted-host pypi.python.org -r requirements.txt # Make port 80 available to the world outside this containers EXPORSE 80 # Define environment variable ENV NAME world # Run app.py when the container launches CMD ["python", "app.py"]
Dockerfile内にまだ作成されていないapp.pyとrequirements.txtがあるので作成していきます.
requirements.txt
Flask Redis
app.py
from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host = "redis", db = 0, socket_connect_timeout = 2, socket_timeout = 2) app = Flask(__name__) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disbled</i?>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
pip install -r requirements.txt によってFlaskとRedisライブラリをインストールし,アプリケーションでは環境変数のNAMEを表示させています.
これで一通りアプリケーションに必要なファイルが揃いました.
ディレクトリ配下に3つのファイルがある状態となります.
$ ls Dockerfile app.py requirements.txt
Build the app
これでアプリケーションをビルドする準備が整いました.
Dockerfileが存在しているディレクトリ上で,docker build コマンドを実行してDockerイメージを作成します.
-tオプションにより,イメージ名を指定できます.
docker build -t friendlyhello .
作成後,Dockerイメージが作られたかを確認します.
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE friendlyhello latest 596560250ed9 About a minute ago 148MB
Run the app
ここでdocker run コマンドによりアプリケーションを起動させていきます. -pオプションで,マシン上の4000番ポートをコンテナ内の80番ポートと紐付けた上で起動させます.
$ docker run -p 4000:80 friendlyhello * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
ここで,マシン上のwebブラウザから,localhostの4000番ポートにアクセスするとアプリケーションへアクセスできます.
-dオプションを使うことでバックグラウンドでも実行できます.
docker run -d -p 4000:80 friendlyhello
docker container ls または docker ps で,使用しているコンテナのIDなどの情報をみることができます. ポートのマッピング情報なども見れます.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2ee894e48ab friendlyhello "python app.py" 5 seconds ago Up 4 seconds 0.0.0.0:4000->80/tcp nostalgic_perlman
起動したコンテナプロセスを止める場合 docker container stop で行えます.
この際に止めたいコンテナのコンテナIDを指定します.
$ docker container stop c2ee894e48ab c2ee894e48ab
Share your image
作成したコンテナイメージの可搬性を実感するために,コンテナイメージを外部にアップロードしてみます.
これを行う際に必要なのは,コンテナをデプロイする際にレジストリにプッシュする方法を知ることのみです.
レジストリはレポジトリのコレクションであり,,レポジトリはイメージのコレクションです.
レジストリのアカウント毎に多くのレポジトリを作成できます.
dockerクライアントはデフォルトで,docker公式レジストリを使用します.
Log in with your Docker ID
https://cloud.docker.com/ でアカウントを作成したうえで,dockerコマンドを使ってマシン上でレジストリにログインします.
$ docker login
Tag the image
レジストリ内のレポジトリの表記は username/repository:tag となります.
タグは必須ではないですが, つけることを推奨します. なぜならタグはレジストリのDockerイメージのバージョンを表す仕組みになっているからです.
レポジトリとタグ名はコンテキストに合わせた名前をつけるべきです.
ここで,実際にDockerイメージにタグを付けてみます.
以下のような表記でタグを作成できます.
username repository TAGはそれぞれユーザによって変えてください.
docker tag image username/repository:TAG
作成したタグは docker image ls で確認できます.
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE username/get-started part2 16974e44583c 21 minutes ago 148MB
Publish the image
前項でDockerイメージに対するタグ付けができました.
ここで,タグをつけたDockerイメージをレポジトリにアップロードします.
docker push username/repository:TAG
アップロードしたイメージはパブリックに利用可能です.
Docker cloudにログインした上で下記のページで作成したイメージを確認できます.
https://hub.docker.com/
Pull and run the image from the remote repository
docker run コマンドでレポジトリとタグを直接指定してコンテナを起動することができます.
docker run -p 4000:80 username/repository:tag
もし指定したDockerイメージがローカルマシンに存在しない場合,DockerはレポジトリからDockerイメージをpullしてきます.