Docker + Flask + Apache

Pythonの公式イメージにApacheとFlaskを入れてwsgiで連携する。

 

ディレクトリ構成
|- app/
| ├ app.wsgi
| └ hello.py
├ conf/
| └ 000-default.conf
├ Dockerfile
└ docker-compose.yml

 

Dockerfile

FROM python:3
USER root

WORKDIR /app

RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE jp_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

RUN apt-get install -y vim less
RUN apt-get install -y apache2
RUN apt-get install -y apache2-dev

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install --upgrade Flask
RUN pip install --upgrade mod_wsgi

CMD ["apachectl", "-D", "FOREGROUND"]

docker-compose.yml

version: '3'
services:
  python3:
    build: .
    container_name: flask_apache_test
    hostname: flask_apache_test
    tty: true
    volumes:
      - ./app:/app
      - ./conf/000-default.conf:/etc/apache2/sites-available/000-default.conf
    ports:
      - 18080:80

conf/000-default.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /app

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/acceess.log combined

    # Pythonのバージョンに合わせてLoadModuleを変更する必要がある。
    # バージョンがわからない場合は、以下の行をコメントアウトしてコンテナを起動し、コンソールでログインしてパスを確認する。
    # docker-compose exec ${container_id} bash
    #LoadModule wsgi_module /usr/local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-x86_64-linux-gnu.so
    LoadModule wsgi_module /usr/local/lib/python3.11/site-packages/mod_wsgi/server/mod_wsgi-py311.cpython-311-x86_64-linux-gnu.so
    WSGIDaemonProcess myapp processes=1 threads=5 python-path="/usr/local/bin/python3"
    WSGIScriptAlias / /app/app.wsgi

    <Directory /app>
        WSGIProcessGroup myapp
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>

</VirtualHost>

app/app.wsgi

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

from hello import app as application

app/hello.py

from flask import Flask
app = Flask(__name__)

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

if __name__ == '__main__':
    app.run(debug=True)

更新を反映するときはwsgiファイルのタイムスタンプを更新する。「touch app.wsgi」

投稿日: