2021年7月11日日曜日

DockerでFlask+Apache環境を作成する

Docker Composeを利用してFlask+Apacheの環境を作成したので、その方法をまとめておく。


環境


Docker Desktop(Windows10 Pro)。


ファイル構成


最終的には以下のファイル構成になる。

任意のフォルダ
│ docker-compose.yml
│ Dockerfile

├─app
│ └─sample
│ │ app.wsgi
│ │ __init__.py

└─conf
   app.conf


Dockerfileの作成

Docker Hubにある公式CentOSイメージのcentos:centos8をベースにイメージを作成する。Dockerfileでは主に以下のことを行う。SSHはFlask+Apache環境を作成するのに必須というわけではないが今回は追加しておく。

  • Python3.8のインストール
  • Apacheのインストール
  • ホストからSSH接続できるようにする
  • ロケールの設定
  • Flaskのインストール
FROM centos:centos8

# コンテナ側のルート直下に作業ディレクトリ(work)を作り移動する
WORKDIR /work

# パッケージのインストールなど
# CentOS8 EOLのためdnfコマンドがエラーになるのでリポジトリ変更で対応(2022.2.13変更)
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-* \
 && dnf -y update \
 && dnf	group install -y "Development Tools" \
 && dnf install -y openssh-server \
    openssh-clients \
	httpd \
	httpd-tools \
	httpd-devel \
	python38 \
	python38-devel \
	python38-mod_wsgi \
	langpacks-ja \
 && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
 && dnf clean all

# タイムゾーン、ロケール設定
ENV TZ="Asia/Tokyo" \
    LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
	LC_ALL="ja_JP.UTF-8"

# Flaskのインストール
RUN pip3 install --no-cache-dir flask

# SSH設定
# rootでのログインを許可
# ポートを22から20022に変更
# rootのパスワードをpasswordに設定
# ssh-keygenでホスト鍵を作成しておかないとSSHの起動に失敗する
RUN /usr/bin/ssh-keygen -A \
 && sed -ri 's/^#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config \
 && sed -ri 's/^#Port 22/Port 20022/' /etc/ssh/sshd_config \
 && echo 'root:password' | chpasswd

EXPOSE 80
EXPOSE 20022

# SSHとApacheを起動
CMD ["sh","-c","/usr/sbin/sshd && /usr/sbin/httpd -D FOREGROUND"]


docker-compose.ymlの作成

Dockerfileでイメージ作成の準備が出来たので、次はdocker-compose.ymlを用意する。

version: "3"
services:
  flask:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: flask
    hostname: flask
    ports:
    - "20022:20022"
    - "80:80"


コンテナ動作確認


作成したDockerfileとdocker-compose.ymlを同じフォルダに置いてコンテナを起動する。  

起動したコンテナの状態確認。

ブラウザでlocalhostにアクセスしてApacheが動作していることを確認。問題がなければ以下の画面が表示される。

次にSSHの確認。ポート20022、rootでパスワードpasswordで接続できればOK。


FlaskをApache上で動かす

コンテナ上のApacheの動作が確認できたら、続いてApacheでFlaskを使えるようにmod_wsgiの設定をする。mod_wsgi (Apache)を参考にApacheのVirtualHostの設定を追加するためにapp.confを作成する。今回はFlaskアプリのファイルをコンテナ上の/var/www/app/sampleに配置するようにする。作成したapp.confはconfフォルダを作成してその中に置いておく。

<VirtualHost *:80>
    WSGIDaemonProcess sample user=apache group=apache threads=5
    WSGIScriptAlias /sample /var/www/app/sample/app.wsgi

    <Directory /var/www/app/sample>
		# WSGIDaemonProcessで指定した名前と同じにする
        WSGIProcessGroup sample

        WSGIApplicationGroup %{GLOBAL}
		
		Require all granted
    </Directory>
</VirtualHost>

次にFlaskアプリの処理を記述した__init__.pyを作成する。

from flask import Flask

def create_app():
    app = Flask(__name__)

    @app.route('/')
    def index():
        return 'Hello!'

    return app

続いて作成した__init__.py内のcreate_appを実行するapp.wsgiを作成する。__init__.pyとapp.wsgiはapp\sampleフォルダを作成してその配下に配置する。

import sys
sys.path.insert(0, '/var/www/app')

from sample import create_app
application = create_app()

最後に作成したファイルをコンテナからマウントするようにdocker-compose.ymlを変更する。

version: "3"
services:
  flask:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: flask
    hostname: flask
    volumes:
      - .\app:/var/www/app
      - .\conf/app.conf:/etc/httpd/conf.d/app.conf
    ports:
    - "20022:20022"
    - "80:80"
追加したApacheの設定を反映させるためにコンテナを再起動。

うまくいっていれば、ブラウザでlocalhost/sampleにアクセスするとHello!と表示される。


2 件のコメント:

  1. 2022年ごろからレポジトリの設定変更が必要です。
    CentOS8がEOLを迎えることにより、既存のレポジトリでは正常に「yum」、「dnf」ダウンロードができなくなりました。
    対策としては、リポジトリの設定を書き換える必要があります。

    今回は以下のコマンドを実行して、リポジトリの設定を書き換えます。

    sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*;

    その後、yum、dnfコマンドでインストール・アップデート等を実行できるようになりました。

    返信削除
    返信
    1. 情報ありがとうございます。
      記事を更新しておきました。

      削除