序章
Webアプリケーションの開発は、さまざまなテクノロジーを構築および保守する場合、複雑で時間がかかる可能性があります。 アプリケーションの複雑さと生産までの時間を短縮するように設計された軽量オプションを検討すると、より柔軟でスケーラブルなソリューションが得られます。 Python 上に構築されたマイクロWebフレームワークとして、 Flask は、プロジェクトに統合できる拡張機能を通じて開発者がアプリケーションを拡張するための拡張可能な方法を提供します。 開発者の技術スタックのスケーラビリティを継続するために、 MongoDB はNoSQLデータベースであり、頻繁な変更に対応できるように拡張および動作するように設計されています。 開発者はDockerを使用して、アプリケーションのパッケージ化とデプロイのプロセスを簡素化できます。
Docker Compose は、アプリケーションサービス、ネットワークボリューム、バインドマウントなどのインフラストラクチャを単一のファイルで定義できるようにすることで、開発環境をさらに簡素化しました。 Docker Composeを使用すると、複数の実行よりも使いやすくなります docker container run
コマンド。 これにより、すべてのサービスを1つの作成ファイルで定義でき、1つのコマンドで、構成からすべてのサービスを作成して開始できます。 これにより、コンテナインフラストラクチャ全体でバージョン管理が確実に行われます。 Docker Composeはプロジェクト名を使用して環境を相互に分離します。これにより、単一のホストで複数の環境を実行できます。
このチュートリアルでは、Docker container 内でFlask、Nginx、およびMongoDBを使用してTo Do Webアプリケーションをビルド、パッケージ化、および実行します。 スタック構成全体を docker-compose.yml
ファイル、Python、MongoDB、およびNginxの構成ファイル。 FlaskはHTTPリクエストを処理するためにWebサーバーを必要とするため、アプリケーションを処理するためにPythonWSGIHTTPサーバーであるGunicornも使用します。 Nginxは、処理のためにリクエストをGunicornに転送するリバースプロキシサーバーとして機能します。
前提条件
このチュートリアルに従うには、次のものが必要です。
- root以外のユーザー
sudo
サーバーの初期設定チュートリアルの手順に従って構成された特権。 - Dockerのインストールと使用方法のステップ1とステップ2の手順でDockerをインストールしました。
- Docker Composeのインストール方法のステップ1の手順に従って、DockerComposeをインストールします。
ステップ1—DockerComposeでスタック構成を作成する
Dockerでアプリケーションを構築すると、DockerComposeで行った構成の変更に応じてインフラストラクチャを簡単にバージョン管理できます。 インフラストラクチャは、単一のファイルで定義し、単一のコマンドで構築できます。 このステップでは、 docker-compose.yml
Flaskアプリケーションを実行するためのファイル。
The docker-compose.yml
ファイルを使用すると、アプリケーションインフラストラクチャを個別のサービスとして定義できます。 サービスは相互に接続でき、永続ストレージ用にボリュームを接続できます。 ボリュームは、Dockerによって管理されるホストファイルシステムの一部に保存されます(/var/lib/docker/volumes/
Linuxの場合)。
ボリューム内のデータはエクスポートしたり、他のアプリケーションと共有したりできるため、ボリュームはDockerでデータを永続化するための最良の方法です。 Dockerでのデータ共有の詳細については、Dockerコンテナとホスト間でデータを共有する方法を参照してください。
開始するには、サーバーのホームディレクトリにアプリケーションのディレクトリを作成します。
- mkdir flaskapp
新しく作成したディレクトリに移動します。
- cd flaskapp
次に、を作成します docker-compose.yml
ファイル:
- nano docker-compose.yml
The docker-compose.yml
ファイルは、DockerComposeファイルのバージョンを識別するバージョン番号で始まります。 DockerComposeファイルのバージョン 3
DockerEngineバージョンをターゲット 1.13.0+
、これはこの設定の前提条件です。 また、を追加します services
次のステップで定義するタグ:
version: '3'
services:
ここで定義します flask
あなたの最初のサービスとして docker-compose.yml
ファイル。 次のコードを追加して、Flaskサービスを定義します。
. . .
flask:
build:
context: app
dockerfile: Dockerfile
container_name: flask
image: digitalocean.com/flask-python:3.6
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_DEBUG: "False"
APP_PORT: 5000
MONGODB_DATABASE: flaskdb
MONGODB_USERNAME: flaskuser
MONGODB_PASSWORD: your_mongodb_password
MONGODB_HOSTNAME: mongodb
volumes:
- appdata:/var/www
depends_on:
- mongodb
networks:
- frontend
- backend
The build
プロパティは、 context
ビルドの。 この場合、 app
を含むフォルダ Dockerfile
.
あなたは container_name
各コンテナの名前を定義するプロパティ。 The image
プロパティは、イメージ名とDockerイメージのタグ付け対象を指定します。 The restart
プロパティは、コンテナを再起動する方法を定義します。あなたの場合は、 unless-stopped
. つまり、Docker Engineが停止/再起動された場合、またはコンテナーを明示的に停止した場合にのみ、コンテナーが停止します。 を使用する利点 unless-stopped
プロパティは、Dockerエンジンが再起動されるか、エラーが発生すると、コンテナが自動的に起動することです。
The environment
プロパティには、コンテナに渡される環境変数が含まれています。 環境変数に安全なパスワードを提供する必要があります MONGODB_PASSWORD
. The volumes
プロパティは、サービスが使用しているボリュームを定義します。 あなたの場合、ボリューム appdata
でコンテナ内にマウントされています /var/www
ディレクトリ。 The depends_on
プロパティは、Flaskが適切に機能するために依存するサービスを定義します。 この場合、 flask
サービスはに依存します mongodb
以来 mongodb
サービスは、アプリケーションのデータベースとして機能します。 depends_on
を保証します flask
サービスは、 mongodb
サービスが実行されています。
The networks
プロパティは指定します frontend
と backend
ネットワークとして flask
サービスはにアクセスできます。
とともに flask
サービスが定義されたら、MongoDB構成をファイルに追加する準備が整いました。 この例では、公式を使用します 4.0.8
バージョン mongo
画像。 次のコードをに追加します docker-compose.yml
次のファイル flask service
:
. . .
mongodb:
image: mongo:4.0.8
container_name: mongodb
restart: unless-stopped
command: mongod --auth
environment:
MONGO_INITDB_ROOT_USERNAME: mongodbuser
MONGO_INITDB_ROOT_PASSWORD: your_mongodb_root_password
MONGO_INITDB_DATABASE: flaskdb
MONGODB_DATA_DIR: /data/db
MONDODB_LOG_DIR: /dev/null
volumes:
- mongodbdata:/data/db
networks:
- backend
The container_name
このサービスのために mongodb
再起動ポリシーが unless-stopped
. あなたは command
コンテナの起動時に実行されるコマンドを定義するプロパティ。 コマンド mongod --auth
資格情報なしでMongoDBシェルへのログインを無効にします。これにより、認証を要求することでMongoDBを保護します。
環境変数 MONGO_INITDB_ROOT_USERNAME
と MONGO_INITDB_ROOT_PASSWORD
指定された資格情報を使用してrootユーザーを作成するため、プレースホルダーを強力なパスワードに置き換えてください。
MongoDBはそのデータをに保存します /data/db
デフォルトでは、したがって、 /data/db
フォルダは指定されたボリュームに書き込まれます mongodbdata
永続性のため。 その結果、再起動してもデータベースが失われることはありません。 The mongoDB
サービスはポートを公開しないため、サービスには backend
通信網。
次に、アプリケーションのWebサーバーを定義します。 次のコードをに追加します docker-compose.yml
Nginxを構成するファイル:
. . .
webserver:
build:
context: nginx
dockerfile: Dockerfile
image: digitalocean.com/webserver:latest
container_name: webserver
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_NAME: "webserver"
APP_DEBUG: "false"
SERVICE_NAME: "webserver"
ports:
- "80:80"
- "443:443"
volumes:
- nginxdata:/var/log/nginx
depends_on:
- flask
networks:
- frontend
ここで定義しました context
の build
、これは nginx
を含むフォルダ Dockerfile
. とともに image
プロパティでは、コンテナのタグ付けと実行に使用するイメージを指定します。 The ports
プロパティは、Nginxサービスがを介してパブリックにアクセスできるように構成します :80
と :443
と volumes
マウントします nginxdata
コンテナ内のボリューム /var/log/nginx
ディレクトリ。
Webサーバーサービスの対象となるサービスを定義しました depends_on
なので flask
. 最後に networks
プロパティは、Webサーバーサービスがアクセスできるネットワークを定義します。 frontend
.
次に、ブリッジネットワークを作成して、コンテナが相互に通信できるようにします。 ファイルの最後に次の行を追加します。
. . .
networks:
frontend:
driver: bridge
backend:
driver: bridge
2つのネットワークを定義しました—frontend
と backend
-接続するサービス用。 Nginxなどのフロントエンドサービスは、 frontend
公的にアクセス可能である必要があるため、ネットワーク。 MongoDBなどのバックエンドサービスは、 backend
サービスへの不正アクセスを防ぐためのネットワーク。
次に、ボリュームを使用して、データベース、アプリケーション、および構成ファイルを永続化します。 アプリケーションはデータベースとファイルを使用するため、それらに加えられた変更を永続化することが不可欠です。 ボリュームはDockerによって管理され、ファイルシステムに保存されます。 このコードをに追加します docker-compose.yml
ボリュームを構成するファイル:
. . .
volumes:
mongodbdata:
driver: local
appdata:
driver: local
nginxdata:
driver: local
The volumes
セクションは、アプリケーションがデータを永続化するために使用するボリュームを宣言します。 ここでボリュームを定義しました mongodbdata
, appdata
、 と nginxdata
MongoDBデータベース、Flaskアプリケーションデータ、およびNginxWebサーバーログをそれぞれ永続化するため。 これらのボリュームはすべて、 local
データをローカルに保存するためのドライバー。 ボリュームはこのデータを永続化するために使用されるため、コンテナーを再起動すると、MongoDBデータベースやNginxWebサーバーログなどのデータが失われる可能性があります。
あなたの完全な docker-compose.yml
ファイルは次のようになります。
version: '3'
services:
flask:
build:
context: app
dockerfile: Dockerfile
container_name: flask
image: digitalocean.com/flask-python:3.6
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_DEBUG: "False"
APP_PORT: 5000
MONGODB_DATABASE: flaskdb
MONGODB_USERNAME: flaskuser
MONGODB_PASSWORD: your_mongodb_password
MONGODB_HOSTNAME: mongodb
volumes:
- appdata:/var/www
depends_on:
- mongodb
networks:
- frontend
- backend
mongodb:
image: mongo:4.0.8
container_name: mongodb
restart: unless-stopped
command: mongod --auth
environment:
MONGO_INITDB_ROOT_USERNAME: mongodbuser
MONGO_INITDB_ROOT_PASSWORD: your_mongodb_root_password
MONGO_INITDB_DATABASE: flaskdb
MONGODB_DATA_DIR: /data/db
MONDODB_LOG_DIR: /dev/null
volumes:
- mongodbdata:/data/db
networks:
- backend
webserver:
build:
context: nginx
dockerfile: Dockerfile
image: digitalocean.com/webserver:latest
container_name: webserver
restart: unless-stopped
environment:
APP_ENV: "prod"
APP_NAME: "webserver"
APP_DEBUG: "true"
SERVICE_NAME: "webserver"
ports:
- "80:80"
- "443:443"
volumes:
- nginxdata:/var/log/nginx
depends_on:
- flask
networks:
- frontend
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
mongodbdata:
driver: local
appdata:
driver: local
nginxdata:
driver: local
ファイルを保存し、構成を確認した後、エディターを終了します。
アプリケーションスタック全体のDocker構成を docker-compose.yml
ファイル。 次に、FlaskとWebサーバー用のDockerfileの作成に進みます。
ステップ2—フラスコとWebサーバーのDockerfileを作成する
Dockerを使用すると、Dockerfileというファイルからアプリケーションを実行するためのコンテナーを構築できます。 Dockerfileは、アプリケーションに必要なソフトウェアをインストールし、要件に基づいてコンテナーを構成するために使用できるカスタムイメージを作成できるツールです。 作成したカスタムイメージをDockerHubまたは任意のプライベートレジストリにプッシュできます。
このステップでは、FlaskおよびWebサーバーサービスのDockerfileを記述します。 開始するには、を作成します app
Flaskアプリケーションのディレクトリ:
- mkdir app
次に、を作成します Dockerfile
のFlaskアプリ用 app
ディレクトリ:
- nano app/Dockerfile
次のコードをファイルに追加して、Flaskコンテナをカスタマイズします。
FROM python:3.6.8-alpine3.9
LABEL MAINTAINER="FirstName LastName <example@domain.com>"
ENV GROUP_ID=1000 \
USER_ID=1000
WORKDIR /var/www/
これで Dockerfile
、Python3.6.8がプリインストールされたAlpine3.9に基づく3.6.8-alpine3.9imageの上にイメージを作成しています。
The ENV
ディレクティブは、グループとユーザーIDの環境変数を定義するために使用されます。 Linux Standard Base(LSB)は、UIDおよびGID0〜99がシステムによって静的に割り当てられることを指定します。 UID 100〜999 は、システムユーザーおよびグループに動的に割り当てられることになっています。 UID 1000-59999 は、ユーザーアカウントに動的に割り当てられることになっています。 これを念頭に置いて、次のUIDとGIDを安全に割り当てることができます。 1000
、さらに、更新することでUID/GIDを変更できます GROUP_ID
と USER_ID
要件に合わせて。
The WORKDIR
ディレクティブは、コンテナの作業ディレクトリを定義します。 必ず交換してください LABEL MAINTAINER
あなたの名前とメールアドレスのフィールド。
次のコードブロックを追加して、Flaskアプリケーションをコンテナーにコピーし、必要な依存関係をインストールします。
. . .
ADD ./requirements.txt /var/www/requirements.txt
RUN pip install -r requirements.txt
ADD . /var/www/
RUN pip install gunicorn
次のコードは ADD
ローカルからファイルをコピーするディレクティブ app
ディレクトリへの /var/www
コンテナのディレクトリ。 次に、Dockerfileは RUN
Gunicornとで指定されたパッケージをインストールするためのディレクティブ requirements.txt
ファイル。チュートリアルの後半で作成します。
次のコードブロックは、新しいユーザーとグループを追加し、アプリケーションを初期化します。
. . .
RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh
USER www
EXPOSE 5000
CMD [ "gunicorn", "-w", "4", "--bind", "0.0.0.0:5000", "wsgi"]
デフォルトでは、Dockerコンテナはrootユーザーとして実行されます。 root ユーザーはシステム内のすべてにアクセスできるため、セキュリティ違反の影響は悲惨なものになる可能性があります。 このセキュリティリスクを軽減するために、これにより、にのみアクセスできる新しいユーザーとグループが作成されます。 /var/www
ディレクトリ。
このコードは最初に addgroup
名前の付いた新しいグループを作成するコマンド www
. The -g
フラグはグループIDをに設定します ENV GROUP_ID=1000
以前に定義された変数 Dockerfile
.
The adduser -D -u $USER_ID -G www www -s /bin/sh
線は作成します www
ユーザーIDが 1000
、によって定義されるように ENV
変数。 The -s
flagは、ユーザーのホームディレクトリが存在しない場合はそれを作成し、デフォルトのログインシェルを次のように設定します。 /bin/sh
. The -G
フラグは、ユーザーの初期ログイングループをに設定するために使用されます www
、前のコマンドで作成されました。
The USER
コマンドは、コンテナで実行されるプログラムがを使用することを定義します www
ユーザー。 Gunicornは耳を傾けます :5000
、したがって、このポートを EXPOSE
指図。
最後に、 CMD [ "gunicorn", "-w", "4", "--bind", "0.0.0.0:5000", "wsgi"]
lineは、ポートでリッスンしている4人のワーカーでGunicornサーバーを起動するコマンドを実行します 5000
. 数は通常、サーバーのコアあたり2〜4ワーカーである必要があります。Gunicornのドキュメントでは、最初のワーカー数として(2 x $ num_cores)+1を推奨しています。
完成しました Dockerfile
次のようになります。
FROM python:3.6.8-alpine3.9
LABEL MAINTAINER="FirstName LastName <example@domain.com>"
ENV GROUP_ID=1000 \
USER_ID=1000
WORKDIR /var/www/
ADD . /var/www/
RUN pip install -r requirements.txt
RUN pip install gunicorn
RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh
USER www
EXPOSE 5000
CMD [ "gunicorn", "-w", "4", "--bind", "0.0.0.0:5000", "wsgi"]
ファイルを保存して、テキストエディタを終了します。
次に、Nginx構成を保持するための新しいディレクトリを作成します。
- mkdir nginx
次に、を作成します Dockerfile
のNginxWebサーバー用 nginx
ディレクトリ:
- nano nginx/Dockerfile
次のコードをファイルに追加して、NginxコンテナーのイメージをビルドするDockerfileを作成します。
FROM alpine:latest
LABEL MAINTAINER="FirstName LastName <example@domain.com>"
RUN apk --update add nginx && \
ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log && \
mkdir /etc/nginx/sites-enabled/ && \
mkdir -p /run/nginx && \
rm -rf /etc/nginx/conf.d/default.conf && \
rm -rf /var/cache/apk/*
COPY conf.d/app.conf /etc/nginx/conf.d/app.conf
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
このNginx Dockerfile
を使用します alpine
ベースイメージ。これは、セキュリティのために構築された最小限の攻撃対象領域を持つ小さなLinuxディストリビューションです。
の中に RUN
インストールするディレクティブ nginx
エラーとアクセスログを標準エラーに公開するためのシンボリックリンクを作成するだけでなく(/dev/stderr
)および出力(/dev/stdout
). コンテナは一時的なものであるため、エラーを標準エラーと出力に公開することがベストプラクティスです。これを行うと、ログはDockerログに送信され、そこからログをElasticスタックなどのログサービスに転送して永続化できます。 これが行われた後、コマンドが実行されて default.conf
と /var/cache/apk/*
結果の画像のサイズを縮小します。 これらすべてのコマンドを1回で実行する RUN
画像のレイヤー数を減らし、結果の画像のサイズも減らします。
The COPY
ディレクティブは app.conf
コンテナ内のWebサーバー構成。 The EXPOSE
ディレクティブは、コンテナがポートでリッスンすることを保証します :80
と :443
、アプリケーションが実行されるように :80
と :443
安全なポートとして。
最後に、 CMD
ディレクティブは、Nginxサーバーを起動するコマンドを定義します。
ファイルを保存して、テキストエディタを終了します。
今では Dockerfile
準備ができたら、トラフィックをFlaskアプリケーションにルーティングするようにNginxリバースプロキシを構成する準備が整いました。
ステップ3—Nginxリバースプロキシの構成
このステップでは、リクエストをGunicornに転送するためのリバースプロキシとしてNginxを構成します。 :5000
. リバースプロキシサーバーは、クライアント要求を適切なバックエンドサーバーに転送するために使用されます。 クライアントとサーバー間のネットワークトラフィックのスムーズな流れを確保するために、抽象化と制御の追加レイヤーを提供します。
を作成することから始めましょう nginx/conf.d
ディレクトリ:
- mkdir nginx/conf.d
Nginxを構成するには、 app.conf
次の構成のファイル nginx/conf.d/
フォルダ。 The app.conf
ファイルには、リバースプロキシがリクエストをGunicornに転送するために必要な構成が含まれています。
- nano nginx/conf.d/app.conf
以下の内容を app.conf
ファイル:
upstream app_server {
server flask:5000;
}
server {
listen 80;
server_name _;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
client_max_body_size 64M;
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
gzip_static on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_buffering off;
proxy_redirect off;
proxy_pass http://app_server;
}
}
これにより、最初にアップストリームサーバーが定義されます。これは、ルーティングまたは負荷分散のためにWebサーバーまたはアプリサーバーを指定するために一般的に使用されます。
アップストリームサーバー、 app_server
、でサーバーアドレスを定義します server
コンテナ名で識別されるディレクティブ flask:5000
.
Nginx Webサーバーの構成は、 server
ブロック。 The listen
ディレクティブは、サーバーが着信要求をリッスンするポート番号を定義します。 The error_log
と access_log
ディレクティブは、ログを書き込むためのファイルを定義します。 The proxy_pass
ディレクティブは、リクエストをに転送するためのアップストリームサーバーを設定するために使用されます http://app_server
.
ファイルを保存して閉じます。
Nginx Webサーバーを構成したら、Flaskto-doAPIの作成に進むことができます。
ステップ4— FlaskTo-DoAPIを作成する
環境を構築したので、アプリケーションを構築する準備が整いました。 このステップでは、POSTリクエストから送信されたToDoメモを保存して表示するToDoAPIアプリケーションを作成します。
を作成することから始めましょう requirements.txt
のファイル app
ディレクトリ:
- nano app/requirements.txt
このファイルは、アプリケーションの依存関係をインストールするために使用されます。 このチュートリアルの実装では、 Flask 、 Flask-PyMongo 、およびrequestsを使用します。 以下をに追加します requirements.txt
ファイル:
Flask==1.0.2
Flask-PyMongo==2.2.0
requests==2.20.1
ファイルを保存し、要件を入力した後、エディターを終了します。
次に、を作成します app.py
にFlaskアプリケーションコードを含めるファイル app
ディレクトリ:
- nano app/app.py
あなたの新しいで app.py
ファイルに、依存関係をインポートするコードを入力します。
import os
from flask import Flask, request, jsonify
from flask_pymongo import PyMongo
The os
パッケージは、環境変数をインポートするために使用されます。 から flask
インポートしたライブラリ Flask
, request
、 と jsonify
アプリケーションをインスタンス化し、リクエストを処理し、JSONレスポンスを送信するオブジェクト。 から flask_pymongo
インポートしました PyMongo
MongoDBと対話するオブジェクト。
次に、MongoDBに接続するために必要なコードを追加します。
. . .
application = Flask(__name__)
application.config["MONGO_URI"] = 'mongodb://' + os.environ['MONGODB_USERNAME'] + ':' + os.environ['MONGODB_PASSWORD'] + '@' + os.environ['MONGODB_HOSTNAME'] + ':27017/' + os.environ['MONGODB_DATABASE']
mongo = PyMongo(application)
db = mongo.db
The Flask(__name__)
アプリケーションオブジェクトをにロードします application
変数。 次に、コードはを使用して環境変数からMongoDB接続文字列を構築します os.environ
. 合格 application
にオブジェクト PyMongo()
メソッドはあなたに mongo
オブジェクト、これはあなたに順番に db
からのオブジェクト mongo.db
.
次に、インデックスメッセージを作成するためのコードを追加します。
. . .
@application.route('/')
def index():
return jsonify(
status=True,
message='Welcome to the Dockerized Flask MongoDB app!'
)
The @application.route('/')
を定義します /
APIのルートを取得します。 ここにあなたの index()
関数は、を使用してJSON文字列を返します jsonify
方法。
次に、 /todo
すべてのやることをリストするためのルート:
. . .
@application.route('/todo')
def todo():
_todos = db.todo.find()
item = {}
data = []
for todo in _todos:
item = {
'id': str(todo['_id']),
'todo': todo['todo']
}
data.append(item)
return jsonify(
status=True,
data=data
)
The @application.route('/todo')
を定義します /todo
APIのGETルート。これにより、データベース内のToDoが返されます。 The db.todo.find()
メソッドは、データベース内のすべてのToDoを返します。 次に、繰り返します _todos
を構築するには item
それだけが含まれています id
と todo
それらを追加するオブジェクトから data
配列し、最後にそれらをJSONとして返します。
次に、やることを作成するためのコードを追加します。
. . .
@application.route('/todo', methods=['POST'])
def createTodo():
data = request.get_json(force=True)
item = {
'todo': data['todo']
}
db.todo.insert_one(item)
return jsonify(
status=True,
message='To-do saved successfully!'
), 201
The @application.route('/todo')
を定義します /todo
APIのPOSTルート。これにより、データベースにToDoメモが作成されます。 The request.get_json(force=True)
ルートに投稿したJSONを取得し、 item
ToDoに保存されるJSONを構築するために使用されます。 The db.todo.insert_one(item)
1つのアイテムをデータベースに挿入するために使用されます。 To Doがデータベースに保存された後、ステータスコードが次のJSON応答を返します。 201 CREATED
.
次に、アプリケーションを実行するためのコードを追加します。
. . .
if __name__ == "__main__":
ENVIRONMENT_DEBUG = os.environ.get("APP_DEBUG", True)
ENVIRONMENT_PORT = os.environ.get("APP_PORT", 5000)
application.run(host='0.0.0.0', port=ENVIRONMENT_PORT, debug=ENVIRONMENT_DEBUG)
状態 __name__ == "__main__"
グローバル変数かどうかを確認するために使用されます。 __name__
、モジュール内はプログラムへのエントリポイントであり、 "__main__"
、次にアプリケーションを実行します。 の場合 __name__
に等しい "__main__"
次に、内部のコード if
ブロックはこのコマンドを使用してアプリを実行します application.run(host='0.0.0.0', port=ENVIRONMENT_PORT, debug=ENVIRONMENT_DEBUG)
.
次に、の値を取得します ENVIRONMENT_DEBUG
と ENVIRONMENT_PORT
を使用して環境変数から os.environ.get()
、最初のパラメーターとしてキーを使用し、2番目のパラメーターとしてデフォルト値を使用します。 The application.run()
を設定します host
, port
、 と debug
アプリケーションの値。
完成 app.py
ファイルは次のようになります。
import os
from flask import Flask, request, jsonify
from flask_pymongo import PyMongo
application = Flask(__name__)
application.config["MONGO_URI"] = 'mongodb://' + os.environ['MONGODB_USERNAME'] + ':' + os.environ['MONGODB_PASSWORD'] + '@' + os.environ['MONGODB_HOSTNAME'] + ':27017/' + os.environ['MONGODB_DATABASE']
mongo = PyMongo(application)
db = mongo.db
@application.route('/')
def index():
return jsonify(
status=True,
message='Welcome to the Dockerized Flask MongoDB app!'
)
@application.route('/todo')
def todo():
_todos = db.todo.find()
item = {}
data = []
for todo in _todos:
item = {
'id': str(todo['_id']),
'todo': todo['todo']
}
data.append(item)
return jsonify(
status=True,
data=data
)
@application.route('/todo', methods=['POST'])
def createTodo():
data = request.get_json(force=True)
item = {
'todo': data['todo']
}
db.todo.insert_one(item)
return jsonify(
status=True,
message='To-do saved successfully!'
), 201
if __name__ == "__main__":
ENVIRONMENT_DEBUG = os.environ.get("APP_DEBUG", True)
ENVIRONMENT_PORT = os.environ.get("APP_PORT", 5000)
application.run(host='0.0.0.0', port=ENVIRONMENT_PORT, debug=ENVIRONMENT_DEBUG)
ファイルを保存して、エディターを終了します。
次に、を作成します wsgi.py
のファイル app
ディレクトリ。
- nano app/wsgi.py
The wsgi.py
fileは、サーバーがそれを使用できるように、アプリケーションオブジェクト(または呼び出し可能)を作成します。 リクエストが来るたびに、サーバーはこのアプリケーションオブジェクトを使用して、URLの解析時にアプリケーションのリクエストハンドラーを実行します。
以下の内容を wsgi.py
ファイルを作成し、ファイルを保存して、テキストエディタを終了します。
from app import application
if __name__ == "__main__":
application.run()
これ wsgi.py
ファイルは、からアプリケーションオブジェクトをインポートします app.py
ファイルを作成し、Gunicornサーバーのアプリケーションオブジェクトを作成します。
これでToDoアプリが配置されたので、コンテナーでアプリケーションの実行を開始する準備が整いました。
ステップ5—コンテナの構築と実行
これで、すべてのサービスを定義しました。 docker-compose.yml
ファイルとその構成により、コンテナを起動できます。
サービスは単一のファイルで定義されているため、単一のコマンドを発行してコンテナーを開始し、ボリュームを作成し、ネットワークをセットアップする必要があります。 このコマンドは、FlaskアプリケーションとNginxWebサーバーのイメージも構築します。 次のコマンドを実行して、コンテナーを作成します。
- docker-compose up -d
コマンドを初めて実行すると、必要なすべてのDockerイメージがダウンロードされます。これには時間がかかる場合があります。 画像がダウンロードされてローカルマシンに保存されたら、 docker-compose
コンテナを作成します。 The -d
flagはプロセスをデーモン化し、バックグラウンドプロセスとして実行できるようにします。
ビルドプロセスが完了したら、次のコマンドを使用して実行中のコンテナを一覧表示します。
- docker ps
次のような出力が表示されます。
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f20e9a7fd2b9 digitalocean.com/webserver:latest "nginx -g 'daemon of…" 2 weeks ago Up 2 weeks 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp webserver
3d53ea054517 digitalocean.com/flask-python:3.6 "gunicorn -w 4 --bin…" 2 weeks ago Up 2 weeks 5000/tcp flask
96f5a91fc0db mongo:4.0.8 "docker-entrypoint.s…" 2 weeks ago Up 2 weeks 27017/tcp mongodb
The CONTAINER ID
コンテナへのアクセスに使用される一意の識別子です。 The IMAGE
指定されたコンテナのイメージ名を定義します。 The NAMES
フィールドは、コンテナが作成されるサービス名であり、次のようになります。 CONTAINER ID
これらは、コンテナへのアクセスに使用できます。 最後に、 STATUS
コンテナーが実行中、再起動中、または停止中かどうかに関するコンテナーの状態に関する情報を提供します。
あなたは使用しました docker-compose
構成ファイルからコンテナーを構築するコマンド。 次のステップでは、アプリケーションのMongoDBユーザーを作成します。
ステップ6—MongoDBデータベースのユーザーを作成する
デフォルトでは、MongoDBはユーザーが資格情報なしでログインすることを許可し、無制限の特権を付与します。 このステップでは、MongoDBデータベースにアクセスするための専用ユーザーを作成して、MongoDBデータベースを保護します。
これを行うには、で設定したルートユーザー名とパスワードが必要になります docker-compose.yml
ファイル環境変数 MONGO_INITDB_ROOT_USERNAME
と MONGO_INITDB_ROOT_PASSWORD
のために mongodb
サービス。 一般に、データベースを操作するときは、root管理者アカウントの使用を避けることをお勧めします。 代わりに、Flaskアプリケーション専用のデータベースユーザーと、Flaskアプリがアクセスできる新しいデータベースを作成します。
新しいユーザーを作成するには、最初にでインタラクティブシェルを起動します mongodb
容器:
- docker exec -it mongodb bash
あなたは docker exec
実行中のコンテナ内でコマンドを実行するためのコマンド -it
コンテナ内でインタラクティブシェルを実行するためのフラグ。
コンテナ内に入ると、MongoDB root管理者アカウントにログインします。
- mongo -u mongodbuser -p
の値として入力したパスワードの入力を求められます MONGO_INITDB_ROOT_PASSWORD
の変数 docker-compose.yml
ファイル。 パスワードは、に新しい値を設定することで変更できます。 MONGO_INITDB_ROOT_PASSWORD
の中に mongodb
サービス。この場合、再実行する必要があります。 docker-compose up -d
指図。
を実行します show dbs;
すべてのデータベースを一覧表示するコマンド:
- show dbs;
次の出力が表示されます。
Outputadmin 0.000GB
config 0.000GB
local 0.000GB
5 rows in set (0.00 sec)
The admin
データベースは、ユーザーに管理者権限を付与する特別なデータベースです。 ユーザーがへの読み取りアクセス権を持っている場合 admin
データベースの場合、他のすべてのデータベースに対する読み取りおよび書き込み権限があります。 出力には admin
データベースの場合、ユーザーはこのデータベースにアクセスできるため、他のすべてのデータベースの読み取りと書き込みを行うことができます。
最初のやることメモを保存すると、自動的にMongoDBデータベースが作成されます。 MongoDBを使用すると、を使用して存在しないデータベースに切り替えることができます。 use database
指図。 ドキュメントがコレクションに保存されるときにデータベースを作成します。 したがって、データベースはここでは作成されません。 これは、APIからデータベースに最初のやることメモを保存するときに発生します。 を実行します use
に切り替えるコマンド flaskdb
データベース:
- use flaskdb
次に、このデータベースへのアクセスを許可する新しいユーザーを作成します。
- db.createUser({user: 'flaskuser', pwd: 'your password', roles: [{role: 'readWrite', db: 'flaskdb'}]})
- exit
このコマンドは、flaskuserという名前のユーザーを作成します。 readWrite
アクセス flaskdb
データベース。 で安全なパスワードを使用してください pwd
分野。 The user
と pwd
で定義した値は次のとおりです docker-compose.yml
の環境変数セクションの下にあるファイル flask
サービス。
次のコマンドを使用して、認証されたデータベースにログインします。
- mongo -u flaskuser -p your password --authenticationDatabase flaskdb
ユーザーを追加したので、データベースからログアウトします。
- exit
そして最後に、コンテナを終了します。
- exit
これで、Flaskアプリケーション専用のデータベースとユーザーアカウントが構成されました。 データベースコンポーネントの準備ができたので、Flaskto-doアプリの実行に進むことができます。
ステップ7—FlaskTo-doアプリを実行する
サービスが構成されて実行されたので、次のコマンドに移動してアプリケーションをテストできます。 http://your_server_ip
ブラウザで。 さらに、あなたは実行することができます curl
FlaskからのJSON応答を確認するには:
- curl -i http://your_server_ip
次の応答が返されます。
Output{"message":"Welcome to the Dockerized Flask MongoDB app!","status":true}
Flaskアプリケーションの構成は、からアプリケーションに渡されます。 docker-compose.yml
ファイル。 データベース接続に関する構成は、 MONGODB_*
で定義された変数 environment
のセクション flask
サービス。
すべてをテストするには、FlaskAPIを使用してやることメモを作成します。 あなたはこれを行うことができます POST
へのカールリクエスト /todo
ルート:
- curl -i -H "Content-Type: application/json" -X POST -d '{"todo": "Dockerize Flask application with MongoDB backend"}' http://your_server_ip/todo
このリクエストの結果、ステータスコードは次のようになります。 201 CREATED
やること項目がMongoDBに保存されるとき:
Output{"message":"To-do saved successfully!","status":true}
GETリクエストを使用して、MongoDBからのすべてのToDoノートを一覧表示できます。 /todo
ルート:
- curl -i http://your_server_ip/todo
Output{"data":[{"id":"5c9fa25591cb7b000a180b60","todo":"Dockerize Flask application with MongoDB backend"}],"status":true}
これにより、サーバーにデプロイされたリバースプロキシとしてNginxを使用してMongoDBバックエンドを実行するFlaskAPIをDocker化できました。 実稼働環境では、次を使用できます sudo systemctl enable docker
Dockerサービスが実行時に自動的に開始されるようにします。
結論
このチュートリアルでは、Docker、MongoDB、Nginx、およびGunicornを使用してFlaskアプリケーションをデプロイしました。 これで、スケーリング可能な最新のステートレスAPIアプリケーションが機能するようになりました。 この結果は、次のようなコマンドを使用して実現できますが docker container run
、 docker-compose.yml
このスタックをバージョン管理に入れ、必要に応じて更新できるため、作業が簡素化されます。
ここから、さらにPythonFrameworkチュートリアルを見ることができます。