著者は、 Write forDOnationsプログラムの一環として寄付を受け取るためにTechEducationFundを選択しました。

序章

Docker は、管理者がコンテナーを使用してアプリケーションを作成、管理、デプロイ、および複製できるようにするオープンソースアプリケーションです。 コンテナは、アプリケーションがオペレーティングシステムレベルで実行するために必要な依存関係を格納するパッケージと考えることができます。 これは、Dockerを使用してデプロイされた各アプリケーションが独自の環境に存在し、その要件が個別に処理されることを意味します。

Flask は、Python上に構築されたWebマイクロフレームワークです。 実行に特定のツールやプラグインを必要としないため、マイクロフレームワークと呼ばれます。 Flaskフレームワークは軽量で柔軟性がありますが、高度に構造化されているため、Pythonで記述された小さなWebアプリで特に人気があります。

Dockerを使用してFlaskアプリケーションをデプロイすると、最小限の再構成で異なるサーバー間でアプリケーションを複製できます。

このチュートリアルでは、Flaskアプリケーションを作成し、Dockerを使用してデプロイします。 このチュートリアルでは、展開後にアプリケーションを更新する方法についても説明します。

前提条件

このチュートリアルに従うには、次のものが必要です。

ステップ1—Flaskアプリケーションのセットアップ

開始するには、Flaskアプリケーションを保持するディレクトリ構造を作成します。 このチュートリアルでは、というディレクトリを作成します TestApp/var/www、ただし、コマンドを変更して、好きな名前を付けることができます。

  1. sudo mkdir /var/www/TestApp

新しく作成されたものに移動します TestApp ディレクトリ:

  1. cd /var/www/TestApp

次に、Flaskアプリケーションの基本フォルダー構造を作成します。

  1. sudo mkdir -p app/static app/templates

The -p フラグは mkdir ディレクトリと存在しないすべての親ディレクトリを作成します。 この場合、 mkdir を作成します app 作成中の親ディレクトリ statictemplates ディレクトリ。

The app ディレクトリには、ビューブループリントなど、Flaskアプリケーションに関連するすべてのファイルが含まれます。 Views は、アプリケーションへの要求に応答するために作成するコードです。 ブループリントは、アプリケーションコンポーネントを作成し、アプリケーション内または複数のアプリケーション間で共通のパターンをサポートします。

The static ディレクトリは、画像、CSS、JavaScriptファイルなどのアセットが存在する場所です。 The templates ディレクトリは、プロジェクトのHTMLテンプレートを配置する場所です。

基本フォルダー構造が完成したので、Flaskアプリケーションの実行に必要なファイルを作成する必要があります。 まず、作成します __init__.py 内部のファイル app nanoまたは選択したテキストエディタを使用したディレクトリ。 このファイルは、Pythonインタープリターに次のことを伝えます。 app ディレクトリはパッケージであり、そのように扱う必要があります。

次のコマンドを実行してファイルを作成します。

  1. sudo nano app/__init__.py

Pythonのパッケージを使用すると、モジュールを論理的な名前空間または階層にグループ化できます。 このアプローチにより、コードを特定の機能を実行する個別の管理可能なブロックに分割できます。

次に、にコードを追加します __init__.py これにより、Flaskインスタンスが作成され、からロジックがインポートされます。 views.py このファイルを保存した後に作成するファイル。 次のコードを新しいファイルに追加します。

/var/www/TestApp/app/__init__.py
from flask import Flask
app = Flask(__name__)
from app import views

そのコードを追加したら、ファイルを保存して閉じます。 を押すと、ファイルを保存して閉じることができます Ctrl+X, 次に、プロンプトが表示されたら、 YEnter.

とともに __init__.py ファイルが作成されたら、作成する準備ができました views.py あなたのファイル app ディレクトリ。 このファイルには、ほとんどのアプリケーションロジックが含まれています。

  1. sudo nano app/views.py

次に、コードを views.py ファイル。 このコードは hello world! Webページにアクセスするユーザーへの文字列:

/var/www/TestApp/app/views.py
from app import app

@app.route('/')
def home():
   return "hello world!"

The @app.route 関数の上の行は、デコレータと呼ばれます。 デコレータは、Flaskで広く使用されているPython言語の規則です。 それらの目的は、それらの直後の関数を変更することです。 この場合、デコレータはどのURLがトリガーするかをFlaskに通知します home() 関数。 The hello world によって返されるテキスト home 機能はブラウザ上でユーザーに表示されます。

とともに views.py ファイルを配置すると、作成する準備が整います。 uwsgi.ini ファイル。 このファイルには、アプリケーションのuWSGI構成が含まれます。 uWSGIは、プロトコルとアプリケーションサーバーの両方であるNginxの展開オプションです。 アプリケーションサーバーは、uWSGI、FastCGI、およびHTTPプロトコルを提供できます。

このファイルを作成するには、次のコマンドを実行します。

  1. sudo nano uwsgi.ini

次に、次のコンテンツをファイルに追加して、uWSGIサーバーを構成します。

/var/www/TestApp/uwsgi.ini
[uwsgi]
module = main
callable = app
master = true

このコードは、Flaskアプリケーションが提供されるモジュールを定義します。 この場合、これは main.py ここで参照されるファイル main. The callable オプションは、uWSGIに使用するように指示します app メインアプリケーションによってエクスポートされたインスタンス。 The master オプションを使用すると、アプリケーションを実行し続けることができるため、アプリケーション全体をリロードする場合でもダウンタイムはほとんどありません。

次に、を作成します main.py アプリケーションへのエントリポイントであるファイル。 エントリポイントは、アプリケーションとの対話方法についてuWSGIに指示します。

  1. sudo nano main.py

次に、以下をコピーしてファイルに貼り付けます。 これにより、Flaskインスタンスという名前がインポートされます app 以前に作成されたアプリケーションパッケージから。

/var/www/TestApp/main.py
from app import app

最後に、 requirements.txt 依存関係を指定するファイル pip パッケージマネージャーがDockerデプロイメントにインストールされます。

  1. sudo nano requirements.txt

次の行を追加して、Flaskを依存関係として追加します。

/var/www/TestApp/requirements.txt
Flask>=2.0.2

インストールするFlaskのバージョンを指定します。 このチュートリアルを書いている時点では、2.0.2が最新のFlaskバージョンであり、 >=2.0.2 バージョン2.0.2以降を確実に入手できます。 このチュートリアルでは基本的なテストアプリを作成しているため、Flaskの将来の更新によって構文が古くなる可能性は低くなりますが、安全でありながらマイナーな更新を受け取りたい場合は、そうでないことを指定できます。次のようなものを指定して、将来のメジャーバージョンをインストールしたい Flask>=2.0.2,<3.0. 更新を確認するには、 Flask の公式Webサイト、またはFlaskライブラリのPythonPackageIndexのランディングページを参照してください。

ファイルを保存して閉じます。 これでFlaskアプリケーションが正常にセットアップされ、Dockerをセットアップする準備が整いました。

ステップ2—Dockerをセットアップする

このステップでは、2つのファイルを作成します。 Dockerfilestart.sh、Dockerデプロイメントを作成します。 The Dockerfile 画像の組み立てに使用されるコマンドを含むテキストドキュメントです。 The start.sh fileは、イメージを構築し、そこからコンテナを作成するシェルスクリプトです。 Dockerfile.

まず、を作成します Dockerfile.

  1. sudo nano Dockerfile

次に、必要な構成をに追加します Dockerfile. これらのコマンドは、イメージの構築方法と、含まれる追加の要件を指定します。

/ var / www / TestApp / Dockerfile
FROM tiangolo/uwsgi-nginx-flask:python3.8-alpine
RUN apk --update add bash nano
ENV STATIC_URL /static
ENV STATIC_PATH /var/www/app/static
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt

この例では、Dockerイメージは既存のイメージから構築されます。 tiangolo/uwsgi-nginx-flaskDockerHubにあります。 この特定のDockerイメージは、さまざまなPythonバージョンとOSイメージをサポートしているため、他のイメージよりも優れています。

最初の2行は、アプリケーションの実行とbashコマンドプロセッサのインストールに使用する親イメージを指定します。 nano テキストエディタ。 また、をインストールします git GitHub、GitLab、Bitbucketなどのバージョン管理ホスティングサービスにプルおよびプッシュするためのクライアント。 ENV STATIC_URL /static このDockerイメージに固有の環境変数です。 画像、CSSファイル、JavaScriptファイルなどのすべてのアセットが提供される静的フォルダーを定義します。

最後の2行は requirements.txt ファイルをコンテナに入れて実行できるようにしてから、 requirements.txt 指定された依存関係をインストールするファイル。

構成を追加したら、ファイルを保存して閉じます。

あなたと Dockerfile 所定の位置に、あなたはあなたの書く準備がほぼできています start.sh Dockerコンテナをビルドするスクリプト。 書く前に start.sh スクリプトでは、最初に、構成で使用するポートが開いていることを確認してください。 ポートが空いているかどうかを確認するには、次のコマンドを実行します。

  1. sudo nc localhost 56733 < /dev/null; echo $?

上記のコマンドの出力が 1、その後、ポートは空いていて使用可能です。 それ以外の場合は、で使用する別のポートを選択する必要があります start.sh 構成ファイル。

使用する開いているポートを見つけたら、 start.sh 脚本:

sudo nano start.sh

The start.sh スクリプトは、からイメージを構築するシェルスクリプトです。 Dockerfile 結果のDockerイメージからコンテナーを作成します。 新しいファイルに構成を追加します。

/var/www/TestApp/start.sh
#!/bin/bash
app="docker.test"
docker build -t ${app} .
docker run -d -p 56733:80 \
  --name=${app} \
  -v $PWD:/app ${app}

最初の行はシバンと呼ばれます。 これがbashファイルであり、コマンドとして実行されることを指定します。 次の行は、画像とコンテナに付ける名前を指定し、名前の付いた変数として保存します app. 次の行は、Dockerにイメージをビルドするように指示します Dockerfile 現在のディレクトリにあります。 これにより、という画像が作成されます docker.test この例では。

最後の3行は、という名前の新しいコンテナを作成します docker.test それは港で公開されています 56733. 最後に、現在のディレクトリをにリンクします /var/www コンテナのディレクトリ。

あなたは -d デーモンモードで、またはバックグラウンドプロセスとしてコンテナを開始するためのフラグ。 あなたは -p サーバー上のポートをDockerコンテナの特定のポートにバインドするためのフラグ。 この場合、ポートをバインドしています 56733 ポートへ 80 Dockerコンテナ上。 The -v flagは、コンテナにマウントするDockerボリュームを指定します。この場合、プロジェクトディレクトリ全体をにマウントします。 /var/www Dockerコンテナのフォルダ。

構成を追加したら、ファイルを保存して閉じます。

を実行します start.sh Dockerイメージを作成し、結果のイメージからコンテナーを構築するスクリプト:

  1. sudo bash start.sh

スクリプトの実行が終了したら、次のコマンドを使用して、実行中のすべてのコンテナーを一覧表示します。

  1. sudo docker ps

コンテナを示す出力が表示されます。

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test

あなたはそれを見つけるでしょう docker.test コンテナが実行されています。 実行されたので、ブラウザの指定されたポートのIPアドレスにアクセスします。 http://ip-address:56733

次のようなページが表示されます。

このステップでは、FlaskアプリケーションをDockerに正常にデプロイしました。 次に、テンプレートを使用してコンテンツをユーザーに表示します。

ステップ3—テンプレートファイルを提供する

テンプレートは、アプリケーションにアクセスするユーザーに静的および動的コンテンツを表示するファイルです。 このステップでは、アプリケーションのホームページを作成するためのHTMLテンプレートを作成します。

作成することから始めます home.html のファイル app/templates ディレクトリ:

  1. sudo nano app/templates/home.html

テンプレートのコードを追加します。 このコードは、タイトルといくつかのテキストを含むHTML5ページを作成します。

/var/www/TestApp/app/templates/home.html

<!doctype html>

<html lang="en-us">   
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Welcome home</title>
  </head>
  
  <body>
    <h1>Home Page</h1>
    <p>This is the home page of our application.</p>
  </body> 
</html>

テンプレートを追加したら、ファイルを保存して閉じます。

次に、 app/views.py 新しく作成されたファイルを提供するファイル:

  1. sudo nano app/views.py

まず、ファイルの先頭に次の行を追加して、 render_template フラスコからの方法。 このメソッドは、HTMLファイルを解析して、ユーザーにWebページをレンダリングします。

/var/www/TestApp/app/views.py
from flask import render_template
...

ファイルの最後に、テンプレートファイルをレンダリングするための新しいルートも追加します。 このコードは、ユーザーにコンテンツが提供されることを指定します home.html 彼らが訪問するたびにファイル /template アプリケーションでルーティングします。

/var/www/TestApp/app/views.py
...

@app.route('/template')
def template():
    return render_template('home.html')

更新された app/views.py ファイルは次のようになります。

/var/www/TestApp/app/views.py
from flask import render_template
from app import app 

@app.route('/')
def home():
    return "Hello world!"

@app.route('/template')
def template():
    return render_template('home.html')

完了したら、ファイルを保存して閉じます。

これらの変更を有効にするには、Dockerコンテナを停止して再起動する必要があります。 次のコマンドを実行して、コンテナを再構築します。

  1. sudo docker stop docker.test && sudo docker start docker.test

次のアプリケーションにアクセスしてください http://your-ip-address:56733/template 提供されている新しいテンプレートを確認します。

これで、アプリケーションの訪問者にサービスを提供するDockerテンプレートファイルを作成しました。 次のステップでは、Dockerコンテナを再起動しなくても、アプリケーションに加えた変更をどのように有効にできるかを確認します。

ステップ4—アプリケーションを更新する

新しい要件のインストール、Dockerコンテナーの更新、HTMLとロジックの変更など、アプリケーションに変更を加える必要がある場合があります。 このセクションでは、構成します touch-reload Dockerコンテナを再起動せずにこれらの変更を行うため。

Python autoreloading は、ファイルシステム全体の変更を監視し、変更を検出するとアプリケーションを更新します。 自動リロードは、リソースをすぐに消費する可能性があるため、本番環境では推奨されません。 このステップでは、 touch-reload 特定のファイルへの変更を監視し、ファイルが更新または置換されたときにリロードします。

これを実装するには、まず uwsgi.ini ファイル:

  1. sudo nano uwsgi.ini

次に、強調表示された行をファイルの最後に追加します。

/var/www/TestApp/uwsgi.ini
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini

これは、アプリケーション全体のリロードをトリガーするように変更されるファイルを指定します。 変更を加えたら、ファイルを保存して閉じます。

これを実証するために、アプリケーションに小さな変更を加えます。 あなたのを開くことから始めます app/views.py ファイル:

  1. sudo nano app/views.py

によって返された文字列を置き換えます home 関数:

/var/www/TestApp/app/views.py
from flask import render_template
from app import app

@app.route('/')
def home():
    return "<b>There has been a change</b>"

@app.route('/template')
def template():
    return render_template('home.html')

変更を加えたら、ファイルを保存して閉じます。

次に、アプリケーションのホームページを開いた場合 http://ip-address:56733、変更が反映されていないことに気付くでしょう。 これは、リロードの条件が uwsgi.ini ファイル。 アプリケーションをリロードするには、 touch 条件をアクティブにするには:

  1. sudo touch uwsgi.ini

アプリケーションのホームページをブラウザに再度ロードします。 アプリケーションに変更が組み込まれていることがわかります。

このステップでは、 touch-reload 変更を加えた後にアプリケーションを更新するための条件。

結論

このチュートリアルでは、Flaskアプリケーションを作成してDockerコンテナーにデプロイしました。 また、構成しました touch-reload コンテナを再起動せずにアプリケーションを更新します。

Docker上の新しいアプリケーションを使用すると、簡単にスケーリングできるようになります。 Dockerの使用の詳細については、Dockerの公式ドキュメントを確認してください。