TiDBローカル環境構築④
TiDBのローカル環境の構築を4回目行なっていきます。
前回DB環境の構築が出来たましたが、今回はDockerでTiDBに繋いだDjango環境を行っていきます。
コンテナ環境のツリー構成
今回追加するのはwwwフォルダ配下とルートのdocker-compose.ymlにAPI用のコンテナ操作を追加します。
ツリー構成は以下になります。
.
├── docker-compose.yml
├── .env.api
└── src
├── infra
│ └── db
│ ├── Dockerfile
│ ├── data
│ │ └── test_db.sql
│ ├── docker-compose.yml
│ └── entrypoint.sh
└── www
└── api
├── Dockerfile
├── docker-compose.yml
├── project
│ ├── manage.py
│ └── project
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ ├── settings.cpython-311.pyc
│ │ ├── urls.cpython-311.pyc
│ │ └── wsgi.cpython-311.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── requirements.txt
ソースコードを作成
ルートのdocker-compose.ymlを編集します。
services:
tiup-playground:
extends:
file: ./src/infra/db/docker-compose.yml
service: tiup-playground
api:
extends:
file: ./src/www/api/docker-compose.yml
service: api
depends_on:
- tiup-playground
networks:
tidb-net:
name: tidb-net
driver: bridge
APIコンテナ用のdocker-compose.ymlの作成を行います。
TiDBのコンテナと連携しています。
services:
api:
build:
context: .
dockerfile: Dockerfile
env_file:
- ../../../.env.api
container_name: ubuntu-dev-container
stdin_open: true
tty: true
ports:
- "8000:8000"
depends_on:
- tiup-playground
volumes:
- .:/app
- /app/node_modules
command: python manage.py runserver 0.0.0.0:8000
networks:
- tidb-net
networks:
tidb-net:
external: true
API環境設定ファイルを作成します。
DJANGO_SECRET_KEY=devsecret
DJANGO_DEBUG=1
DJANGO_ALLOWED_HOSTS=*
DB_ENGINE=django.db.backends.mysql
DB_NAME=test
DB_USER=root
DB_PASSWORD=
DB_HOST=tiup-playground
DB_PORT=4000
python環境でDjangoコンテナ環境を構築します。
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
default-libmysqlclient-dev \
gcc \
pkg-config \
default-mysql-client
WORKDIR /app/project
COPY requirements.txt .
RUN python -m venv /venv
RUN /venv/bin/pip install --no-cache-dir -r requirements.txt
ENV PATH="/venv/bin:$PATH"
COPY . .
CMD ["/bin/bash"]
Django 4.2系でREST APIを構築し、PyMySQLでMySQL/TiDB接続、python-dotenvで環境変数を管理するための依存パッケージ定義します。
Django>=4.2,<4.3
djangorestframework>=3.15
PyMySQL>=1.1
python-dotenv>=1.0
Djangoプロジェクトの manage.py ファイルで、環境変数を設定してからコマンドライン経由で管理コマンドを実行するエントリーポイントを作成します。
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
PyMySQLをMySQLdb互換としてインストールし、DjangoなどMySQLdb依存のコードでも利用できるようにする初期化スクリプトを作成します。
import pymysql
pymysql.install_as_MySQLdb()
DjangoアプリをASGIサーバーで動作させるためのエントリーポイントを定義し、project.settings を読み込む初期設定を行うスクリプトを作成します。
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
Djangoプロジェクト全体の設定(データベース、アプリケーション、ミドルウェア、テンプレート、静的ファイルなど)を管理する構成ファイルを作成します。
from pathlib import Path
import os
from django.db.backends.base.base import BaseDatabaseWrapper
BaseDatabaseWrapper.check_database_version_supported = lambda self: None
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'django-insecure-7$hqwi26z!jmm9-omhajuwy3rop&i)+&@4keai-*y9hzndz4ls'
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'project.wsgi.application'
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": os.getenv("DB_NAME"),
"USER": os.getenv("DB_USER"),
"PASSWORD": os.getenv("DB_PASSWORD"),
"HOST": os.getenv("DB_HOST","tiup-playground"),
"PORT": os.getenv("DB_PORT","4000"),
"OPTIONS": {
"charset": "utf8mb4",
"init_command": "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci'",
},
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_TZ = True
STATIC_URL = 'static/'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DjangoアプリのURLルーティングを定義し、/admin/ にアクセスした際に管理サイトへ接続できるようにする設定ファイルを作成します。
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
DjangoアプリをWSGI互換サーバーで動作させるためのエントリーポイントを定義するファイルの作成を行います。
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
application = get_wsgi_application()
この状態で以下のコマンドを実行します。
docker-compose up -d
以下のURLにアクセスするとDjangoのトップページが確認できました。
詰まった箇所
settings.pyでDatebase設定をする際に、charsetをutf8mb4で定義化していないとエラーになりました。
エラー内容が以下になります。
django.db.utils.OperationalError: (1115, "Unknown character set: 'utf8mb3'")
まとめ
今回は TiDB ローカル環境構築の第4回 として、前回構築した DB 環境に加えて Docker 上で TiDB と接続する Django API 環境 を構築しました。
ルート docker-compose.yml に API サービスを追加し、www/api 配下に Django プロジェクトと関連ファイルを作成。
Django 4.2 系・DRF・PyMySQL・python-dotenv を利用して TiDB に接続し、API 実行環境を整備しました。
起動後に http://127.0.0.1:8000/ にアクセスすると Django のトップページが表示されます。
構築中、settings.py の DB 設定で charset を utf8mb4 にしないとエラーになる 点に注意が必要です。
続きは次回行います。
Discussion