Django + MySQL を Docker で構築してユーザー登録する手順
はじめに
本記事では、ユーザー登録機能を持つ仮想Webアプリケーションを作成しました。
環境は Docker Compose 上で Django(Webフレームワーク)と MySQL(データベース)を連携させて構築しています
この構成により、アプリケーションとデータベースを分離し、ローカル環境に依存しない開発環境を再現できます。
ユーザー登録フォームを作成し、入力したデータが MySQL に保存されることを確認するところまでをまとめています
環境
- Docker / Docker Compose
- Python 3.12
- Django 5.0
- MySQL 8.3
エディタはVSCodeで、Docker拡張機能を使用しています
作業手順
1. Django 環境の構築
- Dockerfile と docker-compose.yml を用意して、Django コンテナ(web)を作成
- Python と必要なパッケージ(Django など)をインストール
- Django プロジェクトを新規作成(例:myproject)
2. MySQL データベースの構築
- docker-compose.yml 内で MySQL コンテナ(db)を設定
- 永続化用のボリュームを作成
- settings.py で Django と MySQL を接続
- migrate コマンドで初期テーブルを作成
3. アプリの作成とユーザー登録機能の実装
- Django アプリ(例:accounts)を作成
- models.py にユーザーモデルを定義
- forms.py にユーザー登録フォームを作成
- views.py と urls.py を設定してフォーム画面を表示
- 登録フォームから入力したデータが MySQL に保存されることを確認
4. 動作確認
- コンテナを起動 (docker compose up)
- ブラウザで http://localhost:8000 にアクセス
- ユーザー登録画面からフォーム送信
- MySQL コンテナ内で登録データを確認 (SELECT * FROM users;)
プロジェクト構成
アプリ作成後のディレクトリ構造は以下のようになります
app/
├─ docker-compose.yml
├─ Dockerfile
├─ requirements.txt
├─ djangopj/
│ ├─ __init__.py
│ ├─ asgi.py
│ ├─ settings.py ← Django全体の設定(DB接続など)
│ ├─ urls.py ← ルーティング設定
│ ├─ wsgi.py
├─ core/
│ ├─ __init__.py
│ ├─ admin.py
│ ├─ apps.py
│ ├─ models.py ← 今回は空でもOK
│ ├─ views.py ← signup・dashboardを記述
│ ├─ tests.py
│ ├─ migrations/
│ └─ __init__.py
├─ templates/
│ ├─ signup.html
│ ├─ login.html
│ └─ dashboard.html
└─ static/
└─ images/
├─ img1.jpg
├─ img2.jpg
├─ img3.jpg
├─ img4.jpg
└─ img5.jpg
-
djangopj/
:プロジェクト全体の設定をまとめる場所 -
core/
:実際のアプリロジックを記述(views.pyなど) -
templates/
:HTMLテンプレート置き場 -
static/
:CSS・画像などの静的ファイル置き場
Django環境作成手順
webコンテナ(Django)とdbコンテナ(MySQL)のコンテナを立てます
1. 作業ディレクトリを作成
まずは開発用のディレクトリを作成します
mkdir app
cd app
2.必要ファイルを準備
以下の3つを用意します。
docker-compose.yml
-
Dockerfile
(web用) requirements.txt
docker-compose.yml
services:
db:
image: mysql:8.3
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: django-db
MYSQL_USER: django
MYSQL_PASSWORD: django
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Dockerfile
FROM python:3.12.4
ENV PYTHONUNBUFFERED=1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip && pip install -r requirements.txt
COPY . /code/
requirements.txt
Django==5.0
mysqlclient
3. Djangoプロジェクト作成
docker compose run web django-admin startproject djangopj .
djangopj/settings.pyを編集してMySQLに接続できるようにします
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django-db',
'USER': 'django',
'PASSWORD': 'django',
'HOST': 'db',
'PORT': '3306'
}
}
4. マイグレーション
マイグレーションを行いMySQLとの接続を行います
docker compose run web python manage.py migrate
5. コンテナ起動
コンテナを立ち上げサイトにアクセスできるか確認します
docker compose up -d
コンテナが立ち上がったら
http://localhost:8000 にアクセスし、以下の画面が表示されるか確認します
6. MySQLにDjango用のDBが作られているかを確認します
6.1. DBコンテナの中に入ります
docker exec -it form-db-1 bash
6.2. MySQLにログインします
mysql -u root -proot
6.3. DBを確認します
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| django-db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
django-dbが作成されていることを確認できました
アプリ作成
ここからは、Django プロジェクトにアプリを追加し、ユーザー登録フォームを作成して実際に MySQL に保存されるところまでを確認します
1. アプリ作成
Django プロジェクト直下にcore
という名のアプリを作成します
docker compose exec web python manage.py startapp accounts core
djangopj/settings.py
に設定を追加します
2. 2.1. INSTALLED_APPS
に追加します
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core', # ← 追加
]
2.2. テンプレートの場所を指定します
プロジェクト直下のtemplates/
を優先して読むための設定です
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"], # プロジェクト共通テンプレート
"APP_DIRS": True, # 各アプリ内の templates/ も読む
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
2.3. 認証時のリダイレクト先
LOGIN_URL = "login"
LOGIN_REDIRECT_URL = "dashboard"
LOGOUT_REDIRECT_URL = "login"
- ログインページのURL名
- ログイン後/ログアウト後に飛ばす先のURL名
2.4. 静的ファイルの配信
BASE_DIR / "static"
を追加して静的ファイルの保存先を作成します
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
2.5. 言語・タイムゾーン
- 日本語・日本時間で表示
-
USE_TZ=True
でDBはUTC、表示は Asia/Tokyo に変換
LANGUAGE_CODE = "ja"
TIME_ZONE = "Asia/Tokyo"
USE_I18N = True
USE_TZ = True
3. URLを紐づける
djangopj/urls.py
にアプリをインクルードします
ここではログイン・ログアウト・新規登録・トップページ のURLを設定しています
from django.contrib import admin
from django.urls import path
from django.contrib.auth import views as auth_views
from core import views as core_views
urlpatterns = [
path("admin/", admin.site.urls),
path("login/", auth_views.LoginView.as_view(template_name="login.html"), name="login"),
path("logout/", auth_views.LogoutView.as_view(), name="logout"),
path("signup/", core_views.signup, name="signup"),
path("", core_views.dashboard, name="dashboard"),
]
core/views.py
の編集
4. ユーザー登録の仕組みフォームの送信処理とページ表示を行うビューを追加します
import random
from datetime import timedelta
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
@login_required
def dashboard(request):
now = timezone.localtime()
# static/images 内のファイル名
images = [
"images/img1.jpg",
"images/img2.jpg",
"images/img3.jpg",
"images/img4.jpg",
"images/img5.jpg",
]
random_image = random.choice(images)
return render(request, "dashboard.html", {
"now": now,
"random_image": random_image,
})
def signup(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save() # ユーザー作成
return redirect("login") # 登録後はログイン画面へ
else:
form = UserCreationForm()
return render(request, "signup.html", {"form": form})
5. テンプレートを用意する
templates/
├─ signup.html
├─ login.html
└─ dashboard.html
各ページにアクセスしたときに表示されるページを作成します
5.1. templates/dashboard.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ダッシュボード</title>
</head>
<body>
<h1>ダッシュボード</h1>
<p>{{ user.username }} さん、ログイン中です。</p>
<p>現在時刻: {{ now|date:"Y-m-d H:i:s" }}</p>
<img src="/static/{{ random_image }}" alt="random image" style="max-width:400px;">
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button type="submit">ログアウト</button>
</form>
</body>
</html>
5.2. templates/login.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
{% if form.errors %}
<p style="color: red;">ユーザー名またはパスワードが間違っています。</p>
{% endif %}
<form method="post">
{% csrf_token %}
<p>
<label for="id_username">ユーザー名:</label>
{{ form.username }}
</p>
<p>
<label for="id_password">パスワード:</label>
{{ form.password }}
</p>
<button type="submit">ログイン</button>
</form>
<p>アカウント未作成ですか?
<a href="{% url 'signup' %}">新規登録はこちら</a>
</p>
</body>
</html>
5.3. templates/signup.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>新規登録</title>
</head>
<body>
<h1>新規登録</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">登録</button>
</form>
<p>すでにアカウントをお持ちですか?
<a href="{% url 'login' %}">ログインはこちら</a>
</p>
</body>
</html>
6. static(画像を配置する)
static/
images/
img1.jpg
img2.jpg
img3.jpg
img4.jpg
img5.jpg
画像ファイル名はviews.py
の配列 と一致させること
動作確認
docker compose exec web python manage.py migrate
docker compose up -d
http://localhost:8000/ にアクセス
-
/signup/
→ ユーザー登録 -
/login/
→ ログイン -
/
→ ダッシュボード(時刻+ランダム画像)
ブラウザで上記ページが表示されれば成功です
MySQLでユーザー情報を確認
web上で作成したアカウントがMySQLに保存されているかを確認します
docker exec -it form-db-1 bash
mysql -u root -proot
use django-db;
SELECT id, username, date_joined FROM auth_user;
出力例:
+----+----------+---------------------+
| id | username | date_joined |
+----+----------+---------------------+
| 1 | testuser | 2025-10-09 12:34:56 |
+----+----------+---------------------+
まとめ
本記事では、以下の内容を実装しました:
- Django + MySQL + Docker 環境構築
- ユーザー登録/ログイン機能の実装
- MySQLにユーザーデータが保存されることの確認
Discussion