書き直しました!(2019/6/20)
その1とその2に分けて書き直しましたので、こちらへどうぞ!
Django + MySQLの開発環境をDockerでつくる(その1)
Django + MySQLの開発環境をDockerでつくる(その2)
#環境
・macOS Mojave v10.14.3
・Docker v18.09.2
#前提
・Djangoのadminコマンドが使用してプロジェクトおよびアプリの作成ができること
(django-admin startproject プロジェクト名
など)
・Djangoの管理コマンドが使用できること
(python manage.py makemigrations アプリ名
など)
#ディレクトリ構成
※赤字部分をDjangoコンテナにマウントします。
・startprojectコマンドで「docker_django_app」プロジェクトを作成
またその配下にstartappコマンドで「django_app」アプリケーションを作成済み
#docker-compose.yml
・djangoサービス配下の「volumes:」でマウントするディレクトリを指定してます。
コンテナ起動後、コンテナ内の「code」フォルダ配下に指定したディレクトリがマウントされます。(試していませんが、フルパス指定でも大丈夫なはず)
・「build:」に指定したディレクトリ配下のDockerfileがビルドされます。
・DjangoのプロジェクトからmysqlのIPAddressを指定して接続したいので、
固定のIPアドレスが割り振られるようにnetworksを指定してます。
version: '3'
services:
mysql:
image: mysql
env_file: ./mysql/.env_sample
command: --default-authentication-plugin=mysql_native_password
ports:
- "3306:3306"
networks:
app_net:
ipv4_address: 172.20.0.3
depends_on:
- django
django:
build: ./django
ports:
- "8000:8000"
volumes:
- ./docker_django_app:/code
networks:
app_net:
ipv4_address: 172.20.0.2
tty: true
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/24
volumes:
est-data:
#Dockerfile
WORKDIRにディレクトリを指定すると、コンテナの作業ディレクトリになるので便利。
(execコマンドなどでコンテナに接続した場合に、ここに指定したディレクトリがカレントディレクトリになる。)
FROM python:3.7.2
ENV LANG en_US.utf8
WORKDIR /code
ADD requirements.txt /code
RUN apt-get update
RUN pip install -r requirements.txt
RUN apt-get install -y mysql-client
#requirements.txt
django==2.1.5
PyMySQL==0.9.3
Pillow
mysqlclient
#.env_sample
「redbull」という名前でDBを作成し、そこにDjangoの管理コマンドでマイグレーションを実行してデータベースを更新する予定です。
MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=redbull
MYSQL_USER=db_user
MYSQL_PASSWORD=password
#settings.py
必要な部分だけ載せてます。
(ユーザーはrootでよかったかも。)
.
..
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_app',# ←作成したアプリケーションを追加しておく
]
...
..
.
DATABASES = {
'default': {
'ENGINE' : 'django.db.backends.mysql'
, 'NAME' : 'redbull'#←.env_sampleで指定したMYSQL_DATABASE
, 'USER' : 'db_user'#←.env_sampleで指定したMYSQL_USER
, 'PASSWORD' : 'password'#←.env_sampleで指定したMYSQL_PASSWORD
, 'HOST' : '172.20.0.3' #←docker-compose.ymlに指定したmysqlのIPAddress
, 'PORT' : '3306'
,
}
}
...
..
.
#manage.py
import os
import sys
import pymysql
.
..
...
#MySql接続
pymysql.install_as_MySQLdb()
#docker-composeでコンテナ起動
まず、cd
コマンドでdocker-compose.ymlファイルがあるディレクトリまで移動しましょう
以下コマンド実行
$ docker-compose up --build -d
最終的に以下のようなメッセージが出ていれば起動できている。
.
..
...
Creating docker_django_django_1 ... done
Creating docker_django_mysql_1 ... done
こんなエラーメッセージが表示された場合、すでに作成済みのコンテナのIPAddress空間や、ホストのIPAddress空間と重複している可能性があるので、docker-compose.ymlに指定した「networks:」の「subnet」を違うアドレスに変更してみてください。
Pool overlaps with other one on this address space
コンテナが起動しているか確認。
・STATUSが「Up...」になっていたら起動している。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9ebfd9bb1af1 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp docker_django_mysql_1
2bdd7ef8dbee docker_django_django "python3" 2 minutes ago Up 2 minutes 0.0.0.0:8000->8000/tcp docker_django_django_1
#コンテナで起動したDjangoの起動画面をホストのブラウザから確認
作成したDjangoコンテナが標準入力を受け入れられるようにします。
$ docker exec -it docker_django_django_1 /bin/bash
root@~:/code#
カレントディレクトリはDockerfileのWORKDIR
に指定したディレクトリ(/code)になっている。
一覧を確認
ディレクトリ構成で赤字にした部分がちゃんとマウントされている。
root@~:/code# ls -al
total 144
drwxr-xr-x 7 root root 224 Mar 9 03:18 .
drwxr-xr-x 1 root root 4096 Mar 9 05:40 ..
-rw-r--r-- 1 root root 6148 Mar 6 15:05 .DS_Store
-rw-r--r-- 1 root root 131072 Mar 9 01:25 db.sqlite3
drwxr-xr-x 10 root root 320 Mar 9 02:13 django_app
drwxr-xr-x 7 root root 224 Mar 9 03:18 docker_django_app
-rwxr-xr-x 1 root root 606 Mar 9 01:34 manage.py
root@~:/code#
Djangoのサーバーを起動してホストから接続してみる
.
..
...
root@~:/code# python manage.py runserver 0.0.0.0:8000
Performing system checks...
System check identified no issues (0 silenced).
You have 16 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, django_app, sessions.
Run 'python manage.py migrate' to apply them.
March 09, 2019 - 06:46:34
Django version 2.1.5, using settings 'docker_django_app.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
起動できたので、ホストのブラウザに以下URLを打ち込んでアクセスして、
ロケットが飛んでるWebページが表示されれば成功です。
おめでとうございます。
(Djangoのバージョンによって違うかもしれないですが。)
http://localhost:8000
#マイグレーションする(テーブル作成)
コンテナにマウントしているので、ホスト側でソースを編集しても問題ありません。
models.pyを編集しましょう。
(コピペでもよいですし、独自に作っていただいても構いません。)
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
# Create your models here.
'''
お酒テーブル
'''
class Alcohol(models.Model):
product_name = models.CharField(max_length=256)
internal_capacity = models.IntegerField(default=0)
price = models.IntegerField(default=0)
frequency = models.FloatField(default=0)
origin_country = models.CharField(max_length=256, blank=True)
description = models.TextField(max_length=4000, blank=True)
delete_flag = models.CharField(max_length=1, default='0')
def __str__(self):
return 'ID: ' + str(self.id) + ', お酒の名前: ' + self.product_name + '(' + str(self.internal_capacity) + ')'
'''
消費税テーブル
'''
class Tax(models.Model):
tax = models.FloatField()
'''
お酒の写真
'''
class AlcoholPicture(models.Model):
alcohol = models.ForeignKey(Alcohol, on_delete=models.CASCADE)
picture = models.ImageField(upload_to='images/')
モデルができたので、マイグレーションファイルを作成しましょう。
(コマンド実行はDjangoのコンテナ内から行ってくださいね)
python manage.py make migrations <アプリの名前>
root@~:/code# python manage.py makemigrations django_app
Migrations for 'django_app':
django_app/migrations/0001_initial.py
- Create model Alcohol
- Create model AlcoholPicture
- Create model Tax
root@~:/code#
このままマイグレーションを実行します。
実行すると、作成したマイグレーションファイルを適用してデータベースが更新されます。
root@~:/code# python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, django_app, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying django_app.0001_initial... OK
Applying sessions.0001_initial... OK
root@~:/code#
#管理ツールを使用するために、管理ユーザーを作成する
まず管理者を作成します。
・Username:admin にしました
・Email address:適当に。
・Password:適当に。
・Password (again):適当に。
パスワードを簡単にすると、パスワードこのままでいいですかみたいな確認をされますが、
ローカルで確認したいだけなのでとりあえず"y"で続けちゃいましょう。
root@~:/code# python manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address: admin@admin.com
Password:
Password (again):
The password is too similar to the email address.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
root@~:/code#
#管理ツールで利用できるテーブルを登録
さきほどマイグレーションで登録したテーブルを管理ツールで利用できるよう、
admin.pyを編集しましょう。
from django.contrib import admin
from .models import Alcohol, Tax
# Register your models here.
admin.site.register(Alcohol)
admin.site.register(Tax)
これだけでOK
#管理ツールにログインしてみる。
Djangoコンテナでサーバーを起動し、管理ツールにアクセスしてみる。
http://localhost:8000/admin
admin.pyに記載したモデルが登録されているが確認できました。
以上です。お疲れ様でした。
#備考
殴り書きなので大変みづらいと思います、申し訳ありません。
パートを分ければよかったと反省(・_・;)
dockerでDjangoからMySQLに接続できるようになったからホスト環境を汚すことなくあれこれできる・・・便利(感動)