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

はじめに

こんにちは、SHOJIです。


今回は、前回作成したDjango & PostgreSQLの環境にApacheを追加します。Apacheは前回に引き続きDockerのコンテナとして追加します。


前回の記事はこちら。

deadline-driven-developer.hatenablog.com

Apacheコンテナを追加してDjangoと連携する

ディレクトリ構成を変更する

前回、このような構成だったディレクトリを

# 前回の構成(runコマンド実行前)
.
├── Dockerfile
├── docker-compose.yml
└── requirements.txt

# 前回の構成(コンテナ起動後)
.
├── Dockerfile
├── composeexample
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── data
│   └── db
│       └── ...
├── docker-compose.yml
├── manage.py
└── requirements.txt

次のように変更する。変更する理由は、Apache用のDockerfileを一つ追加したいのと、各種ファイルがどのイメージのために存在するのかを分かりやすくするため。

# 前回の構成(runコマンド実行前)
.
├── app
│   ├── Dockerfile (Python)
│   └── requirements.txt
├── db
├── docker-compose.yml
└── web
    ├── Dockerfile (Apache)
    └── httpd.conf

# 前回の構成(コンテナ起動後)
.
├── app
│   ├── Dockerfile
│   ├── composeexample
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── manage.py
│   └── requirements.txt
├── db
│   └── data
│       └── ...
├── docker-compose.yml
└── web
    ├── Dockerfile
    └── httpd.conf
  1. 前回の構成(runコマンド実行前)の状態にする。

  2. appディレクトリを作成する。

  3. Dockerfileとrequirements.txtをappディレクトリに移動する。

  4. dbディレクトリを作成する。

  5. webディレクトリを作成する。

    # 現在のディレクトリの状態
    .
    ├── app
    │   ├── Dockerfile (Python)
    │   └── requirements.txt
    ├── db
    ├── docker-compose.yml
    └── web
    

Python実行環境のインストール対象にuWSGIを追加する

  1. app/requirements.txtを編集する。

    Django>=3.0,<4.0
    psycopg2>=2.8
    uWSGI>=2.0.20
    

webディレクトリにApache用ファイルを作成する

  1. webディレクトリ内にDockerfileを作成する。

    このDockerfileをビルドすると、①ローカル環境のhttpd.confでコンテナ内のhttpd.confを上書き、が行われる。

    FROM httpd:2.4
    COPY ./httpd.conf /usr/local/apache2/conf/httpd.conf
    
  2. webディレクトリ内にApacheイメージから取得したhttpd.confを格納する。

    docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > ./web/httpd.conf
    
  3. web/httpd.confを編集する。

    Apacheで受けたアクセスをuWSGIへ受け渡すため、リバースプロキシの設定を有効にする。 ProxyPassにはコンテナを動かしているCentOSIPアドレスを設定する。今回はdocker-compose.ymlで定義したIPアドレスを使用するべく、環境変数を設定している。

    # httpd.conf
    [...]
    # コメントアウトを解除する
    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    [...]
    ProxyRequests Off
    ProxyPass / http://${IPADDRESS}:8000/
    ProxyPassReverse / http://${IPADDRESS}:8000/
    # EOL
    
    # 現在のディレクトリの状態
    .
    ├── app
    │   ├── Dockerfile (Python)
    │   └── requirements.txt
    ├── db
    ├── docker-compose.yml
    └── web
        ├── Dockerfile (Apache)
        └── httpd.conf
    

docker-compose.ymlの設定

  1. docker-compose.ymlを編集する。

    このdocker-composeをアップすると

    version: "3.9"
    services:
      db:
        image: postgres
        volumes:
          # - ./data/db:/var/lib/postgresql/data
          - ./db/data:/var/lib/postgresql/data
        environment:
          - POSTGRES_DB=postgres
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
      # web:
      app:
        # build: .
        build:
          context: ./app
          dockerfile: ./Dockerfile    
        command: uwsgi --http 0.0.0.0:8000 --chdir /code/ --wsgi-file ./composeexample/wsgi.py
        volumes:
          # - .:/code
          - ./app:/code
        ports:
          - "8000:8000"
        environment:
          - POSTGRES_NAME=postgres
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
        depends_on:
          - db
      # 以下、Apache用の設定を追加
      web:
        build:
          context: ./web
          dockerfile: ./Dockerfile
        ports:
          - "8080:80"
        environment:
          - IPADDRESS
        depends_on:
          - app
    

Djangoプロジェクトの生成とサービスの起動

  1. 環境変数「IPADDRESS」にCentOSIPアドレスを設定する。

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

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

    sudo chown -R $USER:$USER ./app/composeexample
    
  4. 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,
        }
    }
    
  5. サービスを起動する。

    docker-compose up
    
  6. ブラウザでhttp://[CentOS IP address]:8080にアクセスできれば完了。
    uWSGIも起動しているため、http://[CentOS IP address]:8000からもアクセスできる。この場合はApacheを介さないアクセスになる。

おわりに

今回はApacheコンテナを追加してDjangoと連携するところまで行いました。


ここからさらにDjango REST FrameworkとReactを導入してSPAの環境構築もやりたかったのですが、キリがいいので一旦終わりにしようと思います。また気持ちが乗ったタイミングで再開します。