【CentOS】Dockerを使用してApacheからDjangoを起動する(mod_wsgi版)

はじめに

こんにちは、SHOJIです。


前回、ApacheDjangoの構成をuWSGIを使用して構築しました。今回はmod-wsgiを使用してApacheからDjangoアプリケーションを起動します。


前回の記事はこちら。

deadline-driven-developer.hatenablog.com

ApacheコンテナにPython実行環境を追加する

作成するファイルはこちら。

.
├── Dockerfile
├── docker-compose.yml
├── httpd.conf
└── requirements.txt


  1. 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
    
  2. 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
    
  3. requirements.txtを作成する。ここにはインストールするPython packageを記載する。

    Django>=3.0,<4.0
    psycopg2>=2.8
    mod-wsgi>=4.9
    mod-wsgi-httpd>=2.4
    
  4. Apacheイメージからhttpd.confを取得し格納する。

    docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > ./httpd.conf
    

Djangoプロジェクトを生成する

  1. Djangoプロジェクト用のディレクトリとファイルを生成する。

    docker-compose run --rm web django-admin startproject composeexample .
    
  2. 生成したファイルの所有者を変更する。

    sudo chown -R $USER:$USER ./app
    
  3. 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の設定を追加する

  1. httpd.confにLoadModuleWSGIPythonHomeを追加する。 これらの設定はコマンドで出力した結果をコピー&ペーストする。下記のコマンドは、出力結果の改行コードを変更して直接ファイルに書き込む。

    docker-compose run --rm web /usr/local/bin/mod_wsgi-express module-config | tr '\r\n' '\n' | tee -a ./httpd.conf
    
  2. 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
    
  3. バックグラウンドでサービスを起動する。

    docker-compose up -d
    
  4. ローカル環境で編集した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の設定を有効にする。

  1. ブラウザでhttp://[CentOS IP address]:8080にアクセスする。 「It works!」と表示されることを確認する。

  2. バックグラウンドで起動中のサービスを停止する。

    docker-compose stop
    
  3. サービスを起動する。これにより、mod-wsgiの設定が反映される。

    docker-compose up
    
  4. ブラウザでhttp://[CentOS IP address]:8080にアクセスする。
    Djangoの画面「The install worked successfully!」が表示されれば完了。

おわりに

今回はApacheDjangoの連携をmod-wsgiを使って行いました。


このやり方だと、ApacheコンテナとPythonコンテナが分かれないのでdockerを使うメリットが薄い感じがしますね。dockerというかApacheイメージを使うメリットが薄い、が正しいでしょうか。複数の役割を一つのコンテナに持たせてよいのなら、Apacheイメージではなく何らかのOSイメージをベースにした方が手っ取り早い気がします。


まあ、前回もPython環境にuWSGIインストールしているので同じといえば同じかもしれません。