前回の軽いあらすじ
前回は
- ✅Nginxのコンテナ化(フロントエンド)
- ✅Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)
を実施した。
今回やること
今回はバックエンド側のコンテナ実装を行う。
- ◻️Djangoのコンテナ化(バックエンド)
- ◻️mysqlのコンテナ化(バックエンド)
を行っていく。
良かったら今回アップデートする対象の僕が作成したwebサービスを使ってみてね!
docker compose
ディレクトリ構成
ディレクトリ構成は以下。
$ tree -L 3
.
├── db
│ ├── Dockerfile
│ ├── dml
│ │ └── sightseeing.csv
│ ├── init.sql
│ └── my.cnf
├── django
│ ├── Dockerfile
│ ├── django_project
│ │ ├── ・・・【略】・・・
│ ├── entrypoint.sh
│ └── requirements.txt
├── docker-compose.yml
├── nginx
│ ├── conf.d
│ │ └── default.conf
│ └── dist
│ └── index.html
└── vue
├── Dockerfile
└── frontend
├── README.md
├── babel.config.js
├── jsconfig.json
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
└── vue.config.js
ハイライトしてある部分は今回の実装部分。
django_projectの下の【略】のところは、Djangoのプロジェクトに関するファイルなので、割愛している。
docker-compose.yml
docker-compose.ymlは以下。
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: nginx-container
restart: always
ports:
- "80:80"
- "443:443"
environment:
TZ: "Asia/Tokyo"
volumes:
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- frontend
- backend
frontend:
container_name: frontend-container
build:
context: ./vue
dockerfile: ./Dockerfile
ports:
- 8080:8080
volumes:
- ./vue/frontend:/app
working_dir: /app
tty: true
command: sh -c "HOST=0.0.0.0 npm run serve"
depends_on:
- backend
backend:
container_name: backend-container
build:
context: ./django
dockerfile: ./Dockerfile
restart: always
ports:
- "8000:8000"
command: sh -c "/code/entrypoint.sh"
volumes:
- ./django/entrypoint.sh:/code/entrypoint.sh
- ./django/django_project:/code
depends_on:
db:
condition: service_healthy
db:
container_name: db-container
build:
context: ./db
dockerfile: ./Dockerfile
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=test_db
- MYSQL_USER=test_user
- MYSQL_PASSWORD=test_passwd
- ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
- DEBUG=True
ports:
- 3306:3306
volumes:
- ./db/dml:/tmp/dml
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u$$MYSQL_USER -p$$MYSQL_PASSWORD
interval: 10s
timeout: 10s
retries: 4
# ヘルスチェックが失敗しても無視する時間は30秒
start_period: 30s
ハイライトしてある部分は今回の実装部分。
Django
DjangoのDockerfileは以下
FROM python:3.8
# PYTHONDONTWRITEBYTECODEとPYTHONUNBUFFEREDはオプション
# pycファイル(および__pycache__)の生成を行わないようにする
ENV PYTHONDONTWRITEBYTECODE=1
# 標準出力・標準エラーのストリームのバッファリングを行わない
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY ./requirements.txt /code/
RUN apt-get update && apt-get install -y tzdata \
libgdal-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal"
COPY ./django_project/code/
COPY ./entrypoint.sh /code/
RUN chmod 755 entrypoint.sh
entrypoint.shは以下
#!/bin/sh
python manage.py makemigrations --noinput
python manage.py migrate --noinput
python manage.py collectstatic --noinput
gunicorn --bind 0.0.0.0:8000 django_project.wsgi
requirements.txtは以下(インストールをするもの)
Django==4.1.4
django-hosts==5.1
django-leaflet==0.28.3
mysql-connector-python==8.0.29
mysqlclient==2.1.1
gunicorn==20.1.0
fontawesomefree==6.3.0
djangorestframework==3.14.0
requests==2.31.0
whitenoise==6.6.0
django-cors-headers==4.3.1
ハマりがちなポイント
👹Can’t connect to local server through socket ‘/run/mysqld/mysqld.sock’ (2)
以下のようなエラー出ませんでした?
2002, "Can't connect to local server through socket '/run/mysqld/mysqld.sock' (2)"
今回はDjangoがmysqlに接続を試みようとして失敗している様子。
これはもしかしたらDjangoのsettings.pyの以下の設定をしていないのかもしれない。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test_db',
'USER': 'test_user',
'PASSWORD': 'test_passwd',
'HOST': 'db',
'OPTIONS': {
'charset': 'utf8mb4',
},
}
}
ハイライトのところをdocker-compose.ymlで設定したDBのサービスの名前を指定する。
今回だと「db」
dockerだと意外に忘れてしまっている変更箇所なのだと思う。
mysql(DB)
mysqlのDockerfileは以下
FROM mysql:8.0.35
COPY ./my.cnf /etc/mysql/conf.d/my.cnf
COPY ./init.sql /docker-entrypoint-initdb.d
my.cofは以下
[mysqld]
character_set_server=utf8mb4
collation_server=utf8mb4_bin
local-infile=1
socket=/run/mysqld/mysqld.sock
default_time_zone=SYSTEM
log_timestamps=SYSTEM
# MySQL8.0以上用のデフォルト認証プラグインの設定
default_authentication_plugin=caching_sha2_password
[mysql]
default_character_set=utf8mb4
local-infile=1
# mysqlクライアントツールの設定
[client]
default_character_set=utf8mb4
init.sqlは以下
GRANT all ON *.* TO test_user@'%';
uSE django_db;
SET GLOBAL local_infile = 1;
SHOW VARIABLES LIKE 'local_infile';
CREATE TABLE `my_table` (【略】);
LOAD DATA LOCAL INFILE '/tmp/dml/sightseeing.csv' INTO TABLE `my_table` FIELDS TERMINATED BY ',' ENCLOSED BY '"' IGNORE 1 LINES;
【略】のところは作成するテーブルのカラムを設定している。
個々で設定するところなので、今回は省略している。
ハマりがちなポイント
👹ERROR 3948 (42000): Loading local data is disabled; this must be enabled on both the client and server sides
以下のようなエラー出ませんでした?
ERROR 3948 (42000): Loading local data is disabled; this must be enabled on both the client and server sides
これはコマンドで解消できると調べるとでてくる。
でも、今回はDockerを使っていることもあって、上記ファイル内で解決している。
my.cnfだと以下のハイライトの部分(クライアント側の設定)
[mysqld]
character_set_server=utf8mb4
collation_server=utf8mb4_bin
local-infile=1
・・・【略】・・・
[mysql]
default_character_set=utf8mb4
local-infile=1
・・・【略】・・・
init.sqlは以下のところ(サーバ側の設定)
・・・【略】・・・
SET GLOBAL local_infile = 1;
・・・【略】・・・
参考:
MySQL – CSVファイルのインポートでエラー – TauStation
MySQL5で「LOAD DATA LOCAL INFILE」でエラーを解決。 | colori (colo-ri.jp)
今回討伐したエラー
- 2002, “Can’t connect to local server through socket ‘/run/mysqld/mysqld.sock’ (2)”
- ERROR 3948 (42000): Loading local data is disabled; this must be enabled on both the client and server sides
まとめ
今回は
- ✅Djangoのコンテナ化(バックエンド)
- ✅mysqlのコンテナ化(バックエンド)
を対応。
これで対応したものは以下のようになった。(✅の項目が対応済みのもの)
- ✅DjangoとVue.jsとの接続確認
- ✅Nginxのコンテナ化(フロントエンド)
- ✅Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)
- ✅Djangoのコンテナ化(バックエンド)
- ✅mysqlのコンテナ化(バックエンド)
- ◻️証明書の自動更新
- ◻️Vue CLIの設定
- ◻️vue-leafletの実装
次回は今回のアップデートの中核とも言える
- ◻️証明書の自動更新
- ◻️Vue CLIの設定
- ◻️vue-leafletの実装
を対応したいと思う。
(やっとここまできた…。)
僕も使っている、SakuraのVPSサーバー。この記事のサービスもこのVPSサーバーで動いています。👇
ドメインはこちらでも取得可能!👇