5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Docker-compose にてAPI(Flask)とDB(MongoDB)とクライアントソフト(MongoExpress)の開発環境作成

Posted at

はじまり

研究室の後輩に対してPython講習会を持ち回りで行っているんですが、自分の出番でAPI通信を勉強したくなりました。

少しだけDockerを作っていることから、DockerでDBとAPIサーバーが作れるようになったら便利かなと思い、トライしてみました。

Docker環境さえあれば、手軽にWebアプリの開発環境としても利用できます。

手に入る環境

image.png

わざわざ説明するまでもないかもしれませんが、構成と環境を書きました。

APIアクセスの場合、localhost:5000にいけば、APIへフォワーディングされ、

DBへの直接接続の場合、localhost:27018にいけばフォワーディングされます。

またlocalhost:10081をブラウザ上で開けば、クライアントソフトであるMongo-Expressが立ち上がります。

なんか微妙にポートを変えている理由は、研究室のサーバーで既に使っているポートがあったためです。

あまり他の記事でも、ポート変更をしてなかったので、備忘録としても書いておきます。

フォルダ構成

├── Dockerfile
├── configdb
├── docker-compose.yml
└── src
    ├── app.py
    ├── mongo.py
    └── requirements.txt

なんか自動的に生成されるフォルダとかは省いています。

DockerFileはFlaskによるAPIサーバーの内容を記述、composeには、mongoとmongo-expressを書いています。

実際のコード

長々と失礼しました。ここからはコードの共有+説明です。

DockerFile
FROM python:3.6

ARG project_dir=/projects/

ADD src/requirements.txt $project_dir

WORKDIR $project_dir

RUN pip install -r requirements.txt

なんてことないPythonのイメージです。

composeにてVolumeなどを行っていきます。

docker-compose.yml
version: '3.1'
services:
  flask:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - "./src:/projects"
    tty: true
    environment:
      TZ: Asia/Tokyo
  api_mongo:
    image: mongo:3.6.5
    restart: always
    ports:
      - 27018:27017
    volumes:
      - /var/lib/mongo_data:/data/db
      - ./configdb:/data/configdb
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: password
  api_mongo-express:
    image: mongo-express
    restart: always
    links:
      - 'api_mongo:mongo'
    ports:
      - 10081:8081
    environment:
      ME_CONFIG_MONGODB_AUTH_DATABASE: admin
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: password
      ME_CONFIG_BASICAUTH_USERNAME: admin
      ME_CONFIG_BASICAUTH_PASSWORD: password
    depends_on:
      - api_mongo

個人的にミソだと思ったところはmongo-expressの場所の以下の記述です

links:
  - 'api_mongo:mongo'

ここでDocker-compose内のMongodbの名前を入れてあげないと、expressが立ち上がりません。

app.py
from flask import Flask, jsonify, request
from mongo import get_mongo

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

@app.route('/')
def index():
  return jsonify({
    "message": "API立ち上がってまーす!"})

@app.route('/test')
def mongo_test():
  conf = get_mongo()
  col = conf['test']['test_col']
  data = col.find_one()
  return jsonify(data)
 
if __name__ == '__main__':
  app.run(host='0.0.0.0', port=5000)

一応、APIが立ち上がっているかだけ確認するlocalhost:5000/
APIにアクセスした上でMongoのコレクションを参照するlocalhost:5000/testを実装しています。

mongo.py
from pymongo import MongoCliant

def get_mongo():
    mongo_client = MongoClient('api_mongo', 27017)
    mongo_client['admin'].authenticate("root","password")
    return mongo_client

こちらはmongoのコネクションを獲得するための関数になります。

これのポイントとしては

mongo_client = MongoClient('api_mongo', 27017)

api_mongoです。ここを自分はlocalhostにしていたんですが、なかなかつながらなくて苦労しました。

なぜかというと、こちらのPythonファイルが動くflaskコンテナにおいてのlocalhostという意味合いになってしまうためですね。

ゆえにDocker-compose時に出来上がるDockerNetWorkで名前解決のできる、docker-compose時につけた名前を書く必要があるというわけです。

requirements.txt
flask
pymongo

flask と pymongoのpip をインストールします

早速起動

docker-compose up -d

後でflaskのコンテナに入りたいので、-dオプションを追加します。

コンテナが3つ立ち上がり、停止していないことを確認します

docker ps

次に、APIサーバーの起動を実際に行います。

そのためにflaskコンテナに入り、app.py を実行します。

docker-compose exec flask bash
## コンテナ内にて
python3 app.py

こうするとAPIサーバーが立ち上がります。

もしコードにタイポや間違いがあったら、上手く立ち上がらないと思います。

あとは、mongo-expressでも直接DBでもいいので、testDBに対してtest_colコレクションを作り、適当に値を入れ、

APIサーバーを実際叩いてみましょう!

curl localhost:5000/
curl localhost:5000/hello

問題なくちゃんと帰ってくれば、開発環境完成です。

終わりに

どこにも所属してないですが、アドベントカレンダー代わりに投稿しました。

今回はlocalで作りましたが、外部に公開したサーバとかと疎通させてみます。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?