【Docker】Django×MySQL×Nginxの selenium入りDockerfile構成

【Docker】Django×MySQL×Nginxの selenium入りDockerfile構成

Docker構築で必要なファイルは6ファイルです。※構築は『さくらインターネットVPS』で行いました。

  1. pythonのドッカーファイル
  2. pythonの依存パッケージを記載したrequirements.txt
  3. MySQLのドッカーファイル
  4. MySQLの初期設定init
  5. Nginxのコンフィグ
  6. Nginxのuwsgi_params(いわゆるおまじない)
  7. docker-compose.yml

フォルダ構成はこんな感じにしました。

Django_Docker
├── python/
│  ├─── Dockerfile ※1
│  └─── requirements.txt ※2
├── mysql/
│  ├─── Dockerfile ※3
│  └─── init.d/
│    └─── init.sql ※4
├── nginx
│  ├─── uwsgi_params ※5
│  └─── conf/
│    └─── app_nginx.conf ※6
├── docker-compose.yml ※7
├── project/ # Djangoのプロジェクト
│  ├─── プロジェクト名/
│  └─── manage.py
├── static/ # Djangoで読み込ませる固定フォルダ
└── entrypoint
└─── db/ # Django_db他生成されるフォルダやファイル

『※1~7』がコンテナ構成ファイル。『#+メモ』がDjangoプロジェクトの構成ファイルです。

pythonのドッカーファイル

FROM python:3.8-buster

RUN mkdir /code
WORKDIR /code

#code ディレクトリにrequirements.txtの中身を展開、pipでインストール
ADD requirements.txt /code/
RUN pip install --upgrade pip \
    && pip install -r requirements.txt

ADD . /code/

#vim、chromeをインストール
RUN apt update; apt -y upgrade \
  && apt-get install -y vim \
  && apt install -y gnupg \
  && wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
  && wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
  && apt install -y ./google-chrome-stable_current_amd64.deb \
  && apt clean \
  && rm -rf /var/lib/apt/lists/ \
  && rm google-chrome-stable_current_amd64.deb

#インストールしたchromeに合わせたWebDriverをインストール
RUN pip install selenium chromedriver-binary~=$(/usr/bin/google-chrome --version | perl -pe 's/([^0-9]+)([0-9]+\.[0-9]+).+/$2/g')

pythonの依存パッケージを記載したrequirements.txt

asgiref==3.2.7
Django==3.0.5
pytz==2020.1
sqlparse==0.3.1
uwsgi==2.0.18
mysqlclient==1.4.6

対応するパッケージについてはPythonとの依存関係を確認してバージョンを記載します。

MySQLのドッカーファイル

FROM mysql:5.7

COPY init.d/* /docker-entrypoint-initdb.d/

最終的に超シンプルになりました。わざわざDockerfileで構成しなくてもよかった感じですが、ここに至る過程があったのでとりあえずDockerfile で上げました。

MySQLの初期設定init

CREATE DATABASE IF NOT EXISTS django_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS '【MySQLのログインユーザー名】'@'%' IDENTIFIED BY '【MySQLのログインPASS】';
GRANT ALL PRIVILEGES ON django_db.* TO '【MySQLのログインユーザー名】'@'%';
FLUSH PRIVILEGES;

ここに記載するユーザー名は【MySQL】へのログイン用です。Django管理ツールへのログイユーザではありません。

Nginxのコンフィグ

upstream django {
  ip_hash;
  server python:8001;
}

server {
  listen      8000;
  server_name 127.0.0.1;
  charset     utf-8;

  location /static {
    alias /static;
  }
 
  # max upload size
  client_max_body_size 200M;   # adjust to taste 
  location / {
    uwsgi_pass  django;
    include     /etc/nginx/uwsgi_params;
  }
}

server_tokens off;

Pythonコンテナから8001ポートで外に出すときの設定です。

吐き出すポートが違う場合は3行目【server python:8001;】を書き換えます。(例:8080の時は server python:8080;)

7行目はnginxが待ち受けるポート。8行目は基本このままでOK。VPSサーバーのIPに変更する必要はありません。

Nginxのuwsgi_params

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

代り映えのしない定型です。私の様に最後の〆(※;)を忘れるとnginxが起動してくれないので要注意です。

docker-compose.yml

version: '3.7'
services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - 80:80
      - 443:443
    restart: always
    environment:
      DOMAINS: '取得したドメイン -> http://取得したドメイン:8000'
      STAGE: production
    volumes:
      - ./org-chimata-ssl-certs:/var/lib/https-portal

  nginx:
    image: nginx:1.17
    ports:
      - "8000:8000"
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
      - ./static:/static
    depends_on:
      - python

  db: 
    build: ./mysql
    ports:
      - "33306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: パスワード
      TZ: 'Asia/Tokyo'
    volumes:
      - ./mysql/init.d:/docker-entrypoint-initdb.d
      - ./entrypoint/db:/var/lib/mysql

  python:
    build: ./python
    command: uwsgi --socket :起動ポート --module プロジェクト名.wsgi --py-autoreload 1 --logto /tmp/uwsgi.log
    volumes:
      - ./project:/code
      - ./static:/static
    expose:
      - "8001"
    depends_on:
      - db

数回ひかかったところを忘れないために【- "33306:3306"】とmysqlの外側ポートを33306に変更してみました。

Djangoのプロジェクトが存在する場合

既にプロジェクトがある場合は、プロジェクトを所定のディレクトリに配置します。

├── project/ # Djangoのプロジェクト
├── static/ # Djangoで読み込ませる固定フォルダ
└── entrypoint
└── db/ # Django_db他生成されるフォルダやファイル

配置が終わったらDockerプロジェクトを起動します。

sudo /usr/local/bin/docker-compose up -d --build

Djangoのプロジェクトが存在しない場合

プロジェクトが無い場合は先に下記手順でプロジェクトの用意を行います。

  1. Djangoプロジェクトを作成する
  2. プロジェクト名\settings.pyを変更する
  3. Djangoの基本データベース構築(Django管理ツールに入る為の構成)
  4. Djangoの管理者ユーザー作成
  5. 静的ファイルをコピー

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

『※1~7』の構成が終わるとDockerコンテナが作れる状態になっています。
このまま起動するとDjangoは存在しないので「指示したポートにデータが無い」としてnginxが落ちたり404エラーを吐いたりします。
その為、まず起動準備としてDjangoのデータを用意します。

  1. pythonコンテナを起動する
  2. pythonコンテナの中に入る
  3. pythonコンテナ内でstartprojectコマンドを実行
pythonコンテナを起動する
sudo /usr/local/bin/docker-compose up -d python
pythonコンテナの中に入る

コンテナが立ち上がると下のコマンドで中に入れます。

sudo /usr/local/bin/docker-compose exec python bash

【 root@ec1f5466b768:/code# 】というように表示が変わったらコンテナに無事はいれてます。

pythonコンテナ内でstartprojectコマンドを実行

カレントフォルダが /code# となっていればそのままでOK。code以外のディレクトリに入るる場合は /codeに移動してからコマンドを実行します。

#code ディレクトリ以外にいる場合はまず移動
cd /code

#codeディレクトリに移動したら
python django-admin.py startproject プロジェクト名 .

プロジェクト名は、docker-compose.yml 39行目のものと同じ名称にします。

プロジェクト名\settings.pyを変更する

ここまででプロジェクトの基礎データが【Django_Docker\project】内に自動生成されています。
具体的にはこんな感じで構成されている事でしょう。

Django_Docker
│
(中略)
├── project/
│   ├── プロジェクト名/
│   │    ├─── __pycache__/
│   │    │      ├─── __init__.cpython-38.pyc
│   │    │      ├─── settings.cpython-38.pyc
│   │    │      ├─── urls.cpython-38.pyc
│   │    │      └─── wsgi.cpython-38.pyc
│   │    ├─── __init__.py
│   │    ├─── settings.py
│   │    ├─── urls.py
│   │    └─── wsgi.py
│   └── manage.py
(中略)
└─── db/

これらは全て基礎設定ファイルです。
Djangoの初期画面を出力するにはまずsettings.pyを編集します。

#vimで開く
vim /code/プロジェクト名/settings.py

【project\プロジェクト名\settings.py】がvimで開いたら、この中の項目【DATABASES】を修正します。具体的には初期値として登録されているを削除してmysqlの接続を登録します。

# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.sqlite3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'MYSQLログインユーザー',
        'PASSWORD': 'MYSQLログインパスワード',
        'PORT': '3306',
        'HOST': 'db',
    }
}
(中略)
# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = '/static/'

注意点はPORTの設定です。
docker-compose.ymlではSQLの出口を33306に変えましたが、ここでは【33306】ではなく【3306】の標準ポートを指定します。
理由は33306は外部との連携に利用されるポートであってDocker内部では3306が利用されているからです。これを33306とした場合、DjangoからMySQLが見えなくなりDBログインエラーが発生します。

最後の行に追加したのはstaticファイルのパスです。
Laravelでは固定ファイルはLaravelプロジェクト内に設置されますが、Djangoでは設置場所の初期値がありません。AWSなんかではこれが逆に使いやすくて良いのですが、今回は『さくらのVPS』で行っているのでDocker構成ファイル内に設置しておきます。

Djangoの基本データベース構築(Django管理ツールに入る為の構成)

この段階ではまだ【entrypoint\db】は空っぽの状態です。下のコマンドを打つとdbディレクトリ内にDjangoの基礎テーブルが生成されます。

#注:まだコンテナ内の作業です。
python ./manage.py migrate

成功すると『django_db、mysql、performance_schema、etc』など複数のディレクトリとファイルが生成されます。

Djangoの管理者ユーザー作成

Djangoの基礎構成はここまでで完了していますが、まだDjango管理ツールにログインする事は出来ません。
下のコマンドで管理者の登録を開始します。

#注:まだコンテナ内の作業です。
python ./manage.py createsuperuser

実行すると『ユーザー名、メールアドレス、パスワード』の3点を訪ねてくるので解答します。

静的ファイルをコピー

#注:まだコンテナ内の作業です。
python ./manage.py collectstatic

このコマンドを実行すると、staticフォルダにadminというフォルダを含め下のような姿になります。

Django_Docker
│
(中略)
├── static/
│  └── admin/
│       ├─── css/
│       │      ├─── vendor/
│       │      ├─── autocomplete.css
│       │      ├─── base.css
│       │    (以下略)
│       ├─── fonts/
│       ├─── img/
│       └─── js/
(中略)
└─── db/

CSSやimageなどの固定ファイルはここに収めていく事になります。

下準備終わり、コンテナから抜けてDockerプロジェクトを起動する

#コンテナから抜ける
exit

#コンテナから抜けてから実行
sudo /usr/local/bin/docker-compose up -d --build

これで無事にDjangoプロジェクトが起動したと思います。

まとめ

何とかDocker×Djangoが起動しました。書き方も大体覚えてきたし、あとは実践の積み重ねです。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。