SEワンタンの独学備忘録

IT関連の独学した内容や資格試験に対する取り組みの備忘録

【Docker】Nginx+NginxUnit(Flask)+MongoDB構成のWebアプリをDockerで再現する

構築イメージと前提

構築イメージ

f:id:wantanBlog:20200419210012p:plain

前提

前提というかここまでの流れ。

一つのサーバにすべての必要なミドルウェアをインストールした以下のものをDockerコンテナを使用して再現していきます。

www.wantanblog.com


または、Dockeで構築した以下のwebアプリにDBサーバ要素を追加した拡張版ともいえます。
但し今回いろいろと最初からやり直します。

www.wantanblog.com


仮称(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つのコンテナが構築できたので、ブラウザから疎通確認を行います。

f:id:wantanBlog:20200419203020p:plain

うん、ちゃんと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


※本記事は本書の内容に沿っているわけではありません。