「スマホでも使いやすいようにVeu.jsを導入、ついでにコンテナ化 その③ バックエンド」わたしのWebサービス開発日記 #15

スポンサーリンク
個人開発
スポンサーリンク

前回の軽いあらすじ

前回は

  • ✅Nginxのコンテナ化(フロントエンド)
  • ✅Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)

を実施した。

今回やること

今回はバックエンド側のコンテナ実装を行う。

  • ◻️Djangoのコンテナ化(バックエンド)
  • ◻️mysqlのコンテナ化(バックエンド)

を行っていく。

良かったら今回アップデートする対象の僕が作成したwebサービスを使ってみてね!

map

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サーバーで動いています。👇

ドメインはこちらでも取得可能!👇

タイトルとURLをコピーしました