ブログに戻る

Ubuntu 20.04上でDockerを使用してFlaskアプリケーションをビルドおよびデプロイする

Ubuntu 20.04上でDockerを使用してFlaskアプリケーションをビルドおよびデプロイする

はじめに

Docker は、オープンソースのコンテナプラットフォームです。これは、物理ホストマシン上で動作する他のソフトウェアから隔離された状態でソフトウェアを実行できるようにする、軽量で仮想化された、ポータブルな、ソフトウェア定義の標準化された環境です。Dockerは、仮想マシンに代わる軽量な選択肢を提供します。同時に、アプリケーションのポータビリティ、パフォーマンス、アジリティ、およびスケーラビリティを提供します。包括的なDockerエコシステムに関するガイドについては、Dockerによるコンテナ化の詳細な概要をご覧ください。.

Flask は、オープンソースの最小限のWebフレームワークで、Python で構築されています。Flaskの優れた特徴の一部は、軽量で柔軟性があり、高度に構造化されていることです。さらに、実行するために特定のツールやプラグインを必要としません。

FlaskとDockerを組み合わせることで、軽量で柔軟、かつスケーラブルなアプリケーションが得られます。Docker化されたコンテナのポータブルな性質のおかげで、多くのサーバーやインフラストラクチャにデプロイできます。このチュートリアルの焦点は、Dockerを使用してFlaskアプリケーションをデプロイする方法を示すことです。また、アプリケーションの将来のアップデートが確実に反映されるようにする方法も実演します。

前提条件

これは実践的なチュートリアルになります。進めるにあたって、以下の環境を作成する必要があります。

それでは、始めましょう!

ステップ1:Flaskアプリケーションの準備

まず、Flaskアプリケーションを保持するディレクトリを作成することから始めます。お好みのディレクトリ名を選択できますが、このチュートリアルでは flask_demo と名付けます。プロジェクトファイルは /var/www ディレクトリ内に保存します。これは通常、Ubuntuがデフォルトでパブリックインターネットへのアクセスを許可するディレクトリです。まず、次のコマンドを実行してディレクトリを作成し、その中に移動します。

プロジェクトのこのルートディレクトリ内に、Flaskアプリケーションのベースフォルダ構造を作成します。次に、以下のコマンドを実行してベース構造を作成し、途中のすべての親フォルダを作成するために -p フラグを追加します:

appフォルダには、viewsblueprints を含む、Flaskアプリに関連するすべてのファイルが保持されます。Views(ビュー)には、アプリケーションに届くリクエストに応答するために記述するコードが含まれています。Blueprints(ブループリント)は、アプリケーションコンポーネントの作成を支援し、Flaskアプリケーションの一般的なパターンをサポートします。

適切に命名された static フォルダは、画像、CSS、JavaScriptファイルなどの静的アセットを保持します。 templates ディレクトリは、プロジェクトのすべてのHTMLテンプレートを保持します。

これで、Flaskアプリケーションを初期化するために必要なファイルの作成を開始できます。まず、appディレクトリ内に __init__.py という名前のファイルを作成し、 Python インタプリタ に対し、appディレクトリをパッケージとして扱うように指示します。ターミナルで次のコマンドを実行して、nanoエディタでファイルを開きます。

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

その後、エディタで開いている __init__.py ファイル内に次のコードスニペットを追加してFlaskインスタンスを起動し、次のステップで作成する views.py からロジックをインポートします:

完了したら、 Ctrl + OENTER でファイルを保存し、その後 Ctrl + X。次に、 views.pyapp ディレクトリ内に作成します。 views.py ファイルには、アプリケーションロジックの大部分が含まれます:

ファイル内に、次のコードスニペットを追加します。このコードは、ユーザーがウェブサイトにアクセスしたときに、アプリが実行中であることを示すシンプルな文字列を表示します:

このファイルでは、まず Flask アプリのインスタンスをインポートすることから始めます。次に、ルートを定義する行を追加する必要があります: @app.route(/)。この @app.route(/) の行は、Flask では デコレータ と呼ばれます。デコレータを使用すると、1つ以上の関数に追加機能を注入できます。この場合、ルートへの呼び出しを / を home 関数に渡しています。ユーザーがこのルートにアクセスすると、次のテキストが表示されます: "Our Flask application is running!".

次に、アプリケーションの uwsgi.ini ファイルを作成して、uWSGI の設定を保持します。 uWSGI は、プロトコルおよびアプリケーションサーバーとして機能する Nginx のデプロイオプションです。次のコマンドを実行して、nano エディタでプロジェクトのルートディレクトリにファイルを作成します:

開いたファイルの中に、次のコードスニペットを追加します:

このファイルにはいくつかのディレクティブが含まれています。以下にその目的を定義します:

  • module – Flask アプリケーションが提供されるモジュールを定義します。ここではモジュールを main に設定し、ルートディレクトリにある main.py ファイルを参照しています。このファイルは次のステップで作成します。
  • callableuWSGI に対し、アプリケーションからエクスポートされた app インスタンスを使用するように指示します。
  • master – アプリケーション全体のリロード中のダウンタイムを最小限に抑えるために、アプリケーションを実行し続けるようにします。

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

これで、アプリケーションへのエントリポイントを決定する main.py ファイルを作成できます。 uWSGI はこのファイルを読み取って、アプリケーションと対話する方法を認識します。次のコマンドを実行して、プロジェクトの main.py  ファイルを nano で ルート ディレクトリ 内に作成します:

ファイル内に、アプリケーションパッケージで作成された Flask インスタンスをインポートする次の行を追加します:

このステップで行う最後の作業は、アプリケーションの実行に必要な依存関係を定義することです。これらの依存関係は、 dependencies.txt というファイル内に定義します。Docker がアプリケーションのイメージをビルドするとき、 pip (パッケージ マネージャー) コマンドを実行して依存関係をインストールします。次のコマンドを使用して、ルートディレクトリにあるファイルを開きます:

プロジェクトの現時点では、必要な依存関係は1つだけです: Flask。したがって、プロジェクトに必要な適切なバージョンの Flask を参照するために、次の行を追加できます:

依存関係として Flask のバージョン 2.0.1 を採用します。これは、このチュートリアル執筆時点での最新バージョンです。さまざまなバージョンの詳細については、Flask Changes ページを参照してください。これで Flask アプリケーションのセットアップは完了です。次に、デプロイ用の Docker 設定を準備しましょう。

ステップ 2: Docker の設定

Docker デプロイを設定するために、2つのファイル Dockerfile と start.sh を作成します。Dockerfile には、Docker イメージを構成する宣言的な行が含まれています。 start.sh は、イメージをビルドし、 Dockerfile からコンテナを起動するための基本的なシェルスクリプトです。プロジェクトのルートディレクトリにいる状態で、次のコマンドを実行して Dockerfile:

このファイルには、Docker イメージに必要な設定が保持されます。次に、依存関係とイメージのビルド方法を指定するために、次のコードスニペットを追加します:

における最初の行は、Dockerfile で、イメージを構築する際のベースイメージを定義します。今回は、以下のイメージをベースに構築します。 tiangolo/uwsgi-nginx-flaskDockerHub から入手可能)です。多くの Python バージョンをサポートしているため、この特定のイメージを選択しました。

また、イメージを更新することも指定しています。次に、 bash コマンドプロセッサnano テキストエディタ、および git クライアントを追加して、 GitHub, Bitbucket, または Gitlabなどのバージョン管理リポジトリからソースコードをプルおよびプッシュできるようにします。 ENV の行は、コンテナ内で使用される環境変数を指定します。

The COPY コマンドは、依存関係をコンテナにコピーします。 RUN コマンドは、 pip パッケージ マネージャーを呼び出して、 dependencies.txt ファイルを解析し、依存関係を インストールします。編集が終わったら、ファイルを保存して閉じます。

次に、 start.sh スクリプトを作成します。このスクリプトには、イメージを ビルドして 実行するための Docker コマンドが含まれます。これらのコマンドはターミナルで順次実行することもできますが、シェルスクリプトに追加してターミナルから1つのコマンドで呼び出す方がすっきりしていると考えました。

このファイルの内容を定義する前に、まず他のサービスが使用していない空きポートを確定する必要があります。ここではポート 45644 を使用します。ただし、別のポートを選択することもできます。次の行を実行して、ポートが空いているかどうかを確認します。

選択したポートによって異なりますが、上記のコマンドの出力が 1 であれば、そのポートは空いています。そうでない場合は、別のポートを選択してコマンドを再試行する必要があるかもしれません。

Flask application Port Check

空きポートが確定したので、次のコマンドを実行して、プロジェクトのルートディレクトリ内に nano でファイルを作成できます。

このファイル内に、次のコードスニペットを追加します。

最初の行は、shebang と呼ばれ、これが bash ファイルであり、コマンドとして実行されるべきであることを指定します。2行目は、 app_name という変数を宣言しています。この変数を使用して、イメージ名とコンテナ名を設定します。3行目は、Docker に対し、現在のディレクトリにある build の定義に基づいてイメージを Dockerfile ビルドするよう指示します。イメージ名は変数に従って docker-flask-demo となります。

最後の行は、定義した変数に従って docker-flask-demo というコンテナを作成します。 -d フラグは、コマンドの実行が終了した後も、コンテナをバックグラウンドでデタッチモードで実行し続けます。 -p フラグは、サーバー上のポートをコンテナ上の特定のポートにバインドします。この例では、ホストマシンのポート 45644 を、Docker がコンテナ内で公開するポート 80 にマウントしています。

We use the -v フラグを使用して、コンテナにマウントする Docker volume を指定します。 $PWD 変数は、特定の時点で自分がいる current directory へのパスを保持する、デフォルトの Linux 変数です。

Flask application pwd

今回のケースでは、プロジェクトディレクトリ全体をコンテナの /var/www ディレクトリにマウントしています。これで Docker の設定は完了です。次のコマンドを実行することで、イメージをビルドし、ビルドされたイメージに基づいてコンテナを起動できます。

スクリプトの実行が完了するのを待ち、次のDockerコマンドを実行して、実行中のすべてのコンテナを一覧表示します:

出力には実行中のコンテナが表示されます:

Demo Docker

実行中のコンテナの一覧に、次の名前のコンテナが表示されるはずです: docker-flask-demo。サーバーのパブリック IPを見つけ、指定されたポートでブラウザからアクセスします: http://your-server-public-ip:45644.

以下のような出力が表示されるはずです:

Flask App Running

ブラウザに上記が表示されれば、Flaskアプリケーションのデプロイは成功です。次に、ファイルを変更し、テンプレートを介してユーザーにコンテンツを提供します。

ステップ 3: テンプレートファイルを介したコンテンツの提供

Flaskでは、テンプレートは、ウェブサイトの訪問者に静的および動的なコンテンツを表示するために使用されます。ここでは、 HTMLテンプレートを作成し、ユーザーが特定のルートにアクセスしたときにそれを提供する手順を説明します。たとえば、これはホームページや「About」ページなどです。

ターミナルで次のコマンドを実行して、 index.htmlファイルを app/templatesディレクトリに作成します:

次に、以下のコードスニペットをファイルに追加します:

完了したらファイルを保存して閉じます。また、次のコマンドを使用して、Aboutページと呼ばれる別のページを作成します:

ファイルに以下のコードスニペットを追加します:

完了したらファイルを保存して閉じます。次に、 app/views.pyファイルを変更して、テンプレートと実際のページのルートを参照するようにします:

ファイルが以下のようになるように変更します:

完了したら、ファイルを保存して閉じます。変更を有効にするには、コンテナを停止して再起動する必要があります。次のDockerコマンドを実行して、コンテナを停止および起動します。前に定義したコンテナ名をメモしておいてください。

コンテナが起動して実行されたら、ホームページとAboutページにアクセスして、新しいコンテンツの一部を確認してください。

Flask application Index

 Flask application 1

ここまでに、ウェブサイトの訪問者にコンテンツを提供できるFlaskアプリケーションを作成しました。プロジェクトのファイル構造は次のとおりです。

File Structure

新しい変更を反映させるために、Dockerコンテナを再起動する必要があったことにお気づきかもしれません。次のステップでは、ダウンタイムを減らすためにこれを自動化します。

ステップ 4: アプリケーションファイルの更新が自動的にリロードされるように設定する

ロジックやユーザーインターフェースの改善、あるいは依存関係の追加など、アプリケーションへの変更は頻繁に行われます。このような変更を有効にするには、Dockerコンテナの再起動が必要になる場合があります。幸いなことに、 uWSGI には、次の名前の機能があります。 touch-reload(コンテナを再起動せずにPythonスクリプトをリロードするための機能)。

Pythonには、標準で次の機能が備わっています。 auto-reloading(ファイルシステム全体を監視して変更を検知し、変更が発生したときにアプリケーションを更新する自動リロード機能)。自動リロードはダウンタイムを最小限に抑えるのに適していますが、リソースを大量に消費する可能性があります。そのため、本番環境には推奨されません。

特定のファイルへの変更を監視し、変更があったときにアプリケーションをリロードするために、どのように touch-reload を使用できるか見てみましょう。nanoエディタで uwsgi.ini ファイルを修正します。

強調表示された行を追加して、次のようになるようにします。

完了したら、ファイルを保存して閉じます。追加された行は、アプリケーションのリロードをトリガーするために変更されるファイルを指定しています。ただし、今後の変更に対してこの条件を有効にするには、まずコンテナを再起動する必要があります。

これで、自動リロードがどのように機能するかを示すために、 app/views.py ファイルを修正できます。

強調表示されているように、home関数によって返される文字列を変更します。

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

ブラウザでアプリケーションのホームページを開きます: http://your-server-public-ip:45644.

まだ変更は表示されません。これは、touch-reload条件が uwsgi.ini ファイルへの変更を検出するためです。 touch を使用して条件をアクティブにし、次のコマンドでアプリケーション全体をリロードできます。

ここでホームページをリロードすると、新しい変更が表示されます。

Touch Reload

今後、さらに変更を加える場合は、次のコマンドを実行するだけです。 sudo touch uwsgi.ini そして、アプリケーション全体がより短いダウンタイムでリロードされます。これでこのチュートリアルは終了です。

まとめ

このチュートリアルでは、Dockerイメージとコンテナを使用してFlaskアプリケーションを実装し、デプロイしました。コンテナを再起動する必要性を回避してダウンタイムを最小限に抑えるために、 touch-reload を構成して、特定のファイルへの変更を監視し、アプリケーション全体を自動的にリロードするようにしました。最後に、これらすべてをブラウザでテストして、正常に動作することを確認しました。

Dockerは迅速なデプロイを可能にし、アプリケーションの容易なスケーリングを実現します。さまざまなDockerコマンドについて詳しく知りたい場合は、次のチュートリアルをご覧ください。 UbuntuにDockerをインストールして使用する方法.

Dockerに関するその他のリソースについては、当社のブログ、以下をご覧ください。

Happy Computing!

author

Pranay Kapgate

著者 · CloudSigma

Preslav DobrevはCloudSigmaのクリエイティブデザイナーであり、従来型および革新的なマーケティングチャネルを活用した一貫性のあるビジネスアイデンティティに注力しています。彼は芸術的なビジョンと戦略的マーケティングを融合させ、インパクトのあるブランドナラティブを生み出すことに長けています。

コメント

コメントはまだありません。最初のコメントを投稿しましょう。