Help us understand the problem. What is going on with this article?

[イメージ図付]Nginx+gunicorn+FlaskをDocker化[前編]

本記事の概要

PythonによるWebアプリケーション学習ロードマップのStep2として、Step1で作成したWebサーバおよびAppサーバをDockerコンテナにて起動するように設定する手順について記載していきます。
記事は前・後編の2編での構成となり、
前編:Docker化後編:docker-compose導入
についての記載となります。(後編はこちら)

前提

MacOSをホストPCとして利用することを想定したコマンド表記となります。

ホストPCとしての準備

本記事ではローカルPCをDockerのホストPCとして構築していきます。
これにあたりDockerを動かすための準備が必要です。
いくつかの方法がありますが、MacOSの場合はDocker for Macをbrewインストールするのが手っ取り早いと思います。

Terminal
brew cask install docker

これでアプリケーションがインストールされるので、ローカルでDocker.appを起動します。右上にクジラのようなアイコンが出現して、下記のようにRunningになっていれば完了です。
スクリーンショット 2020-01-08 14.20.55.png

最終的な成果物

イメージ図

Flask_Nginx_unicorn_diagramdrawio-Step3-docker-compose (1).png

ソースコード

Githubリポジトリを参照ください。

ソースコード簡易解説

Dockerコンテナ化にあたって、Step1からの主な変更点は以下の2つです。

  • Webサーバ、AppサーバそれぞれのDockerfileを新規作成
  • 起動コマンドを記載したMakefileを新規作成

このうち、2つめのMakefileについては、dockerコマンドの入力を簡易的にするだけのものであり、本質的な追加は1つめのDockerfileになります。それぞれのDockerfileの内容について見ていきたいと思います。(Dockerfileそのものについては後述)

Webサーバ

Dockerfile
# ベースとなるイメージを指定。この場合はバージョンまで特定のタグを指定している。
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設定ファイルを読んで起動させたいので、次のような作業を行っています。

  1. ベースとなるイメージを指示
  2. 自前の設定ファイルを送るパスを作成
  3. 自前の設定ファイルをホストPCから、このイメージへコピー

Appサーバ

Dockerfile
# 今回はdebianベースのpythonイメージをベースとする
FROM python:3.8-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サーバにはなかった記述ですね。次のようなことをしています。

  1. Appサーバのコンテナで、9876ポートをLISTEN状態とする
  2. コンテナ起動時のベースディレクトリを/appに設定する
  3. コンテナ起動時、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の記述に関する詳細はこちらを参照ください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした