構築イメージと前提
構築イメージ
前提
前提というかここまでの流れ。
一つのサーバにすべての必要なミドルウェアをインストールした以下のものをDockerコンテナを使用して再現していきます。
または、Dockeで構築した以下のwebアプリにDBサーバ要素を追加した拡張版ともいえます。
但し今回いろいろと最初からやり直します。
仮称(NNMアプリ)
アプリに名称がないと命名が面倒になったりしますので、ここではNginx(Webサーバ)+NginxUnit(APサーバ)+MongoDB(DBサーバ)の構成で構築するWebアプリケーションを「NNMアプリ」(またはnnmap)と仮称します。
DockerfileによるNNMアプリの構築
他の記事などでは、Dockerfileを使用する前にDockerコマンドなどを使用して一つ一つ確認しながら構築していきましたが、ある程度知見もたまってきましたので今回はいきなりDockerfileを使用した構築を行います。
必要な内容のみ記述していますので、細かい内容については必要に応じて過去記事を参照してください。
ディレクトリ構成
ホスト側のディレクトリ構成です。
場所などは基本的に任意です。
/home/ec2-user/docker_work/nnmap ┣mongo ┃ ┣mongoDfile ┃ ┗setup.js ┣nginx ┃ ┣default.conf ┃ ┗nginxDfile ┗unit ┣app ┃ ┣main.py ┃ ┗templates ┃ ┗index.html ┣ conf.json ┗unitDfile
dockerネットワークの構築
今回のアプリでは、3つのコンテナの連携を行いますので、NNMアプリ用のdockerネットワークを作成しておきます。
docker network create nnm-network
MongoDBコンテナ(DBサーバ)の構築
・ファイル構成
/home/ec2-user/docker_work/nnmap/mongo ┣mongoDfile ┗setup.js
・mongoDfile(Dockerfile)
# ベースイメージmongo取得 FROM mongo:4.2.5 # 環境変数の設定 ENV MONGO_INITDB_DATABASE "test" # ファイルのコピー COPY setup.js /docker-entrypoint-initdb.d/ # 認証を有効化して起動 CMD ["mongod", "--auth"]
・setup.js
const user = { user: 'wantan', pwd: 'wantan', roles: [{ role: 'readWrite', db: 'test' }] }; db.createUser(user); db.createCollection('doc'); db.doc.insert({ 'name' : 'wantan', 'num' : '1' }); db.doc.insert({ 'name' : 'ai', 'num' : '2' }); db.doc.insert({ 'name' : 'admin', 'num' : '3' });
・イメージのビルド
※以前ビルドしたイメージがあるのでタグを「2.0」にしています。
docker build -t mongoim:2.0 -f mongoDfile /home/ec2-user/docker_work/nnmap/mongo
・コンテナの起動
docker container run -p 28003:27017 --name nnm-mongo --network nnm-network -d mongoim:2.0
NginxUnitコンテナ(APサーバ)の構築
二つのアプリの接合部になることと、アプリの本体になるため少し煩雑になっています。
・ファイル構成
/home/ec2-user/docker_work/nnmap/unit ┣app ┃ ┣main.py ┃ ┗templates ┃ ┗index.html ┣conf.json ┗unitDfile
・unitDfile(Dockerfile)
# ベースイメージunit取得 FROM nginx/unit:1.16.0-python3.7 # AP用ディレクトリの作成 RUN ["/bin/bash","-c","mkdir -p /usr/local/nginx/app/"] # APディレクトリのコピー COPY app/ /usr/local/nginx/app/ # conf.jsonのコピー COPY conf.json /docker-entrypoint.d/ # 実行環境準備(flaskインストール) RUN ["/bin/bash","-c","apt update"] RUN ["/bin/bash","-c","apt -y upgrade"] RUN ["/bin/bash","-c","apt install -y python3.7"] RUN ["/bin/bash","-c","apt install -y python-pip python3-pip"] RUN ["/bin/bash","-c","pip3 install flask"] RUN ["/bin/bash","-c","pip3 install pymongo"]
・conf.json
{ "listeners": { "*:8082": { "application": "flask_sample" } }, "applications": { "flask_sample": { "type": "python", "path": "/usr/local/nginx/app/", "module": "main" } } }
・app/配下
アプリ本体でもあるため別途後述します。
・イメージのビルド
docker build -t unitim:2.0 -f unitDfile /home/ec2-user/docker_work/nnmap/unit
・コンテナの起動
docker container run -p 8083:8082 --name nnm-unit --network nnm-network -d unitim:2.0
Nginxコンテナ(Webサーバ)の構築
・ファイル構成
/home/ec2-user/docker_work/nnmap/nginx ┣default.conf ┗nginxDfile
・nginxDfile(Dockerfile)
# ベースイメージnginx取得 FROM nginx:1.17 # 設定ファイルのコピー COPY default.conf /etc/nginx/conf.d/
・default.conf
server { listen 80; server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } location /sample/ { proxy_pass http://nnm-unit:8082/; } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
・イメージのビルド
docker build -t nginxim:2.0 -f nginxDfile /home/ec2-user/docker_work/nnmap/nginx
・コンテナの起動
docker run -d -p 8080:80 --name nnm-nginx --network nnm-network nginxim:2.0
疎通確認
3つのコンテナが構築できたので、ブラウザから疎通確認を行います。
うん、ちゃんとDBアクセスしてデータ取得できていますね。
これでコンテナで素早くアプリを構築できるようになりました。
Flaskアプリソース
「/home/ec2-user/docker_work/nnmap/unit/app」配下のアプリソース。
/app/main.py
from flask import Flask, render_template from pymongo import MongoClient application = Flask(__name__) #デフォルトルート @application.route('/') def index(): client = mongo_init() sample = client.test.doc.find() return render_template('index.html',contents=sample) def mongo_init(): host = 'nnm-mongo' port = 27017 db = 'test' user = 'wantan' pwd = 'wantan' client = MongoClient(host, port) client[db].authenticate(user, pwd) return client
/app/templates/index.html
{% block page_content %} <h1>Sample List@docker in ec2</h1> <div> <table> <thread> <tr> <th>name</th> <th>num</th> <th>type</th> </tr> </thread> <tbody> {% for sample in contents %} <tr> <td>{{ sample.name }}</td> <td>{{ sample.num }}</td> <td>{{ sample.type }}</td> </tr> {% else %} <td>no entry exist!</td> {% endfor %} </tbody> </table> </div> </div>
ーーーーーーーーーーーーーーーーーー
少しはDockerfileも使えるようになってきたかな。
・ソース類
docker/nnmap at master · wantanblog/docker · GitHub
※本記事は本書の内容に沿っているわけではありません。