【Docker】Django×MySQL×Nginxの selenium入りDockerfile構成
- 2020.11.21
- サーバーサイド
- Django, Docker, MySQL, python, selenium, さくらインターネット, ひとりごと, ヘッドレスchrome, 仕様, 備忘録, 構成, 自作システム
【Docker】Django×MySQL×Nginxの selenium入りDockerfile構成
Docker構築で必要なファイルは6ファイルです。※構築は『さくらインターネットVPS』で行いました。
- pythonのドッカーファイル
- pythonの依存パッケージを記載したrequirements.txt
- MySQLのドッカーファイル
- MySQLの初期設定init
- Nginxのコンフィグ
- Nginxのuwsgi_params(いわゆるおまじない)
- docker-compose.yml
フォルダ構成はこんな感じにしました。
├── 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のドッカーファイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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
1 2 3 4 5 6 |
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のドッカーファイル
1 2 3 |
FROM mysql:5.7 COPY init.d/* /docker-entrypoint-initdb.d/ |
最終的に超シンプルになりました。わざわざDockerfileで構成しなくてもよかった感じですが、ここに至る過程があったのでとりあえずDockerfile で上げました。
MySQLの初期設定init
1 2 3 4 |
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のコンフィグ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
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のプロジェクトが存在する場合
既にプロジェクトがある場合は、プロジェクトを所定のディレクトリに配置します。
├── static/ # Djangoで読み込ませる固定フォルダ
└── entrypoint
└── db/ # Django_db他生成されるフォルダやファイル
配置が終わったらDockerプロジェクトを起動します。
1 |
sudo /usr/local/bin/docker-compose up -d --build |
Djangoのプロジェクトが存在しない場合
プロジェクトが無い場合は先に下記手順でプロジェクトの用意を行います。
- Djangoプロジェクトを作成する
- プロジェクト名\settings.pyを変更する
- Djangoの基本データベース構築(Django管理ツールに入る為の構成)
- Djangoの管理者ユーザー作成
- 静的ファイルをコピー
Djangoプロジェクトを作成する
『※1~7』の構成が終わるとDockerコンテナが作れる状態になっています。
このまま起動するとDjangoは存在しないので「指示したポートにデータが無い」としてnginxが落ちたり404エラーを吐いたりします。
その為、まず起動準備としてDjangoのデータを用意します。
- pythonコンテナを起動する
- pythonコンテナの中に入る
- pythonコンテナ内でstartprojectコマンドを実行
pythonコンテナを起動する
1 |
sudo /usr/local/bin/docker-compose up -d python |
pythonコンテナの中に入る
コンテナが立ち上がると下のコマンドで中に入れます。
1 |
sudo /usr/local/bin/docker-compose exec python bash |
【 root@ec1f5466b768:/code# 】というように表示が変わったらコンテナに無事はいれてます。
pythonコンテナ内でstartprojectコマンドを実行
カレントフォルダが /code# となっていればそのままでOK。code以外のディレクトリに入るる場合は /codeに移動してからコマンドを実行します。
1 2 3 4 5 |
#code ディレクトリ以外にいる場合はまず移動 cd /code #codeディレクトリに移動したら python django-admin.py startproject プロジェクト名 . |
プロジェクト名は、docker-compose.yml 39行目のものと同じ名称にします。
プロジェクト名\settings.pyを変更する
ここまででプロジェクトの基礎データが【Django_Docker\project】内に自動生成されています。
具体的にはこんな感じで構成されている事でしょう。
│
(中略)
├── 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を編集します。
1 2 |
#vimで開く vim /code/プロジェクト名/settings.py |
【project\プロジェクト名\settings.py】がvimで開いたら、この中の項目【DATABASES】を修正します。具体的には初期値として登録されているを削除してmysqlの接続を登録します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 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の基礎テーブルが生成されます。
1 2 |
#注:まだコンテナ内の作業です。 python ./manage.py migrate |
成功すると『django_db、mysql、performance_schema、etc』など複数のディレクトリとファイルが生成されます。
Djangoの管理者ユーザー作成
Djangoの基礎構成はここまでで完了していますが、まだDjango管理ツールにログインする事は出来ません。
下のコマンドで管理者の登録を開始します。
1 2 |
#注:まだコンテナ内の作業です。 python ./manage.py createsuperuser |
実行すると『ユーザー名、メールアドレス、パスワード』の3点を訪ねてくるので解答します。
静的ファイルをコピー
1 2 |
#注:まだコンテナ内の作業です。 python ./manage.py collectstatic |
このコマンドを実行すると、staticフォルダにadminというフォルダを含め下のような姿になります。
Django_Docker
│
(中略)
├── static/
│ └── admin/
│ ├─── css/
│ │ ├─── vendor/
│ │ ├─── autocomplete.css
│ │ ├─── base.css
│ │ (以下略)
│ ├─── fonts/
│ ├─── img/
│ └─── js/
(中略)
└─── db/
CSSやimageなどの固定ファイルはここに収めていく事になります。
下準備終わり、コンテナから抜けてDockerプロジェクトを起動する
1 2 3 4 5 |
#コンテナから抜ける exit #コンテナから抜けてから実行 sudo /usr/local/bin/docker-compose up -d --build |
これで無事にDjangoプロジェクトが起動したと思います。
まとめ
何とかDocker×Djangoが起動しました。書き方も大体覚えてきたし、あとは実践の積み重ねです。
-
前の記事
Docker:コンテナ起動エラーの理由を調べる方法 2020.11.20
-
次の記事
【Django】django.core.exceptions.FieldError: Unknown field(s) () specified for 2020.11.25
コメントを残す