Django+Apache環境をDocker Composeで作る

ここではDocker(compose)でDjango+Apache環境を構築してみます。
作成した環境はGitHubで公開しています。
こちら

環境

テスト環境

2環境で実施。

  1. Ubuntu 18.04 LTS
    1.1. Docker、docker-composeインストール済み
    1.2. アーキテクチャ : x86_64
  2. Raspbian(Raspberry Pi3+B)
    2.1. Docker、docker-composeインストール済み
    2.2. アーキテクチャ : armv7l

Dockerで作成する環境

2コンテナで構成します。

  1. DBコンテナ
    1.1. DB:MariaDB
  2. Apache+Djangoコンテナ
    2.1. OS:CentOS7
    2.1. Web:Apache

Ubuntuでの環境構築

ファイル構造

以下のようなファイルを用意します。

  • /
    — docker-compose.yml // DBとWebの2コンテナを管理
    — Dockerfile // Web+Djangoコンテナ用
    — requirements.txt // pipでインストールするライブラリをまとめたファイル
    — wsgi.conf // Apache+Django連携のためにApache側に必要な設定ファイル

docker-compose.yml

全体コード

version: '3'

services:
  db:
    image: mariadb
    #image: jsurf/rpi-mariadb
    restart: always
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: [mariadb_root_password]
      MYSQL_DATABASE: [mariadb_db_name]
      MYSQL_USER: [mariadb_user_name]
      MYSQL_PASSWORD: [mariadb_user_password]
  web:
    restart: always
    build: .
    volumes:
      - .:/code
    ports:
      - '8000:8000'
      - '80:80'
    depends_on:
      - db
    privileged: true

コンテナ作成時のイメージ

  • DBコンテナは公開されたmariadbのイメージを使用
  • Web+Djangoコンテナは後ほどのDockerfileでイメージ作成

DB各種設定部分

  • dbコンテナ部分のenvironment欄には
    — [mariadb_root_password] : DBの管理者パスワード
    — [mariadb_db_name] : 作成するデータベース名
    — [mariadb_user_name] : 作成するユーザー名
    — [mariadb_user_password] : 作成するユーザーのパスワード
    を設定。

Webコンテナへのコンテナ外容量のマウント

  • 構築環境とコンテナでDjangoプロジェクトを共有したいため、本ファイル構造のルートをコンテナの作業ディレクトリ/codeにマウント
volumes:
 - .:/code
  • webコンテナのvolumes部分に
volumes:
 - .:/code
 - /mnt/nas_to:/mnt/nas_from

と記述することで構築対象環境の/mnt/nas_fromをコンテナの/mnt/nas_toとしてマウントすることができます。

コンテナとのポートフォワーディング

  • 起動ホストのポート80に来たリクエストをコンテナのポート80にフォワードする必要があるため
    ports:
      - '8000:8000'
      - '80:80'

を記述

コンテナにprivileged権限付加

  • コンテナ内でサービスを起動したいが、systemctlを行うにはprivileged権限付加しなければいけない
    privileged: true

Dockerfile

全体コード

FROM centos:centos7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code

# Python env
RUN yum install -y python3 python3-devel python3-libs httpd-devel gcc make mariadb-devel wget
RUN curl https://bootstrap.pypa.io/get-pip.py | python3

ADD requirements.txt /code/
ADD wsgi.conf /etc/httpd/conf.d/
RUN pip install -r requirements.txt

RUN systemctl enable httpd

CMD ["/sbin/init"]

作業ディレクトリは/code

  • 後ほどターミナルからコンテナに入る際のホームディレクトリ、また構築環境とDjangoプロジェクトを共有するためのディレクトリとして作業ディレクトリ/codeを作成、設定。
RUN mkdir /code
WORKDIR /code

pythonライブラリのインストール

  • 別ファイル(requirements.txt)に記載しているpythonライブラリをインストール
ADD requirements.txt /code/
ADD wsgi.conf /etc/httpd/conf.d/
RUN pip install -r requirements.txt

Apache側の設定ファイルwsgi.confをインストール

  • ApacheとDjangoを連携させるためにApache側に必要な設定ファイルwsgi.confをコンテナ内Apacheに配備
ADD wsgi.conf /etc/httpd/conf.d/

requirements.txt

全体コード

# Django
django==2.2.2
# mod wsgi
mod_wsgi
mod-wsgi-httpd
# Mysql driver
mysqlclient
mysql-connector-python
# Application

requirements.txtファイルです。 ここにはpipでインストールするライブラリをいれます。

Djangoのバージョン指定

  • まずDjangoのバージョンによって使えるDBクライアントなども異なってくるため、 バージョンを指定します。
#Django
django==2.2.2

ApacheとDjango連携のためのPythonライブラリ

  • ApacheとDjangoを連携させるために必要なmod_wsgiをインストールします。
# mod wsgi
mod_wsgi
mod-wsgi-httpd

DBにpythonから接続するためのドライバ

  • Django2.2にはpymysqlやMySQLdbはまだ対応していなようなので、mysql-connector-pythonを選択
# Mysql driver
mysqlclient
mysql-connector-python

Djangoプロジェクトで使用したいライブラリ

  • Djangoプロジェクトで使用したいライブラリがあればこのファイルに追記します。

wsgi.conf

# LoadModule for x86_64
LoadModule wsgi_module /usr/local/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
# LoadModule for armv7l(raspi)
#LoadModule wsgi_module /usr/local/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-arm-linux-gnueabi.so


WSGIScriptAlias / /code/[django_project]/[django-project]/wsgi.py
WSGIPythonPath /code/[django-project]
<Directory /code/[django_project]/[django-project]>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
  • 以下の部分は使用Djangoプロジェクトの名称に置換
    — [django-project] : 使用するDjangoプロジェクトのプロジェクト名

RaspberryPiで使用する際の編集点

docker-compose.yml内、DBコンテナのイメージ変更

  • docker-compose.ymlファイル内dbのimageでmariadbをコメントアウトしてjsurf/rpi-mariadbのコメントを外す
    #image: mariadb
    image: jsurf/rpi-mariadb

RaspberryPiのアーキテクチャarmv7l(PCはx86_64)ではmariadbの公開イメージが使用できないため、大体のイメージを使用

wsgi.conf内、LoadModule参照先変更

  • wsgi.confファイル内、x86_64用のLoadModule行(2行目)をコメントアウトして、armv7l用のLoadModule行(4行目)のコメントを外す
# LoadModule for x86_64
#LoadModule wsgi_module /usr/local/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
# LoadModule for armv7l(raspi)
LoadModule wsgi_module /usr/local/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-arm-linux-gnueabi.so

Djangoプロジェクト側の設定

Djangoプロジェクト側の設定ファイル(setting.py)も編集する必要があります。

[django-project]/[django-project]/setting.pyの編集

受付ホスト名の設定

  • 構築環境にリモートからアクセスする場合、Listenホストを設定します。
ALLOWED_HOSTS = ['0.0.0.0','localhost']

DB設定

  • engineのmariadbへの設定、docker-compose.ymlで定義したDB側設定、HOST名、PORT番号の指定。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'NAME': '[mariadb-db-name]',
        'USER': '[mariadb-user-name]',
        'PASSWORD': '[mariadb-user-password]',
        'HOST': 'db',
        'PORT': '3306',
    }
}
  • このWeb+Djangoコンテナ側からはホスト名’db’としてアクセスする必要がある。

  • ちなみにコンテナ外からは’db’というホスト名でDBコンテナにアクセスすることはできません。

コメント