概要
Flaskアプリケーションを立ち上げる手順や関連する設定について記載します。
本記事の内容は、ローカルにてWebサーバおよびAppサーバをDockerコンテナで起動するケースとなります。
前編はプロセスをそれぞれdocker
コマンドで起動する、後編はdocker-compose
で一括起動するといった内容を扱います。
前提
- ローカル環境でpythonが実行可能であること
- Webサーバ・Appサーバはローカルプロセス編のものを利用する
全体像
ホストPCとしての準備
本記事ではローカルPCをDockerのホストPCとして構築していきます。
これにあたりDockerを動かすための準備が必要です。
いくつかの方法がありますが、MacOS
の場合はDocker for Mac
をbrewインストールするのが手っ取り早いと思います。
※ Docker for Mac
の有料化が叫ばれていますが、個人利用の範疇では引き続き無料で利用が可能です。
brew install docker --cask
これでアプリケーションがインストールされるので、ローカルでDocker.app
を起動します。右上にクジラのようなアイコンが出現して、下記のようにRunningになっていれば完了です。
最終的な成果物
ソースコード
Githubリポジトリを参照ください。
ソースコード簡易解説
Dockerコンテナ化にあたって、Step1からの主な変更点は以下の2つです。
- Webサーバ、AppサーバそれぞれのDockerfileを新規作成
- 起動コマンドを記載したMakefileを新規作成
このうち、2つめのMakefileについては、dockerコマンドの入力を簡易的にするだけのものであり、本質的な追加は1つめのDockerfileになります。それぞれのDockerfileの内容について見ていきたいと思います。(Dockerfileそのものについては後述)
Webサーバ
# ベースとなるイメージを指定。この場合はバージョンまで特定のタグを指定している。
FROM nginx:1.17.6-alpine
# ホストPCの設定ファイル(config/nginx.conf)を上で作成したディレクトリへコピーして送る
RUN mkdir -p /etc/nginx
COPY config/nginx.conf /etc/nginx/nginx.conf
単にnginxを利用するのであれば、Docker Hub
に公開されているnginx Official ImageをpullするだけでOKです。今回は手元で作成したnginx設定ファイルを読んで起動させたいので、次のような作業を行っています。
- ベースとなるイメージを指示
- 自前の設定ファイルを送るパスを作成
- 自前の設定ファイルをホストPCから、このイメージへコピー
Appサーバ
# 今回はdebianベースのpythonイメージをベースとする
FROM python:3.10-slim-buster
# 設定ファイルの転送(適当な場所が思いつかないので/app直下)
RUN mkdir -p /app/config
COPY requirements.txt /app/requirements.txt
COPY config/gunicorn_settings.py /app/config/gunicorn_settings.py
COPY flask_app.py /app/flask_app.py
# パッケージのインストール
RUN pip install -r /app/requirements.txt
EXPOSE 9876
WORKDIR /app
# run実行時のコマンド
# ENTRYPOINT->CMDでCMDはrunのときの引数で上書きすることが可能
ENTRYPOINT [ "gunicorn", "flask_app:app" ]
CMD [ "-c", "/app/config/gunicorn_settings.py" ]
osのみのベースイメージから始めて、python等をインストールするという手順でもいいのですが、せっかくpythonのOfficialイメージが公開されているので、今回はこれをベースとしてスタートします。
パッケージのインストール
まではほぼWebサーバと同様ですが、それより下はWebサーバにはなかった記述ですね。次のようなことをしています。
- Appサーバのコンテナで、9876ポートをLISTEN状態とする
- コンテナ起動時のベースディレクトリを
/app
に設定する - コンテナ起動時、
gunicorn flask_app:app -c /app/config/gunicorn_settings.py
コマンドを実行する
About Docker
Docker化する理由
これに関してはいくつかあると思いますが、自分の感じる利点を2つ記載しておきます。
開発/実行環境の統一・準備の簡易化
チーム開発を行うにあたって、これまでは開発者がそれぞれのマシンで開発環境を準備してそのうえで開発を開始する必要がありました。手順を示したドキュメントはあるでしょうが、実際はドキュメント不備やツールのアップデートなどの事由によってうまく環境構築ができないなどコストがかかるかと思います。また、個人がそれぞれに言語のバージョンアップなどを行い微妙な違いが発生するというリスクも考えられます。
一方で、あらかじめ用意されたDockerコンテナを利用することにより、
- 少ないコマンド数(
docker run
)で環境が構築できる - 開発環境の統一が容易
という恩恵を受けることができます。
本番環境にもコンテナをのせられる
クラウド上での運用が当たり前となった現在では、GKEなどを利用したコンテナオーケストレーションツールが数多く出回っています。コンテナオーケストレーションというくらいなので、実際に本番環境でもコンテナ上でアプリケーションが起動していることとなります。
もちろん開発、ステージング、本番とで環境変数やエンドポイントなどを変更することが必要ですが、オーケストレーション側でも吸収することはでき、いずれにせよ開発環境で動いたコンテナがほぼそのまま本番環境でも稼働することとなります。
イメージとコンテナ
まずイメージを作成(=ビルド)して、そのイメージをもとにコンテナを作成・起動するといった順番です。
うまい例ではないですが、PCゲームで置き換えると
- Dockerイメージ = ディスク
- Dockerコンテナ = ゲーム起動中のウィンドウ
みたいな感じです。
Docker Hubとは
自身が作成したコンテナイメージをアップロードして公開・共有できるサービス。要はGithubのDocker限定版みたいなものです。
公開されているイメージは自由にダウンロード、利用することが可能です。自身でカスタマイズしたイメージを作成する際にも、ベースとなるイメージはDocker Hubに登録されているものから選択します。
イメージの信頼性
Docker Hubには有志によるイメージも数多く登録されています。その中でベースイメージとして選択するとよいものはDocker Official Images
というタグのついたものとなります。
理由を一言にすると、信頼性が高いからなのですが、いくつか箇条書きであげておきます。
- 適時セキュリティ・アップデートが行われる
- 明確なドキュメントが存在する
- Dockerfileのベストプラクティスを提供する
- 必要不可欠なベースイメージを提供する
Dockerfileとは
作成するコンテナのベースとなるイメージ、アプリケーションインストール、アプリケーション起動の準備などの一連の作業を一括で実施できる命令が記述されたファイルのことです。
なお、Dockerfileの記述に関する詳細はこちらを参照ください。