はじめに
こんにちは、SHOJIです。
前回、Apache&Djangoの構成をuWSGIを使用して構築しました。今回はmod-wsgiを使用してApacheからDjangoアプリケーションを起動します。
前回の記事はこちら。
deadline-driven-developer.hatenablog.com
作成するファイルはこちら。
.
├── Dockerfile
├── docker-compose.yml
├── httpd.conf
└── requirements.txt
Dockerfileを作成する。
ApacheイメージをベースにPythonの実行環境をインストールする。
FROM httpd:2.4
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y python3-pip
RUN apt-get install -y apache2-dev
RUN apt-get install -y libpq-dev
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY ./httpd.conf /usr/local/apache2/conf/httpd.conf
docker-compose.ymlを作成する。
データベースは前回同様PostgreSQLを使用する。
version: "3.9"
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
web:
build: .
volumes:
- ./app:/code
ports:
- "8080:80"
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
depends_on:
- db
requirements.txtを作成する。ここにはインストールするPython packageを記載する。
Django>=3.0,<4.0
psycopg2>=2.8
mod-wsgi>=4.9
mod-wsgi-httpd>=2.4
Apacheイメージからhttpd.confを取得し格納する。
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > ./httpd.conf
Djangoプロジェクト用のディレクトリとファイルを生成する。
docker-compose run --rm web django-admin startproject composeexample .
生成したファイルの所有者を変更する。
sudo chown -R $USER:$USER ./app
composeexample/settings.pyを編集する。
# settings.py
import os
[...]
ALLOWED_HOSTS = ['*'] # アクセス可能なipアドレスを指定する。アスタリスクはセキュリティの面で非推奨。
[...]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('POSTGRES_NAME'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': 'db',
'PORT': 5432,
}
}
mod-wsgiの設定を追加する
httpd.confにLoadModuleとWSGIPythonHomeを追加する。
これらの設定はコマンドで出力した結果をコピー&ペーストする。下記のコマンドは、出力結果の改行コードを変更して直接ファイルに書き込む。
docker-compose run --rm web /usr/local/bin/mod_wsgi-express module-config | tr '\r\n' '\n' | tee -a ./httpd.conf
httpd.confの末尾に連携するDjangoプロジェクトの定義を追加する。
LoadModule wsgi_module "/usr/local/lib/python3.9/dist-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-x86_64-linux-g
nu.so"
WSGIPythonHome "/usr"
# 以下、手動で追加
WSGIScriptAlias / "/code/composeexample/wsgi.py"
WSGIPythonPath "/code"
<Directory /code/composeexample>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
# EOL
バックグラウンドでサービスを起動する。
docker-compose up -d
ローカル環境で編集したhttpd.confをコンテナへコピーする。
$(docker-compose ps -q web)とすることで、docker-composeで定義したwebサービスのコンテナIDを取得することができる。
docker cp ./httpd.conf $(docker-compose ps -q web):/usr/local/apache2/conf/httpd.conf
サービスを再起動し、mod-wsgiの設定を有効にする。
ブラウザでhttp://[CentOS IP address]:8080にアクセスする。
「It works!」と表示されることを確認する。
バックグラウンドで起動中のサービスを停止する。
docker-compose stop
サービスを起動する。これにより、mod-wsgiの設定が反映される。
docker-compose up
ブラウザでhttp://[CentOS IP address]:8080にアクセスする。
Djangoの画面「The install worked successfully!」が表示されれば完了。
おわりに
今回はApacheとDjangoの連携をmod-wsgiを使って行いました。
このやり方だと、ApacheコンテナとPythonコンテナが分かれないのでdockerを使うメリットが薄い感じがしますね。dockerというかApacheイメージを使うメリットが薄い、が正しいでしょうか。複数の役割を一つのコンテナに持たせてよいのなら、Apacheイメージではなく何らかのOSイメージをベースにした方が手っ取り早い気がします。
まあ、前回もPython環境にuWSGIインストールしているので同じといえば同じかもしれません。